@scaleway/sdk 0.0.2-alpha.0
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/LICENSE +191 -0
- package/README.md +28 -0
- package/dist/api/function/manual/FunctionAPI.js +436 -0
- package/dist/api/function/manual/WaitForFunctionAPI.js +27 -0
- package/dist/api/function/manual/types.js +1 -0
- package/dist/api/registry/manual/RegistryAPI.js +260 -0
- package/dist/api/registry/manual/WaitForRegistryAPI.js +27 -0
- package/dist/api/registry/manual/types.js +1 -0
- package/dist/helpers/API.js +12 -0
- package/dist/helpers/camelize.js +36 -0
- package/dist/helpers/forRegions.js +15 -0
- package/dist/helpers/is-browser.js +3 -0
- package/dist/helpers/json.js +6 -0
- package/dist/index.cjs +9449 -0
- package/dist/index.d.ts +1126 -0
- package/dist/index.js +13 -0
- package/dist/internal/async/interval-retrier.js +89 -0
- package/dist/internal/async/sleep.js +13 -0
- package/dist/internal/auth.js +68 -0
- package/dist/internal/interceptors/interceptor.js +11 -0
- package/dist/internal/interceptors/request.js +29 -0
- package/dist/internal/logger/console-logger.js +31 -0
- package/dist/internal/logger/index.js +38 -0
- package/dist/internal/logger/level-resolver.js +16 -0
- package/dist/internal/tools/string-validation.js +39 -0
- package/dist/internals.js +4 -0
- package/dist/node_modules/@scaleway/random-name/dist/index.js +254 -0
- package/dist/scw/client-ini-factory.js +24 -0
- package/dist/scw/client-ini-profile.js +30 -0
- package/dist/scw/client-settings.js +49 -0
- package/dist/scw/client.js +96 -0
- package/dist/scw/constants.js +4 -0
- package/dist/scw/errors/error-parser.js +121 -0
- package/dist/scw/errors/non-standard/invalid-request-mapper.js +34 -0
- package/dist/scw/errors/non-standard/unknown-resource-mapper.js +26 -0
- package/dist/scw/errors/scw-error.js +64 -0
- package/dist/scw/errors/standard/already-exists-error.js +26 -0
- package/dist/scw/errors/standard/denied-authentication-error.js +58 -0
- package/dist/scw/errors/standard/index.js +12 -0
- package/dist/scw/errors/standard/invalid-arguments-error.js +75 -0
- package/dist/scw/errors/standard/out-of-stock-error.js +24 -0
- package/dist/scw/errors/standard/permissions-denied-error.js +50 -0
- package/dist/scw/errors/standard/precondition-failed-error.js +62 -0
- package/dist/scw/errors/standard/quotas-exceeded-error.js +61 -0
- package/dist/scw/errors/standard/resource-expired-error.js +26 -0
- package/dist/scw/errors/standard/resource-locked-error.js +25 -0
- package/dist/scw/errors/standard/resource-not-found-error.js +25 -0
- package/dist/scw/errors/standard/transient-state-error.js +26 -0
- package/dist/scw/errors/types.js +26 -0
- package/dist/scw/fetch/build-fetcher.js +66 -0
- package/dist/scw/fetch/http-dumper.js +57 -0
- package/dist/scw/fetch/http-interceptors.js +80 -0
- package/dist/scw/fetch/resource-paginator.js +41 -0
- package/dist/scw/fetch/response-parser.js +46 -0
- package/dist/scw/marshalling.js +103 -0
- package/package.json +27 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { InvalidRequestMapper } from './non-standard/invalid-request-mapper.js';
|
|
2
|
+
import { UnknownResourceMapper } from './non-standard/unknown-resource-mapper.js';
|
|
3
|
+
import { ScalewayError } from './scw-error.js';
|
|
4
|
+
import { AlreadyExistsError } from './standard/already-exists-error.js';
|
|
5
|
+
import { DeniedAuthenticationError } from './standard/denied-authentication-error.js';
|
|
6
|
+
import { InvalidArgumentsError } from './standard/invalid-arguments-error.js';
|
|
7
|
+
import { OutOfStockError } from './standard/out-of-stock-error.js';
|
|
8
|
+
import { PermissionsDeniedError } from './standard/permissions-denied-error.js';
|
|
9
|
+
import { PreconditionFailedError } from './standard/precondition-failed-error.js';
|
|
10
|
+
import { QuotasExceededError } from './standard/quotas-exceeded-error.js';
|
|
11
|
+
import { ResourceExpiredError } from './standard/resource-expired-error.js';
|
|
12
|
+
import { ResourceLockedError } from './standard/resource-locked-error.js';
|
|
13
|
+
import { ResourceNotFoundError } from './standard/resource-not-found-error.js';
|
|
14
|
+
import { TransientStateError } from './standard/transient-state-error.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Unmarshals a standard error from raw body.
|
|
18
|
+
*
|
|
19
|
+
* @param type - The error type
|
|
20
|
+
* @param status - The status code
|
|
21
|
+
* @param body - The error response
|
|
22
|
+
* @returns The standard error if found
|
|
23
|
+
*
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
const unmarshalStandardError = (type, status, body) => {
|
|
28
|
+
let error;
|
|
29
|
+
|
|
30
|
+
switch (type) {
|
|
31
|
+
case 'denied_authentication':
|
|
32
|
+
error = DeniedAuthenticationError;
|
|
33
|
+
break;
|
|
34
|
+
|
|
35
|
+
case 'invalid_arguments':
|
|
36
|
+
error = InvalidArgumentsError;
|
|
37
|
+
break;
|
|
38
|
+
|
|
39
|
+
case 'out_of_stock':
|
|
40
|
+
error = OutOfStockError;
|
|
41
|
+
break;
|
|
42
|
+
|
|
43
|
+
case 'permissions_denied':
|
|
44
|
+
error = PermissionsDeniedError;
|
|
45
|
+
break;
|
|
46
|
+
|
|
47
|
+
case 'precondition_failed':
|
|
48
|
+
error = PreconditionFailedError;
|
|
49
|
+
break;
|
|
50
|
+
|
|
51
|
+
case 'quotas_exceeded':
|
|
52
|
+
error = QuotasExceededError;
|
|
53
|
+
break;
|
|
54
|
+
|
|
55
|
+
case 'expired':
|
|
56
|
+
error = ResourceExpiredError;
|
|
57
|
+
break;
|
|
58
|
+
|
|
59
|
+
case 'not_found':
|
|
60
|
+
error = ResourceNotFoundError;
|
|
61
|
+
break;
|
|
62
|
+
|
|
63
|
+
case 'locked':
|
|
64
|
+
error = ResourceLockedError;
|
|
65
|
+
break;
|
|
66
|
+
|
|
67
|
+
case 'transient_state':
|
|
68
|
+
error = TransientStateError;
|
|
69
|
+
break;
|
|
70
|
+
|
|
71
|
+
case 'already_exists':
|
|
72
|
+
error = AlreadyExistsError;
|
|
73
|
+
break;
|
|
74
|
+
|
|
75
|
+
default:
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return error.fromJSON(status, body);
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Unmarshals a non-standard error from raw body.
|
|
83
|
+
*
|
|
84
|
+
* @param type - The error type
|
|
85
|
+
* @param status - The status code
|
|
86
|
+
* @param body - The error response
|
|
87
|
+
* @returns The non-standard error if found
|
|
88
|
+
*
|
|
89
|
+
* @internal
|
|
90
|
+
*/
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
const unmarshalNonStandardError = (type, status, body) => {
|
|
94
|
+
switch (type) {
|
|
95
|
+
case 'unknown_resource':
|
|
96
|
+
return UnknownResourceMapper.fromJSON(status, body);
|
|
97
|
+
|
|
98
|
+
case 'invalid_request_error':
|
|
99
|
+
return InvalidRequestMapper.fromJSON(status, body);
|
|
100
|
+
|
|
101
|
+
default:
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Parses Scaleway error from raw body.
|
|
107
|
+
*
|
|
108
|
+
* @param status - The status code
|
|
109
|
+
* @param body - The error response
|
|
110
|
+
* @returns The resolved error
|
|
111
|
+
*
|
|
112
|
+
* @internal
|
|
113
|
+
*/
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
const parseScalewayError = (status, body) => {
|
|
117
|
+
const parsableError = typeof body.type === 'string' && (unmarshalStandardError(body.type, status, body) ?? unmarshalNonStandardError(body.type, status, body));
|
|
118
|
+
return parsableError || new ScalewayError(status, body);
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export { parseScalewayError };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ScalewayError } from '../scw-error.js';
|
|
2
|
+
import { InvalidArgumentsError } from '../standard/invalid-arguments-error.js';
|
|
3
|
+
import { QuotasExceededError } from '../standard/quotas-exceeded-error.js';
|
|
4
|
+
import { isRecordOfStringArray } from '../types.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* InvalidRequest error is only returned by the instance API.
|
|
8
|
+
*
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
class InvalidRequestMapper {
|
|
13
|
+
static fromJSON(status, obj) {
|
|
14
|
+
if (typeof obj.message === 'string' && obj.message.toLowerCase().includes('quota exceeded for this resource')) return new QuotasExceededError(status, obj, [{
|
|
15
|
+
current: 0,
|
|
16
|
+
quota: 0,
|
|
17
|
+
resource: typeof obj.resource === 'string' ? obj.resource : ''
|
|
18
|
+
}]);
|
|
19
|
+
const fields = obj.fields && isRecordOfStringArray(obj.fields) ? obj.fields : {};
|
|
20
|
+
const fieldsMessages = Object.entries(fields);
|
|
21
|
+
if (fieldsMessages.length) return new InvalidArgumentsError(status, obj, fieldsMessages.map(_ref => {
|
|
22
|
+
let [argumentName, messages] = _ref;
|
|
23
|
+
return messages.map(helpMessage => ({
|
|
24
|
+
argumentName,
|
|
25
|
+
helpMessage,
|
|
26
|
+
reason: 'constraint'
|
|
27
|
+
}));
|
|
28
|
+
}).flat());
|
|
29
|
+
return new ScalewayError(status, obj);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export { InvalidRequestMapper };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { isUUID } from '../../../internal/tools/string-validation.js';
|
|
2
|
+
import { ScalewayError } from '../scw-error.js';
|
|
3
|
+
import { ResourceNotFoundError } from '../standard/resource-not-found-error.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* UnknownResource error is only returned by the instance API.
|
|
7
|
+
*
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
class UnknownResourceMapper {
|
|
12
|
+
static fromJSON(status, obj) {
|
|
13
|
+
// Split the message
|
|
14
|
+
// Note: some errors uses ' and not "
|
|
15
|
+
// Examples: `"111..." not found` or `Security Group '111...' not found`
|
|
16
|
+
const messageParts = typeof obj.message === 'string' ? obj.message.split(/"|'/) : [];
|
|
17
|
+
if (messageParts.length === 3 && isUUID(messageParts[1])) return new ResourceNotFoundError(status, obj, // transform `Security group ` to `security_group`
|
|
18
|
+
// `.replaceAll()` may be too recent to use yet.
|
|
19
|
+
// that's why we're using `.split(' ').join('_')` for now.
|
|
20
|
+
messageParts[0].trim().toLowerCase().split(' ').join('_'), messageParts[1]);
|
|
21
|
+
return new ScalewayError(status, obj);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { UnknownResourceMapper };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { isJSONObject } from '../../helpers/json.js';
|
|
2
|
+
import { isRecordOfStringArray } from './types.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Builds the default message for {@link ScalewayError}.
|
|
6
|
+
*
|
|
7
|
+
* @param status - The response code
|
|
8
|
+
* @param body - The response body
|
|
9
|
+
* @returns The error message
|
|
10
|
+
*
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const buildDefaultMessage = (status, body) => {
|
|
15
|
+
let output = `scaleway-sdk-js: http error ${status}`;
|
|
16
|
+
|
|
17
|
+
if (isJSONObject(body)) {
|
|
18
|
+
if (typeof body.resource === 'string') {
|
|
19
|
+
output += `: resource ${body.resource}`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (typeof body.message === 'string') {
|
|
23
|
+
output += `: ${body.message}`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (body.fields && isRecordOfStringArray(body.fields)) {
|
|
27
|
+
const reasonList = Object.entries(body.fields).reduce((acc, _ref) => {
|
|
28
|
+
let [name, list] = _ref;
|
|
29
|
+
return acc.concat(`${name} (${list.join(', ')})`);
|
|
30
|
+
}, []);
|
|
31
|
+
output += `: ${reasonList.join(', ')}`;
|
|
32
|
+
}
|
|
33
|
+
} else if (typeof body === 'string') {
|
|
34
|
+
output += `: ${body}`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return output;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Scaleway error.
|
|
41
|
+
*
|
|
42
|
+
* @public
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class ScalewayError extends Error {
|
|
47
|
+
constructor(status, body, message = buildDefaultMessage(status, body)) {
|
|
48
|
+
super(message); // 'Error' breaks prototype chain here
|
|
49
|
+
|
|
50
|
+
this.status = status;
|
|
51
|
+
this.body = body;
|
|
52
|
+
this.message = message;
|
|
53
|
+
this.name = new.target.name; // set name as 'CustomError' (or the class name that extends this class)
|
|
54
|
+
|
|
55
|
+
Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
static fromJSON(status, obj) {
|
|
59
|
+
return new ScalewayError(status, obj);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export { ScalewayError };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ScalewayError } from '../scw-error.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* AlreadyExists error is used when a resource already exists.
|
|
5
|
+
*
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
class AlreadyExistsError extends ScalewayError {
|
|
10
|
+
constructor(status, body, resource, resourceId, helpMessage) {
|
|
11
|
+
super(status, body, `scaleway-sdk-js: resource ${resource} with ID ${resourceId} already exists: ${helpMessage}`);
|
|
12
|
+
this.status = status;
|
|
13
|
+
this.body = body;
|
|
14
|
+
this.resource = resource;
|
|
15
|
+
this.resourceId = resourceId;
|
|
16
|
+
this.helpMessage = helpMessage;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static fromJSON(status, obj) {
|
|
20
|
+
if (typeof obj.resource !== 'string' || typeof obj.resource_id !== 'string' || typeof obj.help_message !== 'string') return null;
|
|
21
|
+
return new AlreadyExistsError(status, obj, obj.resource, obj.resource_id, obj.help_message);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { AlreadyExistsError };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ScalewayError } from '../scw-error.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Build the default message for {@link DeniedAuthenticationError}.
|
|
5
|
+
*
|
|
6
|
+
* @param method - The authentication method
|
|
7
|
+
* @param reason - The deny reason
|
|
8
|
+
* @returns The error message
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const buildMessage = (method, reason) => {
|
|
14
|
+
let reasonDesc;
|
|
15
|
+
|
|
16
|
+
switch (reason) {
|
|
17
|
+
case 'invalid_argument':
|
|
18
|
+
reasonDesc = `invalid ${method} format or empty value`;
|
|
19
|
+
break;
|
|
20
|
+
|
|
21
|
+
case 'not_found':
|
|
22
|
+
reasonDesc = `${method} does not exist`;
|
|
23
|
+
break;
|
|
24
|
+
|
|
25
|
+
case 'expired':
|
|
26
|
+
reasonDesc = `${method} is expired`;
|
|
27
|
+
break;
|
|
28
|
+
|
|
29
|
+
default:
|
|
30
|
+
reasonDesc = `unknown reason for ${method}`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return `scaleway-sdk-js: denied authentication: ${reasonDesc}`;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* DeniedAuthentication error is used by the API Gateway auth service to deny a request.
|
|
37
|
+
*
|
|
38
|
+
* @public
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class DeniedAuthenticationError extends ScalewayError {
|
|
43
|
+
constructor(status, body, method, reason) {
|
|
44
|
+
super(status, body, buildMessage(method, reason));
|
|
45
|
+
this.status = status;
|
|
46
|
+
this.body = body;
|
|
47
|
+
this.method = method;
|
|
48
|
+
this.reason = reason;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static fromJSON(status, obj) {
|
|
52
|
+
if (typeof obj.method !== 'string' || typeof obj.reason !== 'string') return null;
|
|
53
|
+
return new DeniedAuthenticationError(status, obj, obj.method, obj.reason);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { DeniedAuthenticationError };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { ScalewayError } from '../scw-error.js';
|
|
2
|
+
export { AlreadyExistsError } from './already-exists-error.js';
|
|
3
|
+
export { DeniedAuthenticationError } from './denied-authentication-error.js';
|
|
4
|
+
export { InvalidArgumentsError } from './invalid-arguments-error.js';
|
|
5
|
+
export { OutOfStockError } from './out-of-stock-error.js';
|
|
6
|
+
export { PermissionsDeniedError } from './permissions-denied-error.js';
|
|
7
|
+
export { PreconditionFailedError } from './precondition-failed-error.js';
|
|
8
|
+
export { QuotasExceededError } from './quotas-exceeded-error.js';
|
|
9
|
+
export { ResourceExpiredError } from './resource-expired-error.js';
|
|
10
|
+
export { ResourceLockedError } from './resource-locked-error.js';
|
|
11
|
+
export { ResourceNotFoundError } from './resource-not-found-error.js';
|
|
12
|
+
export { TransientStateError } from './transient-state-error.js';
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { isJSONObject } from '../../../helpers/json.js';
|
|
2
|
+
import { ScalewayError } from '../scw-error.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Details of an {@link InvalidArgumentsError} error.
|
|
6
|
+
*
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Build the default message for {@link InvalidArgumentsError}.
|
|
12
|
+
*
|
|
13
|
+
* @param list - The list of {@link InvalidArgumentsErrorDetails}
|
|
14
|
+
* @returns The error message
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
const buildMessage = list => {
|
|
19
|
+
const invalidArgs = list.reduce((acc, details) => {
|
|
20
|
+
let readableReason = '';
|
|
21
|
+
|
|
22
|
+
switch (details.reason) {
|
|
23
|
+
case 'required':
|
|
24
|
+
readableReason = `is required`;
|
|
25
|
+
break;
|
|
26
|
+
|
|
27
|
+
case 'format':
|
|
28
|
+
readableReason = `is wrongly formatted`;
|
|
29
|
+
break;
|
|
30
|
+
|
|
31
|
+
case 'constraint':
|
|
32
|
+
readableReason = `does not respect constraint`;
|
|
33
|
+
break;
|
|
34
|
+
|
|
35
|
+
default:
|
|
36
|
+
readableReason = `is invalid for unexpected reason`;
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (details.helpMessage && details.helpMessage.length > 0) {
|
|
41
|
+
readableReason = readableReason.concat(`, `, details.helpMessage);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
acc.push(`${details.argumentName} ${readableReason}`);
|
|
45
|
+
return acc;
|
|
46
|
+
}, []);
|
|
47
|
+
return `scaleway-sdk-js: invalid argument(s): ${invalidArgs.join('; ')}`;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* InvalidArguments error happens when one or many fields are invalid in the request message.
|
|
51
|
+
*
|
|
52
|
+
* @public
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class InvalidArgumentsError extends ScalewayError {
|
|
57
|
+
constructor(status, body, details) {
|
|
58
|
+
super(status, body, buildMessage(details));
|
|
59
|
+
this.status = status;
|
|
60
|
+
this.body = body;
|
|
61
|
+
this.details = details;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
static fromJSON(status, obj) {
|
|
65
|
+
if (!Array.isArray(obj.details)) return null;
|
|
66
|
+
return new InvalidArgumentsError(status, obj, obj.details.reduce((list, detail) => isJSONObject(detail) && typeof detail.argument_name === 'string' && typeof detail.reason === 'string' ? list.concat({
|
|
67
|
+
argumentName: detail.argument_name,
|
|
68
|
+
helpMessage: typeof detail.help_message === 'string' ? detail.help_message : undefined,
|
|
69
|
+
reason: detail.reason
|
|
70
|
+
}) : list, []));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export { InvalidArgumentsError };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ScalewayError } from '../scw-error.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* OutOfStock error happens when stocks are empty for the resource.
|
|
5
|
+
*
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
class OutOfStockError extends ScalewayError {
|
|
10
|
+
constructor(status, body, resource) {
|
|
11
|
+
super(status, body, `scaleway-sdk-js: resource ${resource} is out of stock`);
|
|
12
|
+
this.status = status;
|
|
13
|
+
this.body = body;
|
|
14
|
+
this.resource = resource;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
static fromJSON(status, obj) {
|
|
18
|
+
if (typeof obj.resource !== 'string') return null;
|
|
19
|
+
return new OutOfStockError(status, obj, obj.resource);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { OutOfStockError };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { isJSONObject } from '../../../helpers/json.js';
|
|
2
|
+
import { ScalewayError } from '../scw-error.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Details of an {@link PermissionsDeniedError} error.
|
|
6
|
+
*
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Build the default message for {@link PermissionsDeniedError}.
|
|
12
|
+
*
|
|
13
|
+
* @param list - The list of {@link PermissionsDeniedErrorDetails}
|
|
14
|
+
* @returns The error message
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
const buildMessage = list => `scaleway-sdk-js: insufficient permissions: ${list.map(_ref => {
|
|
19
|
+
let {
|
|
20
|
+
action,
|
|
21
|
+
resource
|
|
22
|
+
} = _ref;
|
|
23
|
+
return `${action} ${resource}`;
|
|
24
|
+
}).join('; ')}`;
|
|
25
|
+
/**
|
|
26
|
+
* PermissionsDenied error happens when one or many permissions are not accorded to the user making the request.
|
|
27
|
+
*
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class PermissionsDeniedError extends ScalewayError {
|
|
33
|
+
constructor(status, body, list) {
|
|
34
|
+
super(status, body, buildMessage(list));
|
|
35
|
+
this.status = status;
|
|
36
|
+
this.body = body;
|
|
37
|
+
this.list = list;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
static fromJSON(status, obj) {
|
|
41
|
+
if (!Array.isArray(obj.details)) return null;
|
|
42
|
+
return new PermissionsDeniedError(status, obj, obj.details.reduce((list, detail) => isJSONObject(detail) && typeof detail.resource === 'string' && typeof detail.action === 'string' ? list.concat({
|
|
43
|
+
action: detail.action,
|
|
44
|
+
resource: detail.resource
|
|
45
|
+
}) : list, []));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export { PermissionsDeniedError };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { ScalewayError } from '../scw-error.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Build the default message for {@link PreconditionFailedError}.
|
|
5
|
+
*
|
|
6
|
+
* @param precondition - The precondition
|
|
7
|
+
* @param helpMessage - The message which should help the user to fix the root cause
|
|
8
|
+
* @returns The error message
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const buildMessage = (precondition, helpMessage) => {
|
|
14
|
+
let message;
|
|
15
|
+
|
|
16
|
+
switch (precondition) {
|
|
17
|
+
case 'unknown_precondition':
|
|
18
|
+
message = 'unknown precondition';
|
|
19
|
+
break;
|
|
20
|
+
|
|
21
|
+
case 'resource_still_in_use':
|
|
22
|
+
message = 'resource is still in use';
|
|
23
|
+
break;
|
|
24
|
+
|
|
25
|
+
case 'attribute_must_be_set':
|
|
26
|
+
message = 'attribute must be set';
|
|
27
|
+
break;
|
|
28
|
+
|
|
29
|
+
default:
|
|
30
|
+
message = '';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (typeof helpMessage === 'string' && helpMessage.length > 0) {
|
|
34
|
+
message = message.concat(', ', helpMessage);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return `scaleway-sdk-js: precondition failed: ${message}`;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* PreconditionFailed error is used when a precondition is not respected.
|
|
41
|
+
*
|
|
42
|
+
* @public
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class PreconditionFailedError extends ScalewayError {
|
|
47
|
+
constructor(status, body, precondition, helpMessage) {
|
|
48
|
+
super(status, body, buildMessage(precondition, helpMessage));
|
|
49
|
+
this.status = status;
|
|
50
|
+
this.body = body;
|
|
51
|
+
this.precondition = precondition;
|
|
52
|
+
this.helpMessage = helpMessage;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
static fromJSON(status, obj) {
|
|
56
|
+
if (typeof obj.precondition !== 'string' || typeof obj.help_message !== 'string') return null;
|
|
57
|
+
return new PreconditionFailedError(status, obj, obj.precondition, obj.help_message);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export { PreconditionFailedError };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { isJSONObject } from '../../../helpers/json.js';
|
|
2
|
+
import { ScalewayError } from '../scw-error.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Scope of an {@link QuotasExceededErrorDetails} error.
|
|
6
|
+
*
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Build the default message for {@link QuotasExceededError}.
|
|
12
|
+
*
|
|
13
|
+
* @param list - The list of {@link QuotasExceededErrorDetails}
|
|
14
|
+
* @returns The error message
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
const buildMessage = list => `scaleway-sdk-js: quota exceeded(s): ${list.map(details => {
|
|
19
|
+
const message = `${details.resource} has reached its quota (${details.current}/${details.quota})`;
|
|
20
|
+
return details.scope ? `${message} for ${details.scope.kind} '${details.scope.id}'` : message;
|
|
21
|
+
}).join('; ')}`;
|
|
22
|
+
|
|
23
|
+
const buildScope = detail => {
|
|
24
|
+
if (typeof detail.organization_id === 'string' && detail.organization_id.length) return {
|
|
25
|
+
id: detail.organization_id,
|
|
26
|
+
kind: 'organization'
|
|
27
|
+
};
|
|
28
|
+
if (typeof detail.project_id === 'string' && detail.project_id.length) return {
|
|
29
|
+
id: detail.project_id,
|
|
30
|
+
kind: 'project'
|
|
31
|
+
};
|
|
32
|
+
return undefined;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* QuotasExceeded error happens when one or many resource exceed quotas during the creation of a resource.
|
|
36
|
+
*
|
|
37
|
+
* @public
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class QuotasExceededError extends ScalewayError {
|
|
42
|
+
constructor(status, body, list) {
|
|
43
|
+
super(status, body, buildMessage(list));
|
|
44
|
+
this.status = status;
|
|
45
|
+
this.body = body;
|
|
46
|
+
this.list = list;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static fromJSON(status, obj) {
|
|
50
|
+
if (!Array.isArray(obj.details)) return null;
|
|
51
|
+
return new QuotasExceededError(status, obj, obj.details.reduce((list, detail) => isJSONObject(detail) && typeof detail.resource === 'string' && typeof detail.quota === 'number' && typeof detail.current === 'number' ? list.concat({
|
|
52
|
+
current: detail.current,
|
|
53
|
+
quota: detail.quota,
|
|
54
|
+
resource: detail.resource,
|
|
55
|
+
scope: buildScope(detail)
|
|
56
|
+
}) : list, []));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export { QuotasExceededError };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ScalewayError } from '../scw-error.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ResourceExpired error happens when trying to access a resource that has expired.
|
|
5
|
+
*
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
class ResourceExpiredError extends ScalewayError {
|
|
10
|
+
constructor(status, body, resource, resourceId, expiredSince) {
|
|
11
|
+
super(status, body, `scaleway-sdk-js: resource ${resource} with ID ${resourceId} expired since ${expiredSince.toISOString()}`);
|
|
12
|
+
this.status = status;
|
|
13
|
+
this.body = body;
|
|
14
|
+
this.resource = resource;
|
|
15
|
+
this.resourceId = resourceId;
|
|
16
|
+
this.expiredSince = expiredSince;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static fromJSON(status, obj) {
|
|
20
|
+
if (typeof obj.resource !== 'string' || typeof obj.resource_id !== 'string' || typeof obj.expired_since !== 'string') return null;
|
|
21
|
+
return new ResourceExpiredError(status, obj, obj.resource, obj.resource_id, new Date(obj.expired_since));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { ResourceExpiredError };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ScalewayError } from '../scw-error.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ResourceLocked error happens when a resource is locked by trust and safety.
|
|
5
|
+
*
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
class ResourceLockedError extends ScalewayError {
|
|
10
|
+
constructor(status, body, resource, resourceId) {
|
|
11
|
+
super(status, body, `scaleway-sdk-js: resource ${resource} with ID ${resourceId} is locked`);
|
|
12
|
+
this.status = status;
|
|
13
|
+
this.body = body;
|
|
14
|
+
this.resource = resource;
|
|
15
|
+
this.resourceId = resourceId;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static fromJSON(status, obj) {
|
|
19
|
+
if (typeof obj.resource !== 'string' || typeof obj.resource_id !== 'string') return null;
|
|
20
|
+
return new ResourceLockedError(status, obj, obj.resource, obj.resource_id);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export { ResourceLockedError };
|