@aigne/afs-http 1.11.0-beta.3
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.md +26 -0
- package/README.md +318 -0
- package/dist/adapters/express.cjs +74 -0
- package/dist/adapters/express.d.cts +56 -0
- package/dist/adapters/express.d.cts.map +1 -0
- package/dist/adapters/express.d.mts +56 -0
- package/dist/adapters/express.d.mts.map +1 -0
- package/dist/adapters/express.mjs +74 -0
- package/dist/adapters/express.mjs.map +1 -0
- package/dist/adapters/koa.cjs +73 -0
- package/dist/adapters/koa.d.cts +56 -0
- package/dist/adapters/koa.d.cts.map +1 -0
- package/dist/adapters/koa.d.mts +56 -0
- package/dist/adapters/koa.d.mts.map +1 -0
- package/dist/adapters/koa.mjs +73 -0
- package/dist/adapters/koa.mjs.map +1 -0
- package/dist/client.cjs +143 -0
- package/dist/client.d.cts +70 -0
- package/dist/client.d.cts.map +1 -0
- package/dist/client.d.mts +70 -0
- package/dist/client.d.mts.map +1 -0
- package/dist/client.mjs +144 -0
- package/dist/client.mjs.map +1 -0
- package/dist/errors.cjs +105 -0
- package/dist/errors.d.cts +63 -0
- package/dist/errors.d.cts.map +1 -0
- package/dist/errors.d.mts +63 -0
- package/dist/errors.d.mts.map +1 -0
- package/dist/errors.mjs +98 -0
- package/dist/errors.mjs.map +1 -0
- package/dist/handler.cjs +126 -0
- package/dist/handler.d.cts +43 -0
- package/dist/handler.d.cts.map +1 -0
- package/dist/handler.d.mts +43 -0
- package/dist/handler.d.mts.map +1 -0
- package/dist/handler.mjs +127 -0
- package/dist/handler.mjs.map +1 -0
- package/dist/index.cjs +33 -0
- package/dist/index.d.cts +8 -0
- package/dist/index.d.mts +8 -0
- package/dist/index.mjs +9 -0
- package/dist/protocol.cjs +68 -0
- package/dist/protocol.d.cts +119 -0
- package/dist/protocol.d.cts.map +1 -0
- package/dist/protocol.d.mts +119 -0
- package/dist/protocol.d.mts.map +1 -0
- package/dist/protocol.mjs +64 -0
- package/dist/protocol.mjs.map +1 -0
- package/dist/retry.cjs +111 -0
- package/dist/retry.d.cts +57 -0
- package/dist/retry.d.cts.map +1 -0
- package/dist/retry.d.mts +57 -0
- package/dist/retry.d.mts.map +1 -0
- package/dist/retry.mjs +105 -0
- package/dist/retry.mjs.map +1 -0
- package/package.json +55 -0
package/dist/errors.cjs
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
const require_protocol = require('./protocol.cjs');
|
|
2
|
+
|
|
3
|
+
//#region src/errors.ts
|
|
4
|
+
/**
|
|
5
|
+
* Base class for AFS HTTP errors
|
|
6
|
+
*/
|
|
7
|
+
var AFSHttpError = class extends Error {
|
|
8
|
+
constructor(message, code, httpStatus = 200, details) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.httpStatus = httpStatus;
|
|
12
|
+
this.details = details;
|
|
13
|
+
this.name = "AFSHttpError";
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Path not found error
|
|
18
|
+
*/
|
|
19
|
+
var AFSNotFoundError = class extends AFSHttpError {
|
|
20
|
+
constructor(path, details) {
|
|
21
|
+
super(`Path not found: ${path}`, require_protocol.AFSErrorCode.NOT_FOUND, 200, details);
|
|
22
|
+
this.name = "AFSNotFoundError";
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Permission denied error (including readonly mode)
|
|
27
|
+
*/
|
|
28
|
+
var AFSPermissionError = class extends AFSHttpError {
|
|
29
|
+
constructor(message, details) {
|
|
30
|
+
super(message, require_protocol.AFSErrorCode.PERMISSION_DENIED, 200, details);
|
|
31
|
+
this.name = "AFSPermissionError";
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Conflict error (concurrent modification)
|
|
36
|
+
*/
|
|
37
|
+
var AFSConflictError = class extends AFSHttpError {
|
|
38
|
+
constructor(message, details) {
|
|
39
|
+
super(message, require_protocol.AFSErrorCode.CONFLICT, 200, details);
|
|
40
|
+
this.name = "AFSConflictError";
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Runtime error
|
|
45
|
+
*/
|
|
46
|
+
var AFSRuntimeError = class extends AFSHttpError {
|
|
47
|
+
constructor(message, details) {
|
|
48
|
+
super(message, require_protocol.AFSErrorCode.RUNTIME_ERROR, 200, details);
|
|
49
|
+
this.name = "AFSRuntimeError";
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Invalid request error (bad JSON, invalid method, etc.)
|
|
54
|
+
*/
|
|
55
|
+
var AFSInvalidRequestError = class extends AFSHttpError {
|
|
56
|
+
constructor(message, details) {
|
|
57
|
+
super(message, require_protocol.AFSErrorCode.RUNTIME_ERROR, 400, details);
|
|
58
|
+
this.name = "AFSInvalidRequestError";
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Payload too large error
|
|
63
|
+
*/
|
|
64
|
+
var AFSPayloadTooLargeError = class extends AFSHttpError {
|
|
65
|
+
constructor(maxSize, actualSize) {
|
|
66
|
+
const message = actualSize ? `Payload too large: ${actualSize} bytes exceeds limit of ${maxSize} bytes` : `Payload too large: exceeds limit of ${maxSize} bytes`;
|
|
67
|
+
super(message, require_protocol.AFSErrorCode.RUNTIME_ERROR, 413, {
|
|
68
|
+
maxSize,
|
|
69
|
+
actualSize
|
|
70
|
+
});
|
|
71
|
+
this.name = "AFSPayloadTooLargeError";
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Network error (for client-side use)
|
|
76
|
+
*/
|
|
77
|
+
var AFSNetworkError = class extends Error {
|
|
78
|
+
constructor(message, cause, retryable = true) {
|
|
79
|
+
super(message);
|
|
80
|
+
this.cause = cause;
|
|
81
|
+
this.retryable = retryable;
|
|
82
|
+
this.name = "AFSNetworkError";
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Map common error messages to appropriate AFS error codes
|
|
87
|
+
*/
|
|
88
|
+
function mapErrorToCode(error) {
|
|
89
|
+
const message = error.message.toLowerCase();
|
|
90
|
+
if (message.includes("not found") || message.includes("enoent") || message.includes("does not exist")) return require_protocol.AFSErrorCode.NOT_FOUND;
|
|
91
|
+
if (message.includes("permission") || message.includes("readonly") || message.includes("read-only") || message.includes("access denied") || message.includes("eacces")) return require_protocol.AFSErrorCode.PERMISSION_DENIED;
|
|
92
|
+
if (message.includes("conflict") || message.includes("already exists") || message.includes("eexist")) return require_protocol.AFSErrorCode.CONFLICT;
|
|
93
|
+
return require_protocol.AFSErrorCode.RUNTIME_ERROR;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
//#endregion
|
|
97
|
+
exports.AFSConflictError = AFSConflictError;
|
|
98
|
+
exports.AFSHttpError = AFSHttpError;
|
|
99
|
+
exports.AFSInvalidRequestError = AFSInvalidRequestError;
|
|
100
|
+
exports.AFSNetworkError = AFSNetworkError;
|
|
101
|
+
exports.AFSNotFoundError = AFSNotFoundError;
|
|
102
|
+
exports.AFSPayloadTooLargeError = AFSPayloadTooLargeError;
|
|
103
|
+
exports.AFSPermissionError = AFSPermissionError;
|
|
104
|
+
exports.AFSRuntimeError = AFSRuntimeError;
|
|
105
|
+
exports.mapErrorToCode = mapErrorToCode;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { AFSErrorCode } from "./protocol.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/errors.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Base class for AFS HTTP errors
|
|
6
|
+
*/
|
|
7
|
+
declare class AFSHttpError extends Error {
|
|
8
|
+
readonly code: AFSErrorCode;
|
|
9
|
+
readonly httpStatus: number;
|
|
10
|
+
readonly details?: unknown | undefined;
|
|
11
|
+
constructor(message: string, code: AFSErrorCode, httpStatus?: number, details?: unknown | undefined);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Path not found error
|
|
15
|
+
*/
|
|
16
|
+
declare class AFSNotFoundError extends AFSHttpError {
|
|
17
|
+
constructor(path: string, details?: unknown);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Permission denied error (including readonly mode)
|
|
21
|
+
*/
|
|
22
|
+
declare class AFSPermissionError extends AFSHttpError {
|
|
23
|
+
constructor(message: string, details?: unknown);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Conflict error (concurrent modification)
|
|
27
|
+
*/
|
|
28
|
+
declare class AFSConflictError extends AFSHttpError {
|
|
29
|
+
constructor(message: string, details?: unknown);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Runtime error
|
|
33
|
+
*/
|
|
34
|
+
declare class AFSRuntimeError extends AFSHttpError {
|
|
35
|
+
constructor(message: string, details?: unknown);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Invalid request error (bad JSON, invalid method, etc.)
|
|
39
|
+
*/
|
|
40
|
+
declare class AFSInvalidRequestError extends AFSHttpError {
|
|
41
|
+
constructor(message: string, details?: unknown);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Payload too large error
|
|
45
|
+
*/
|
|
46
|
+
declare class AFSPayloadTooLargeError extends AFSHttpError {
|
|
47
|
+
constructor(maxSize: number, actualSize?: number);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Network error (for client-side use)
|
|
51
|
+
*/
|
|
52
|
+
declare class AFSNetworkError extends Error {
|
|
53
|
+
readonly cause?: Error | undefined;
|
|
54
|
+
readonly retryable: boolean;
|
|
55
|
+
constructor(message: string, cause?: Error | undefined, retryable?: boolean);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Map common error messages to appropriate AFS error codes
|
|
59
|
+
*/
|
|
60
|
+
declare function mapErrorToCode(error: Error): AFSErrorCode;
|
|
61
|
+
//#endregion
|
|
62
|
+
export { AFSConflictError, AFSHttpError, AFSInvalidRequestError, AFSNetworkError, AFSNotFoundError, AFSPayloadTooLargeError, AFSPermissionError, AFSRuntimeError, mapErrorToCode };
|
|
63
|
+
//# sourceMappingURL=errors.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.cts","names":[],"sources":["../src/errors.ts"],"mappings":";;;;AAKA;;cAAa,YAAA,SAAqB,KAAA;EAAA,SAAA,IAAA,EAGR,YAAA;EAAA,SAAA,UAAA;EAAA,SAAA,OAAA;EAAA,YAAA,OAAA,UAAA,IAAA,EAAA,YAAA,EAAA,UAAA,WAAA,OAAA;AAAA;AAAA;;;AAAA,cAYb,gBAAA,SAAyB,YAAA;EAAA,YAAA,IAAA,UAAA,OAAA;AAAA;AAAA;AAUtC;AAUA;AApBsC,cAUzB,kBAAA,SAA2B,YAAA;EAAA,YAAA,OAAA,UAAA,OAAA;AAAA;AAAA;AAUxC;AAUA;AApBwC,cAU3B,gBAAA,SAAyB,YAAA;EAAA,YAAA,OAAA,UAAA,OAAA;AAAA;AAAA;AAUtC;AAUA;AApBsC,cAUzB,eAAA,SAAwB,YAAA;EAAA,YAAA,OAAA,UAAA,OAAA;AAAA;AAAA;AAUrC;AAUA;AApBqC,cAUxB,sBAAA,SAA+B,YAAA;EAAA,YAAA,OAAA,UAAA,OAAA;AAAA;AAAA;AAU5C;AAaA;AAvB4C,cAU/B,uBAAA,SAAgC,YAAA;EAAA,YAAA,OAAA,UAAA,UAAA;AAAA;AAAA;AAa7C;;AAb6C,cAahC,eAAA,SAAwB,KAAA;EAAA,SAAA,KAAA,GAGT,KAAA;EAAA,SAAA,SAAA;EAAA,YAAA,OAAA,UAAA,KAAA,GAAA,KAAA,cAAA,SAAA;AAAA;AAAA;;;AAAA,iBAWZ,cAAA,CAAA,KAAA,EAAsB,KAAA,GAAQ,YAAA"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { AFSErrorCode } from "./protocol.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/errors.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Base class for AFS HTTP errors
|
|
6
|
+
*/
|
|
7
|
+
declare class AFSHttpError extends Error {
|
|
8
|
+
readonly code: AFSErrorCode;
|
|
9
|
+
readonly httpStatus: number;
|
|
10
|
+
readonly details?: unknown | undefined;
|
|
11
|
+
constructor(message: string, code: AFSErrorCode, httpStatus?: number, details?: unknown | undefined);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Path not found error
|
|
15
|
+
*/
|
|
16
|
+
declare class AFSNotFoundError extends AFSHttpError {
|
|
17
|
+
constructor(path: string, details?: unknown);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Permission denied error (including readonly mode)
|
|
21
|
+
*/
|
|
22
|
+
declare class AFSPermissionError extends AFSHttpError {
|
|
23
|
+
constructor(message: string, details?: unknown);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Conflict error (concurrent modification)
|
|
27
|
+
*/
|
|
28
|
+
declare class AFSConflictError extends AFSHttpError {
|
|
29
|
+
constructor(message: string, details?: unknown);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Runtime error
|
|
33
|
+
*/
|
|
34
|
+
declare class AFSRuntimeError extends AFSHttpError {
|
|
35
|
+
constructor(message: string, details?: unknown);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Invalid request error (bad JSON, invalid method, etc.)
|
|
39
|
+
*/
|
|
40
|
+
declare class AFSInvalidRequestError extends AFSHttpError {
|
|
41
|
+
constructor(message: string, details?: unknown);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Payload too large error
|
|
45
|
+
*/
|
|
46
|
+
declare class AFSPayloadTooLargeError extends AFSHttpError {
|
|
47
|
+
constructor(maxSize: number, actualSize?: number);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Network error (for client-side use)
|
|
51
|
+
*/
|
|
52
|
+
declare class AFSNetworkError extends Error {
|
|
53
|
+
readonly cause?: Error | undefined;
|
|
54
|
+
readonly retryable: boolean;
|
|
55
|
+
constructor(message: string, cause?: Error | undefined, retryable?: boolean);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Map common error messages to appropriate AFS error codes
|
|
59
|
+
*/
|
|
60
|
+
declare function mapErrorToCode(error: Error): AFSErrorCode;
|
|
61
|
+
//#endregion
|
|
62
|
+
export { AFSConflictError, AFSHttpError, AFSInvalidRequestError, AFSNetworkError, AFSNotFoundError, AFSPayloadTooLargeError, AFSPermissionError, AFSRuntimeError, mapErrorToCode };
|
|
63
|
+
//# sourceMappingURL=errors.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.mts","names":[],"sources":["../src/errors.ts"],"mappings":";;;;AAKA;;cAAa,YAAA,SAAqB,KAAA;EAAA,SAAA,IAAA,EAGR,YAAA;EAAA,SAAA,UAAA;EAAA,SAAA,OAAA;EAAA,YAAA,OAAA,UAAA,IAAA,EAAA,YAAA,EAAA,UAAA,WAAA,OAAA;AAAA;AAAA;;;AAAA,cAYb,gBAAA,SAAyB,YAAA;EAAA,YAAA,IAAA,UAAA,OAAA;AAAA;AAAA;AAUtC;AAUA;AApBsC,cAUzB,kBAAA,SAA2B,YAAA;EAAA,YAAA,OAAA,UAAA,OAAA;AAAA;AAAA;AAUxC;AAUA;AApBwC,cAU3B,gBAAA,SAAyB,YAAA;EAAA,YAAA,OAAA,UAAA,OAAA;AAAA;AAAA;AAUtC;AAUA;AApBsC,cAUzB,eAAA,SAAwB,YAAA;EAAA,YAAA,OAAA,UAAA,OAAA;AAAA;AAAA;AAUrC;AAUA;AApBqC,cAUxB,sBAAA,SAA+B,YAAA;EAAA,YAAA,OAAA,UAAA,OAAA;AAAA;AAAA;AAU5C;AAaA;AAvB4C,cAU/B,uBAAA,SAAgC,YAAA;EAAA,YAAA,OAAA,UAAA,UAAA;AAAA;AAAA;AAa7C;;AAb6C,cAahC,eAAA,SAAwB,KAAA;EAAA,SAAA,KAAA,GAGT,KAAA;EAAA,SAAA,SAAA;EAAA,YAAA,OAAA,UAAA,KAAA,GAAA,KAAA,cAAA,SAAA;AAAA;AAAA;;;AAAA,iBAWZ,cAAA,CAAA,KAAA,EAAsB,KAAA,GAAQ,YAAA"}
|
package/dist/errors.mjs
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { AFSErrorCode } from "./protocol.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/errors.ts
|
|
4
|
+
/**
|
|
5
|
+
* Base class for AFS HTTP errors
|
|
6
|
+
*/
|
|
7
|
+
var AFSHttpError = class extends Error {
|
|
8
|
+
constructor(message, code, httpStatus = 200, details) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.httpStatus = httpStatus;
|
|
12
|
+
this.details = details;
|
|
13
|
+
this.name = "AFSHttpError";
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Path not found error
|
|
18
|
+
*/
|
|
19
|
+
var AFSNotFoundError = class extends AFSHttpError {
|
|
20
|
+
constructor(path, details) {
|
|
21
|
+
super(`Path not found: ${path}`, AFSErrorCode.NOT_FOUND, 200, details);
|
|
22
|
+
this.name = "AFSNotFoundError";
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Permission denied error (including readonly mode)
|
|
27
|
+
*/
|
|
28
|
+
var AFSPermissionError = class extends AFSHttpError {
|
|
29
|
+
constructor(message, details) {
|
|
30
|
+
super(message, AFSErrorCode.PERMISSION_DENIED, 200, details);
|
|
31
|
+
this.name = "AFSPermissionError";
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Conflict error (concurrent modification)
|
|
36
|
+
*/
|
|
37
|
+
var AFSConflictError = class extends AFSHttpError {
|
|
38
|
+
constructor(message, details) {
|
|
39
|
+
super(message, AFSErrorCode.CONFLICT, 200, details);
|
|
40
|
+
this.name = "AFSConflictError";
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Runtime error
|
|
45
|
+
*/
|
|
46
|
+
var AFSRuntimeError = class extends AFSHttpError {
|
|
47
|
+
constructor(message, details) {
|
|
48
|
+
super(message, AFSErrorCode.RUNTIME_ERROR, 200, details);
|
|
49
|
+
this.name = "AFSRuntimeError";
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Invalid request error (bad JSON, invalid method, etc.)
|
|
54
|
+
*/
|
|
55
|
+
var AFSInvalidRequestError = class extends AFSHttpError {
|
|
56
|
+
constructor(message, details) {
|
|
57
|
+
super(message, AFSErrorCode.RUNTIME_ERROR, 400, details);
|
|
58
|
+
this.name = "AFSInvalidRequestError";
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Payload too large error
|
|
63
|
+
*/
|
|
64
|
+
var AFSPayloadTooLargeError = class extends AFSHttpError {
|
|
65
|
+
constructor(maxSize, actualSize) {
|
|
66
|
+
const message = actualSize ? `Payload too large: ${actualSize} bytes exceeds limit of ${maxSize} bytes` : `Payload too large: exceeds limit of ${maxSize} bytes`;
|
|
67
|
+
super(message, AFSErrorCode.RUNTIME_ERROR, 413, {
|
|
68
|
+
maxSize,
|
|
69
|
+
actualSize
|
|
70
|
+
});
|
|
71
|
+
this.name = "AFSPayloadTooLargeError";
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Network error (for client-side use)
|
|
76
|
+
*/
|
|
77
|
+
var AFSNetworkError = class extends Error {
|
|
78
|
+
constructor(message, cause, retryable = true) {
|
|
79
|
+
super(message);
|
|
80
|
+
this.cause = cause;
|
|
81
|
+
this.retryable = retryable;
|
|
82
|
+
this.name = "AFSNetworkError";
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Map common error messages to appropriate AFS error codes
|
|
87
|
+
*/
|
|
88
|
+
function mapErrorToCode(error) {
|
|
89
|
+
const message = error.message.toLowerCase();
|
|
90
|
+
if (message.includes("not found") || message.includes("enoent") || message.includes("does not exist")) return AFSErrorCode.NOT_FOUND;
|
|
91
|
+
if (message.includes("permission") || message.includes("readonly") || message.includes("read-only") || message.includes("access denied") || message.includes("eacces")) return AFSErrorCode.PERMISSION_DENIED;
|
|
92
|
+
if (message.includes("conflict") || message.includes("already exists") || message.includes("eexist")) return AFSErrorCode.CONFLICT;
|
|
93
|
+
return AFSErrorCode.RUNTIME_ERROR;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
//#endregion
|
|
97
|
+
export { AFSConflictError, AFSHttpError, AFSInvalidRequestError, AFSNetworkError, AFSNotFoundError, AFSPayloadTooLargeError, AFSPermissionError, AFSRuntimeError, mapErrorToCode };
|
|
98
|
+
//# sourceMappingURL=errors.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.mjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["import { AFSErrorCode } from \"./protocol.js\";\n\n/**\n * Base class for AFS HTTP errors\n */\nexport class AFSHttpError extends Error {\n constructor(\n message: string,\n public readonly code: AFSErrorCode,\n public readonly httpStatus: number = 200,\n public readonly details?: unknown,\n ) {\n super(message);\n this.name = \"AFSHttpError\";\n }\n}\n\n/**\n * Path not found error\n */\nexport class AFSNotFoundError extends AFSHttpError {\n constructor(path: string, details?: unknown) {\n super(`Path not found: ${path}`, AFSErrorCode.NOT_FOUND, 200, details);\n this.name = \"AFSNotFoundError\";\n }\n}\n\n/**\n * Permission denied error (including readonly mode)\n */\nexport class AFSPermissionError extends AFSHttpError {\n constructor(message: string, details?: unknown) {\n super(message, AFSErrorCode.PERMISSION_DENIED, 200, details);\n this.name = \"AFSPermissionError\";\n }\n}\n\n/**\n * Conflict error (concurrent modification)\n */\nexport class AFSConflictError extends AFSHttpError {\n constructor(message: string, details?: unknown) {\n super(message, AFSErrorCode.CONFLICT, 200, details);\n this.name = \"AFSConflictError\";\n }\n}\n\n/**\n * Runtime error\n */\nexport class AFSRuntimeError extends AFSHttpError {\n constructor(message: string, details?: unknown) {\n super(message, AFSErrorCode.RUNTIME_ERROR, 200, details);\n this.name = \"AFSRuntimeError\";\n }\n}\n\n/**\n * Invalid request error (bad JSON, invalid method, etc.)\n */\nexport class AFSInvalidRequestError extends AFSHttpError {\n constructor(message: string, details?: unknown) {\n super(message, AFSErrorCode.RUNTIME_ERROR, 400, details);\n this.name = \"AFSInvalidRequestError\";\n }\n}\n\n/**\n * Payload too large error\n */\nexport class AFSPayloadTooLargeError extends AFSHttpError {\n constructor(maxSize: number, actualSize?: number) {\n const message = actualSize\n ? `Payload too large: ${actualSize} bytes exceeds limit of ${maxSize} bytes`\n : `Payload too large: exceeds limit of ${maxSize} bytes`;\n super(message, AFSErrorCode.RUNTIME_ERROR, 413, { maxSize, actualSize });\n this.name = \"AFSPayloadTooLargeError\";\n }\n}\n\n/**\n * Network error (for client-side use)\n */\nexport class AFSNetworkError extends Error {\n constructor(\n message: string,\n public readonly cause?: Error,\n public readonly retryable: boolean = true,\n ) {\n super(message);\n this.name = \"AFSNetworkError\";\n }\n}\n\n/**\n * Map common error messages to appropriate AFS error codes\n */\nexport function mapErrorToCode(error: Error): AFSErrorCode {\n const message = error.message.toLowerCase();\n\n if (\n message.includes(\"not found\") ||\n message.includes(\"enoent\") ||\n message.includes(\"does not exist\")\n ) {\n return AFSErrorCode.NOT_FOUND;\n }\n\n if (\n message.includes(\"permission\") ||\n message.includes(\"readonly\") ||\n message.includes(\"read-only\") ||\n message.includes(\"access denied\") ||\n message.includes(\"eacces\")\n ) {\n return AFSErrorCode.PERMISSION_DENIED;\n }\n\n if (\n message.includes(\"conflict\") ||\n message.includes(\"already exists\") ||\n message.includes(\"eexist\")\n ) {\n return AFSErrorCode.CONFLICT;\n }\n\n return AFSErrorCode.RUNTIME_ERROR;\n}\n"],"mappings":";;;;;;AAKA,IAAa,eAAb,cAAkC,MAAM;CACtC,YACE,SACA,AAAgB,MAChB,AAAgB,aAAqB,KACrC,AAAgB,SAChB;AACA,QAAM,QAAQ;EAJE;EACA;EACA;AAGhB,OAAK,OAAO;;;;;;AAOhB,IAAa,mBAAb,cAAsC,aAAa;CACjD,YAAY,MAAc,SAAmB;AAC3C,QAAM,mBAAmB,QAAQ,aAAa,WAAW,KAAK,QAAQ;AACtE,OAAK,OAAO;;;;;;AAOhB,IAAa,qBAAb,cAAwC,aAAa;CACnD,YAAY,SAAiB,SAAmB;AAC9C,QAAM,SAAS,aAAa,mBAAmB,KAAK,QAAQ;AAC5D,OAAK,OAAO;;;;;;AAOhB,IAAa,mBAAb,cAAsC,aAAa;CACjD,YAAY,SAAiB,SAAmB;AAC9C,QAAM,SAAS,aAAa,UAAU,KAAK,QAAQ;AACnD,OAAK,OAAO;;;;;;AAOhB,IAAa,kBAAb,cAAqC,aAAa;CAChD,YAAY,SAAiB,SAAmB;AAC9C,QAAM,SAAS,aAAa,eAAe,KAAK,QAAQ;AACxD,OAAK,OAAO;;;;;;AAOhB,IAAa,yBAAb,cAA4C,aAAa;CACvD,YAAY,SAAiB,SAAmB;AAC9C,QAAM,SAAS,aAAa,eAAe,KAAK,QAAQ;AACxD,OAAK,OAAO;;;;;;AAOhB,IAAa,0BAAb,cAA6C,aAAa;CACxD,YAAY,SAAiB,YAAqB;EAChD,MAAM,UAAU,aACZ,sBAAsB,WAAW,0BAA0B,QAAQ,UACnE,uCAAuC,QAAQ;AACnD,QAAM,SAAS,aAAa,eAAe,KAAK;GAAE;GAAS;GAAY,CAAC;AACxE,OAAK,OAAO;;;;;;AAOhB,IAAa,kBAAb,cAAqC,MAAM;CACzC,YACE,SACA,AAAgB,OAChB,AAAgB,YAAqB,MACrC;AACA,QAAM,QAAQ;EAHE;EACA;AAGhB,OAAK,OAAO;;;;;;AAOhB,SAAgB,eAAe,OAA4B;CACzD,MAAM,UAAU,MAAM,QAAQ,aAAa;AAE3C,KACE,QAAQ,SAAS,YAAY,IAC7B,QAAQ,SAAS,SAAS,IAC1B,QAAQ,SAAS,iBAAiB,CAElC,QAAO,aAAa;AAGtB,KACE,QAAQ,SAAS,aAAa,IAC9B,QAAQ,SAAS,WAAW,IAC5B,QAAQ,SAAS,YAAY,IAC7B,QAAQ,SAAS,gBAAgB,IACjC,QAAQ,SAAS,SAAS,CAE1B,QAAO,aAAa;AAGtB,KACE,QAAQ,SAAS,WAAW,IAC5B,QAAQ,SAAS,iBAAiB,IAClC,QAAQ,SAAS,SAAS,CAE1B,QAAO,aAAa;AAGtB,QAAO,aAAa"}
|
package/dist/handler.cjs
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
const require_protocol = require('./protocol.cjs');
|
|
2
|
+
const require_errors = require('./errors.cjs');
|
|
3
|
+
|
|
4
|
+
//#region src/handler.ts
|
|
5
|
+
/**
|
|
6
|
+
* Default handler options
|
|
7
|
+
*/
|
|
8
|
+
const DEFAULT_OPTIONS = {
|
|
9
|
+
maxBodySize: 10 * 1024 * 1024,
|
|
10
|
+
timeout: 3e4
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Create an AFS HTTP handler function
|
|
14
|
+
*
|
|
15
|
+
* This function creates a pure handler that accepts a Web Standard Request
|
|
16
|
+
* and returns a Web Standard Response. It can be used with any HTTP framework
|
|
17
|
+
* that supports these standards (Hono, Bun, Deno, etc.) or adapted for
|
|
18
|
+
* frameworks like Express and Koa.
|
|
19
|
+
*
|
|
20
|
+
* @param options - Handler options
|
|
21
|
+
* @returns A handler function that processes AFS RPC requests
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* // With Hono
|
|
26
|
+
* const handler = createAFSHttpHandler({ module: provider });
|
|
27
|
+
* app.post("/afs/rpc", (c) => handler(c.req.raw));
|
|
28
|
+
*
|
|
29
|
+
* // With Bun
|
|
30
|
+
* Bun.serve({
|
|
31
|
+
* fetch(req) {
|
|
32
|
+
* if (url.pathname === "/afs/rpc") return handler(req);
|
|
33
|
+
* }
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
function createAFSHttpHandler(options) {
|
|
38
|
+
const { module, maxBodySize = DEFAULT_OPTIONS.maxBodySize } = options;
|
|
39
|
+
return async (request) => {
|
|
40
|
+
try {
|
|
41
|
+
if (request.method !== "POST") return createJsonResponse(require_protocol.createErrorResponse(require_protocol.AFSErrorCode.RUNTIME_ERROR, `Method not allowed: ${request.method}`), 405);
|
|
42
|
+
if (!request.headers.get("content-type")?.includes("application/json")) return createJsonResponse(require_protocol.createErrorResponse(require_protocol.AFSErrorCode.RUNTIME_ERROR, "Content-Type must be application/json"), 400);
|
|
43
|
+
const contentLength = request.headers.get("content-length");
|
|
44
|
+
if (contentLength && Number.parseInt(contentLength, 10) > maxBodySize) {
|
|
45
|
+
const error = new require_errors.AFSPayloadTooLargeError(maxBodySize, Number.parseInt(contentLength, 10));
|
|
46
|
+
return createJsonResponse(require_protocol.createErrorResponse(error.code, error.message, error.details), error.httpStatus);
|
|
47
|
+
}
|
|
48
|
+
let body;
|
|
49
|
+
try {
|
|
50
|
+
const text = await request.text();
|
|
51
|
+
if (text.length > maxBodySize) {
|
|
52
|
+
const error = new require_errors.AFSPayloadTooLargeError(maxBodySize, text.length);
|
|
53
|
+
return createJsonResponse(require_protocol.createErrorResponse(error.code, error.message, error.details), error.httpStatus);
|
|
54
|
+
}
|
|
55
|
+
body = JSON.parse(text);
|
|
56
|
+
} catch {
|
|
57
|
+
return createJsonResponse(require_protocol.createErrorResponse(require_protocol.AFSErrorCode.RUNTIME_ERROR, "Invalid JSON body"), 400);
|
|
58
|
+
}
|
|
59
|
+
if (!body || typeof body !== "object") return createJsonResponse(require_protocol.createErrorResponse(require_protocol.AFSErrorCode.RUNTIME_ERROR, "Request body must be an object"), 400);
|
|
60
|
+
const { method, params } = body;
|
|
61
|
+
if (!method || typeof method !== "string") return createJsonResponse(require_protocol.createErrorResponse(require_protocol.AFSErrorCode.RUNTIME_ERROR, "Missing or invalid method"), 400);
|
|
62
|
+
if (!require_protocol.isValidRpcMethod(method)) return createJsonResponse(require_protocol.createErrorResponse(require_protocol.AFSErrorCode.RUNTIME_ERROR, `Unknown method: ${method}`), 400);
|
|
63
|
+
if (!params || typeof params !== "object") return createJsonResponse(require_protocol.createErrorResponse(require_protocol.AFSErrorCode.RUNTIME_ERROR, "Missing or invalid params"), 400);
|
|
64
|
+
return createJsonResponse(require_protocol.createSuccessResponse(await executeRpcMethod(module, method, params)), 200);
|
|
65
|
+
} catch (error) {
|
|
66
|
+
if (error instanceof require_errors.AFSHttpError) return createJsonResponse(require_protocol.createErrorResponse(error.code, error.message, error.details), error.httpStatus);
|
|
67
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
68
|
+
return createJsonResponse(require_protocol.createErrorResponse(error instanceof Error ? require_errors.mapErrorToCode(error) : require_protocol.AFSErrorCode.RUNTIME_ERROR, message), 200);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Execute an RPC method on the module
|
|
74
|
+
*/
|
|
75
|
+
async function executeRpcMethod(module, method, params) {
|
|
76
|
+
switch (method) {
|
|
77
|
+
case "list": {
|
|
78
|
+
if (!module.list) throw new require_errors.AFSInvalidRequestError("Module does not support list operation");
|
|
79
|
+
const { path, options } = params;
|
|
80
|
+
return await module.list(path, options);
|
|
81
|
+
}
|
|
82
|
+
case "read": {
|
|
83
|
+
if (!module.read) throw new require_errors.AFSInvalidRequestError("Module does not support read operation");
|
|
84
|
+
const { path, options } = params;
|
|
85
|
+
return await module.read(path, options);
|
|
86
|
+
}
|
|
87
|
+
case "write": {
|
|
88
|
+
if (!module.write) throw new require_errors.AFSInvalidRequestError("Module does not support write operation");
|
|
89
|
+
const { path, content, options } = params;
|
|
90
|
+
return await module.write(path, content, options);
|
|
91
|
+
}
|
|
92
|
+
case "delete": {
|
|
93
|
+
if (!module.delete) throw new require_errors.AFSInvalidRequestError("Module does not support delete operation");
|
|
94
|
+
const { path, options } = params;
|
|
95
|
+
return await module.delete(path, options);
|
|
96
|
+
}
|
|
97
|
+
case "rename": {
|
|
98
|
+
if (!module.rename) throw new require_errors.AFSInvalidRequestError("Module does not support rename operation");
|
|
99
|
+
const { oldPath, newPath, options } = params;
|
|
100
|
+
return await module.rename(oldPath, newPath, options);
|
|
101
|
+
}
|
|
102
|
+
case "search": {
|
|
103
|
+
if (!module.search) throw new require_errors.AFSInvalidRequestError("Module does not support search operation");
|
|
104
|
+
const { path, query, options } = params;
|
|
105
|
+
return await module.search(path, query, options);
|
|
106
|
+
}
|
|
107
|
+
case "exec": {
|
|
108
|
+
if (!module.exec) throw new require_errors.AFSInvalidRequestError("Module does not support exec operation");
|
|
109
|
+
const { path, args, options } = params;
|
|
110
|
+
return await module.exec(path, args, options);
|
|
111
|
+
}
|
|
112
|
+
default: throw new require_errors.AFSInvalidRequestError(`Unknown method: ${method}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Create a JSON Response with proper headers
|
|
117
|
+
*/
|
|
118
|
+
function createJsonResponse(body, status) {
|
|
119
|
+
return new Response(JSON.stringify(body), {
|
|
120
|
+
status,
|
|
121
|
+
headers: { "Content-Type": "application/json" }
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
//#endregion
|
|
126
|
+
exports.createAFSHttpHandler = createAFSHttpHandler;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { AFSModule } from "@aigne/afs";
|
|
2
|
+
|
|
3
|
+
//#region src/handler.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Options for creating an AFS HTTP handler
|
|
6
|
+
*/
|
|
7
|
+
interface AFSHttpHandlerOptions {
|
|
8
|
+
/** The AFS module to expose */
|
|
9
|
+
module: AFSModule;
|
|
10
|
+
/** Maximum request body size in bytes (default: 10MB) */
|
|
11
|
+
maxBodySize?: number;
|
|
12
|
+
/** Request timeout in milliseconds (default: 30000) */
|
|
13
|
+
timeout?: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Create an AFS HTTP handler function
|
|
17
|
+
*
|
|
18
|
+
* This function creates a pure handler that accepts a Web Standard Request
|
|
19
|
+
* and returns a Web Standard Response. It can be used with any HTTP framework
|
|
20
|
+
* that supports these standards (Hono, Bun, Deno, etc.) or adapted for
|
|
21
|
+
* frameworks like Express and Koa.
|
|
22
|
+
*
|
|
23
|
+
* @param options - Handler options
|
|
24
|
+
* @returns A handler function that processes AFS RPC requests
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* // With Hono
|
|
29
|
+
* const handler = createAFSHttpHandler({ module: provider });
|
|
30
|
+
* app.post("/afs/rpc", (c) => handler(c.req.raw));
|
|
31
|
+
*
|
|
32
|
+
* // With Bun
|
|
33
|
+
* Bun.serve({
|
|
34
|
+
* fetch(req) {
|
|
35
|
+
* if (url.pathname === "/afs/rpc") return handler(req);
|
|
36
|
+
* }
|
|
37
|
+
* });
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
declare function createAFSHttpHandler(options: AFSHttpHandlerOptions): (request: Request) => Promise<Response>;
|
|
41
|
+
//#endregion
|
|
42
|
+
export { AFSHttpHandlerOptions, createAFSHttpHandler };
|
|
43
|
+
//# sourceMappingURL=handler.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.cts","names":[],"sources":["../src/handler.ts"],"mappings":";;;;AAoBA;AA0CA;UA1CiB,qBAAA;EAAA;EAAA,MAAA,EAEP,SAAA;EAAA;EAAA,WAAA;EAAA;EAAA,OAAA;AAAA;AAAA;AAwCV;;;;;;;;;;;;;;;;;;;;;;;;AAxCU,iBAwCM,oBAAA,CAAA,OAAA,EACL,qBAAA,IAAA,OAAA,EACE,OAAA,KAAY,OAAA,CAAQ,QAAA"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { AFSModule } from "@aigne/afs";
|
|
2
|
+
|
|
3
|
+
//#region src/handler.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Options for creating an AFS HTTP handler
|
|
6
|
+
*/
|
|
7
|
+
interface AFSHttpHandlerOptions {
|
|
8
|
+
/** The AFS module to expose */
|
|
9
|
+
module: AFSModule;
|
|
10
|
+
/** Maximum request body size in bytes (default: 10MB) */
|
|
11
|
+
maxBodySize?: number;
|
|
12
|
+
/** Request timeout in milliseconds (default: 30000) */
|
|
13
|
+
timeout?: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Create an AFS HTTP handler function
|
|
17
|
+
*
|
|
18
|
+
* This function creates a pure handler that accepts a Web Standard Request
|
|
19
|
+
* and returns a Web Standard Response. It can be used with any HTTP framework
|
|
20
|
+
* that supports these standards (Hono, Bun, Deno, etc.) or adapted for
|
|
21
|
+
* frameworks like Express and Koa.
|
|
22
|
+
*
|
|
23
|
+
* @param options - Handler options
|
|
24
|
+
* @returns A handler function that processes AFS RPC requests
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* // With Hono
|
|
29
|
+
* const handler = createAFSHttpHandler({ module: provider });
|
|
30
|
+
* app.post("/afs/rpc", (c) => handler(c.req.raw));
|
|
31
|
+
*
|
|
32
|
+
* // With Bun
|
|
33
|
+
* Bun.serve({
|
|
34
|
+
* fetch(req) {
|
|
35
|
+
* if (url.pathname === "/afs/rpc") return handler(req);
|
|
36
|
+
* }
|
|
37
|
+
* });
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
declare function createAFSHttpHandler(options: AFSHttpHandlerOptions): (request: Request) => Promise<Response>;
|
|
41
|
+
//#endregion
|
|
42
|
+
export { AFSHttpHandlerOptions, createAFSHttpHandler };
|
|
43
|
+
//# sourceMappingURL=handler.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.mts","names":[],"sources":["../src/handler.ts"],"mappings":";;;;AAoBA;AA0CA;UA1CiB,qBAAA;EAAA;EAAA,MAAA,EAEP,SAAA;EAAA;EAAA,WAAA;EAAA;EAAA,OAAA;AAAA;AAAA;AAwCV;;;;;;;;;;;;;;;;;;;;;;;;AAxCU,iBAwCM,oBAAA,CAAA,OAAA,EACL,qBAAA,IAAA,OAAA,EACE,OAAA,KAAY,OAAA,CAAQ,QAAA"}
|