jitar 0.3.9 → 0.4.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/CHANGELOG.md +1 -94
- package/dist/client.js +1 -24
- package/dist/globals-9eff87d1.js +1 -0
- package/dist/lib.d.ts +340 -35
- package/dist/lib.js +1 -29
- package/dist/server.js +1 -0
- package/package.json +22 -12
- package/LICENCE +0 -23
- package/dist/client.d.ts +0 -3
- package/dist/core/Context.d.ts +0 -5
- package/dist/core/Context.js +0 -7
- package/dist/core/ErrorManager.d.ts +0 -3
- package/dist/core/ErrorManager.js +0 -11
- package/dist/core/Implementation.d.ts +0 -10
- package/dist/core/Implementation.js +0 -44
- package/dist/core/Procedure.d.ts +0 -13
- package/dist/core/Procedure.js +0 -58
- package/dist/core/Segment.d.ts +0 -13
- package/dist/core/Segment.js +0 -36
- package/dist/core/SegmentBuilder.d.ts +0 -6
- package/dist/core/SegmentBuilder.js +0 -32
- package/dist/core/Version.d.ts +0 -13
- package/dist/core/Version.js +0 -50
- package/dist/core/definitions/AccessLevel.d.ts +0 -2
- package/dist/core/definitions/AccessLevel.js +0 -2
- package/dist/core/errors/BadRequest.d.ts +0 -3
- package/dist/core/errors/BadRequest.js +0 -6
- package/dist/core/errors/Forbidden.d.ts +0 -3
- package/dist/core/errors/Forbidden.js +0 -6
- package/dist/core/errors/ImplementationNotFound.d.ts +0 -4
- package/dist/core/errors/ImplementationNotFound.js +0 -7
- package/dist/core/errors/InvalidVersionNumber.d.ts +0 -4
- package/dist/core/errors/InvalidVersionNumber.js +0 -7
- package/dist/core/errors/MissingParameterValue.d.ts +0 -4
- package/dist/core/errors/MissingParameterValue.js +0 -7
- package/dist/core/errors/NotFound.d.ts +0 -3
- package/dist/core/errors/NotFound.js +0 -6
- package/dist/core/errors/NotImplemented.d.ts +0 -3
- package/dist/core/errors/NotImplemented.js +0 -6
- package/dist/core/errors/PaymentRequired.d.ts +0 -3
- package/dist/core/errors/PaymentRequired.js +0 -6
- package/dist/core/errors/ProcedureNotFound.d.ts +0 -4
- package/dist/core/errors/ProcedureNotFound.js +0 -7
- package/dist/core/errors/Teapot.d.ts +0 -3
- package/dist/core/errors/Teapot.js +0 -6
- package/dist/core/errors/Unauthorized.d.ts +0 -3
- package/dist/core/errors/Unauthorized.js +0 -6
- package/dist/core/errors/UnknownParameter.d.ts +0 -4
- package/dist/core/errors/UnknownParameter.js +0 -7
- package/dist/core/interfaces/Runner.d.ts +0 -4
- package/dist/core/interfaces/Runner.js +0 -1
- package/dist/core/reflection/ParameterParser.d.ts +0 -5
- package/dist/core/reflection/ParameterParser.js +0 -51
- package/dist/core/reflection/ReflectionHelper.d.ts +0 -13
- package/dist/core/reflection/ReflectionHelper.js +0 -69
- package/dist/core/reflection/models/ReflectionField.d.ts +0 -8
- package/dist/core/reflection/models/ReflectionField.js +0 -14
- package/dist/core/reflection/models/ReflectionParameter.d.ts +0 -7
- package/dist/core/reflection/models/ReflectionParameter.js +0 -11
- package/dist/core/types/Component.d.ts +0 -5
- package/dist/core/types/Component.js +0 -1
- package/dist/core/types/FlexObject.d.ts +0 -4
- package/dist/core/types/FlexObject.js +0 -1
- package/dist/core/types/Module.d.ts +0 -3
- package/dist/core/types/Module.js +0 -1
- package/dist/core/types/SegmentImplementation.d.ts +0 -6
- package/dist/core/types/SegmentImplementation.js +0 -1
- package/dist/core/types/SegmentModule.d.ts +0 -5
- package/dist/core/types/SegmentModule.js +0 -1
- package/dist/core/types/SegmentProcedure.d.ts +0 -7
- package/dist/core/types/SegmentProcedure.js +0 -1
- package/dist/core/utils/FqnBuilder.d.ts +0 -3
- package/dist/core/utils/FqnBuilder.js +0 -5
- package/dist/hooks.d.ts +0 -2
- package/dist/hooks.js +0 -2
- package/dist/runtime/ClientId.d.ts +0 -4
- package/dist/runtime/ClientId.js +0 -11
- package/dist/runtime/Gateway.d.ts +0 -5
- package/dist/runtime/Gateway.js +0 -3
- package/dist/runtime/LocalGateway.d.ts +0 -14
- package/dist/runtime/LocalGateway.js +0 -61
- package/dist/runtime/LocalNode.d.ts +0 -18
- package/dist/runtime/LocalNode.js +0 -75
- package/dist/runtime/LocalRepository.d.ts +0 -17
- package/dist/runtime/LocalRepository.js +0 -94
- package/dist/runtime/Node.d.ts +0 -3
- package/dist/runtime/Node.js +0 -3
- package/dist/runtime/NodeBalancer.d.ts +0 -9
- package/dist/runtime/NodeBalancer.js +0 -34
- package/dist/runtime/NodeMonitor.d.ts +0 -7
- package/dist/runtime/NodeMonitor.js +0 -38
- package/dist/runtime/ProcedureRunner.d.ts +0 -9
- package/dist/runtime/ProcedureRunner.js +0 -11
- package/dist/runtime/ProcedureRuntime.d.ts +0 -14
- package/dist/runtime/ProcedureRuntime.js +0 -28
- package/dist/runtime/Proxy.d.ts +0 -18
- package/dist/runtime/Proxy.js +0 -33
- package/dist/runtime/Remote.d.ts +0 -15
- package/dist/runtime/Remote.js +0 -102
- package/dist/runtime/RemoteGateway.d.ts +0 -11
- package/dist/runtime/RemoteGateway.js +0 -22
- package/dist/runtime/RemoteNode.d.ts +0 -12
- package/dist/runtime/RemoteNode.js +0 -29
- package/dist/runtime/RemoteRepository.d.ts +0 -14
- package/dist/runtime/RemoteRepository.js +0 -34
- package/dist/runtime/Repository.d.ts +0 -11
- package/dist/runtime/Repository.js +0 -3
- package/dist/runtime/Runtime.d.ts +0 -9
- package/dist/runtime/Runtime.js +0 -27
- package/dist/runtime/caching/CacheBuilder.d.ts +0 -6
- package/dist/runtime/caching/CacheBuilder.js +0 -246
- package/dist/runtime/caching/ImportRewriter.d.ts +0 -4
- package/dist/runtime/caching/ImportRewriter.js +0 -58
- package/dist/runtime/caching/RemoteBuilder.d.ts +0 -5
- package/dist/runtime/caching/RemoteBuilder.js +0 -31
- package/dist/runtime/caching/SourceAppender.d.ts +0 -5
- package/dist/runtime/caching/SourceAppender.js +0 -30
- package/dist/runtime/caching/definitions/Keywords.d.ts +0 -2
- package/dist/runtime/caching/definitions/Keywords.js +0 -2
- package/dist/runtime/caching/errors/InvalidSegmentFilename.d.ts +0 -3
- package/dist/runtime/caching/errors/InvalidSegmentFilename.js +0 -5
- package/dist/runtime/caching/errors/MissingModuleExport.d.ts +0 -3
- package/dist/runtime/caching/errors/MissingModuleExport.js +0 -5
- package/dist/runtime/caching/errors/SegmentFileNotLoaded.d.ts +0 -3
- package/dist/runtime/caching/errors/SegmentFileNotLoaded.js +0 -5
- package/dist/runtime/caching/errors/SegmentModuleNotLoaded.d.ts +0 -3
- package/dist/runtime/caching/errors/SegmentModuleNotLoaded.js +0 -5
- package/dist/runtime/caching/models/ApplicationModule.d.ts +0 -10
- package/dist/runtime/caching/models/ApplicationModule.js +0 -19
- package/dist/runtime/caching/models/Implementation.d.ts +0 -12
- package/dist/runtime/caching/models/Implementation.js +0 -27
- package/dist/runtime/caching/models/Procedure.d.ts +0 -9
- package/dist/runtime/caching/models/Procedure.js +0 -15
- package/dist/runtime/caching/models/Segment.d.ts +0 -10
- package/dist/runtime/caching/models/Segment.js +0 -16
- package/dist/runtime/caching/models/SegmentModule.d.ts +0 -10
- package/dist/runtime/caching/models/SegmentModule.js +0 -14
- package/dist/runtime/caching/types/SegmentFile.d.ts +0 -5
- package/dist/runtime/caching/types/SegmentFile.js +0 -1
- package/dist/runtime/caching/types/SegmentImportProperties.d.ts +0 -6
- package/dist/runtime/caching/types/SegmentImportProperties.js +0 -1
- package/dist/runtime/caching/types/SegmentImports.d.ts +0 -5
- package/dist/runtime/caching/types/SegmentImports.js +0 -1
- package/dist/runtime/errors/ClientNotFound.d.ts +0 -3
- package/dist/runtime/errors/ClientNotFound.js +0 -6
- package/dist/runtime/errors/FileNotFound.d.ts +0 -3
- package/dist/runtime/errors/FileNotFound.js +0 -6
- package/dist/runtime/errors/InvalidClientId.d.ts +0 -3
- package/dist/runtime/errors/InvalidClientId.js +0 -6
- package/dist/runtime/errors/InvalidJitarHooks.d.ts +0 -3
- package/dist/runtime/errors/InvalidJitarHooks.js +0 -6
- package/dist/runtime/errors/InvalidSegmentFile.d.ts +0 -3
- package/dist/runtime/errors/InvalidSegmentFile.js +0 -6
- package/dist/runtime/errors/ModuleNotLoaded.d.ts +0 -3
- package/dist/runtime/errors/ModuleNotLoaded.js +0 -6
- package/dist/runtime/errors/NoNodeAvailable.d.ts +0 -3
- package/dist/runtime/errors/NoNodeAvailable.js +0 -6
- package/dist/runtime/errors/RepositoryNotAvaiable.d.ts +0 -3
- package/dist/runtime/errors/RepositoryNotAvaiable.js +0 -6
- package/dist/runtime/errors/RuntimeNotAvailable.d.ts +0 -3
- package/dist/runtime/errors/RuntimeNotAvailable.js +0 -6
- package/dist/runtime/errors/SegmentNotFound.d.ts +0 -3
- package/dist/runtime/errors/SegmentNotFound.js +0 -6
- package/dist/runtime/hooks/dependencies.d.ts +0 -2
- package/dist/runtime/hooks/dependencies.js +0 -9
- package/dist/runtime/hooks/runtime.d.ts +0 -3
- package/dist/runtime/hooks/runtime.js +0 -16
- package/dist/runtime/interfaces/FileManager.d.ts +0 -11
- package/dist/runtime/interfaces/FileManager.js +0 -1
- package/dist/runtime/interfaces/HealthCheck.d.ts +0 -3
- package/dist/runtime/interfaces/HealthCheck.js +0 -1
- package/dist/runtime/interfaces/Middleware.d.ts +0 -5
- package/dist/runtime/interfaces/Middleware.js +0 -1
- package/dist/runtime/middleware/CorsMiddleware.d.ts +0 -11
- package/dist/runtime/middleware/CorsMiddleware.js +0 -22
- package/dist/runtime/models/File.d.ts +0 -9
- package/dist/runtime/models/File.js +0 -14
- package/dist/runtime/serialization/ArrayBufferSerializer.d.ts +0 -10
- package/dist/runtime/serialization/ArrayBufferSerializer.js +0 -54
- package/dist/runtime/serialization/ArraySerializer.d.ts +0 -7
- package/dist/runtime/serialization/ArraySerializer.js +0 -15
- package/dist/runtime/serialization/ClassSerializer.d.ts +0 -10
- package/dist/runtime/serialization/ClassSerializer.js +0 -74
- package/dist/runtime/serialization/DateSerializer.d.ts +0 -9
- package/dist/runtime/serialization/DateSerializer.js +0 -21
- package/dist/runtime/serialization/MapSerializer.d.ts +0 -9
- package/dist/runtime/serialization/MapSerializer.js +0 -35
- package/dist/runtime/serialization/ObjectSerializer.d.ts +0 -9
- package/dist/runtime/serialization/ObjectSerializer.js +0 -21
- package/dist/runtime/serialization/SetSerializer.d.ts +0 -9
- package/dist/runtime/serialization/SetSerializer.js +0 -23
- package/dist/runtime/serialization/ValueSerializer.d.ts +0 -8
- package/dist/runtime/serialization/ValueSerializer.js +0 -69
- package/dist/runtime/serialization/errors/ClassNotFound.d.ts +0 -3
- package/dist/runtime/serialization/errors/ClassNotFound.js +0 -6
- package/dist/runtime/serialization/errors/InvalidClass.d.ts +0 -3
- package/dist/runtime/serialization/errors/InvalidClass.js +0 -6
- package/dist/runtime/serialization/errors/InvalidPropertyType.d.ts +0 -4
- package/dist/runtime/serialization/errors/InvalidPropertyType.js +0 -7
- package/dist/runtime/serialization/interfaces/Serializer.d.ts +0 -4
- package/dist/runtime/serialization/interfaces/Serializer.js +0 -1
- package/dist/runtime/serialization/types/SerializableObject.d.ts +0 -3
- package/dist/runtime/serialization/types/SerializableObject.js +0 -1
- package/dist/runtime/serialization/types/Serialized.d.ts +0 -5
- package/dist/runtime/serialization/types/Serialized.js +0 -1
- package/dist/runtime/serialization/types/SerializedArrayBuffer.d.ts +0 -6
- package/dist/runtime/serialization/types/SerializedArrayBuffer.js +0 -1
- package/dist/runtime/serialization/types/SerializedClass.d.ts +0 -8
- package/dist/runtime/serialization/types/SerializedClass.js +0 -1
- package/dist/runtime/serialization/types/SerializedDate.d.ts +0 -5
- package/dist/runtime/serialization/types/SerializedDate.js +0 -1
- package/dist/runtime/serialization/types/SerializedMap.d.ts +0 -8
- package/dist/runtime/serialization/types/SerializedMap.js +0 -1
- package/dist/runtime/serialization/types/SerializedObject.d.ts +0 -4
- package/dist/runtime/serialization/types/SerializedObject.js +0 -1
- package/dist/runtime/serialization/types/SerializedSet.d.ts +0 -5
- package/dist/runtime/serialization/types/SerializedSet.js +0 -1
- package/dist/runtime/serialization/types/TypedArray.d.ts +0 -2
- package/dist/runtime/serialization/types/TypedArray.js +0 -1
- package/dist/runtime/types/JitarHooks.d.ts +0 -6
- package/dist/runtime/types/JitarHooks.js +0 -1
- package/dist/runtime/types/ModuleImporter.d.ts +0 -3
- package/dist/runtime/types/ModuleImporter.js +0 -1
- package/dist/runtime/types/NextHandler.d.ts +0 -2
- package/dist/runtime/types/NextHandler.js +0 -1
- package/dist/runtime/utils/ModuleAnalyser.d.ts +0 -7
- package/dist/runtime/utils/ModuleAnalyser.js +0 -23
- package/dist/runtime/utils/ModuleLoader.d.ts +0 -8
- package/dist/runtime/utils/ModuleLoader.js +0 -30
- package/dist/runtime/utils/UrlRewriter.d.ts +0 -4
- package/dist/runtime/utils/UrlRewriter.js +0 -36
package/dist/lib.d.ts
CHANGED
|
@@ -1,35 +1,340 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
declare class BadRequest extends Error {
|
|
3
|
+
constructor(message?: string);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
declare class Forbidden extends Error {
|
|
7
|
+
constructor(message?: string);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
declare class NotFound extends Error {
|
|
11
|
+
constructor(message?: string);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
declare class NotImplemented extends Error {
|
|
15
|
+
constructor(message?: string);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
declare class PaymentRequired extends Error {
|
|
19
|
+
constructor(message?: string);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
declare class ServerError extends Error {
|
|
23
|
+
constructor(message?: string);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
declare class Teapot extends Error {
|
|
27
|
+
constructor();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
declare class Unauthorized extends Error {
|
|
31
|
+
constructor(message?: string);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
declare class ClientNotFound extends BadRequest {
|
|
35
|
+
#private;
|
|
36
|
+
constructor(clientId: string);
|
|
37
|
+
get clientId(): string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
declare class FileNotFound extends NotFound {
|
|
41
|
+
#private;
|
|
42
|
+
constructor(filename: string);
|
|
43
|
+
get filename(): string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
declare class ImplementationNotFound extends NotFound {
|
|
47
|
+
#private;
|
|
48
|
+
constructor(fqn: string, version: string);
|
|
49
|
+
get fqn(): string;
|
|
50
|
+
get version(): string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
declare class InvalidClientId extends BadRequest {
|
|
54
|
+
#private;
|
|
55
|
+
constructor(clientId: string);
|
|
56
|
+
get clientId(): string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
declare class InvalidParameterValue extends BadRequest {
|
|
60
|
+
#private;
|
|
61
|
+
constructor(parameterName: string);
|
|
62
|
+
get parameterName(): string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
declare class InvalidSegmentFile extends ServerError {
|
|
66
|
+
#private;
|
|
67
|
+
constructor(filename: string);
|
|
68
|
+
get filename(): string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
declare class InvalidVersionNumber extends BadRequest {
|
|
72
|
+
#private;
|
|
73
|
+
constructor(number: string);
|
|
74
|
+
get number(): string;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
declare class MissingParameterValue extends BadRequest {
|
|
78
|
+
#private;
|
|
79
|
+
constructor(parameterName: string);
|
|
80
|
+
get parameterName(): string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
declare class ModuleNotAccessible extends Forbidden {
|
|
84
|
+
#private;
|
|
85
|
+
constructor(url: string);
|
|
86
|
+
get url(): string;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
declare class ModuleNotLoaded extends ServerError {
|
|
90
|
+
#private;
|
|
91
|
+
constructor(url: string, reason?: string);
|
|
92
|
+
get url(): string;
|
|
93
|
+
get reason(): string | undefined;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
declare class NoNodeAvailable extends ServerError {
|
|
97
|
+
#private;
|
|
98
|
+
constructor(name: string);
|
|
99
|
+
get name(): string;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
declare class ProcedureNotAccessible extends Forbidden {
|
|
103
|
+
#private;
|
|
104
|
+
constructor(fqn: string, versionNumber: string);
|
|
105
|
+
get fqn(): string;
|
|
106
|
+
get versionNumber(): string;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
declare class ProcedureNotFound extends NotFound {
|
|
110
|
+
#private;
|
|
111
|
+
constructor(fqn: string);
|
|
112
|
+
get fqn(): string;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
declare class RepositoryNotAvailable extends ServerError {
|
|
116
|
+
constructor();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
declare class RuntimeNotAvailable extends ServerError {
|
|
120
|
+
constructor();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
declare class SegmentNotFound extends ServerError {
|
|
124
|
+
#private;
|
|
125
|
+
constructor(source: string);
|
|
126
|
+
get source(): string;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
declare class UnknownParameter extends BadRequest {
|
|
130
|
+
#private;
|
|
131
|
+
constructor(parameterName: string);
|
|
132
|
+
get parameterName(): string;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
declare class File {
|
|
136
|
+
#private;
|
|
137
|
+
constructor(location: string, type: string, content: Buffer | string);
|
|
138
|
+
get location(): string;
|
|
139
|
+
get type(): string;
|
|
140
|
+
get content(): string | Buffer;
|
|
141
|
+
get size(): number;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
interface HealthCheck {
|
|
145
|
+
get timeout(): number | undefined;
|
|
146
|
+
isHealthy(): Promise<boolean>;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
declare class Version {
|
|
150
|
+
#private;
|
|
151
|
+
static get DEFAULT(): Version;
|
|
152
|
+
constructor(major?: number, minor?: number, patch?: number);
|
|
153
|
+
get major(): number;
|
|
154
|
+
get minor(): number;
|
|
155
|
+
get patch(): number;
|
|
156
|
+
equals(version: Version): boolean;
|
|
157
|
+
greater(version: Version): boolean;
|
|
158
|
+
less(version: Version): boolean;
|
|
159
|
+
toString(): string;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
type NextHandler = () => Promise<unknown>;
|
|
163
|
+
|
|
164
|
+
interface Middleware {
|
|
165
|
+
handle(fqn: string, version: Version, args: Map<string, unknown>, headers: Map<string, string>, next: NextHandler): Promise<unknown>;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
declare class Parameter {
|
|
169
|
+
#private;
|
|
170
|
+
constructor(name: string, isOptional?: boolean);
|
|
171
|
+
get name(): string;
|
|
172
|
+
get isOptional(): boolean;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
declare class DestructuredParameter extends Parameter {
|
|
176
|
+
#private;
|
|
177
|
+
constructor(variables: Parameter[], name?: string, isOptional?: boolean);
|
|
178
|
+
get variables(): Parameter[];
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
declare class ArrayParameter extends DestructuredParameter {
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
declare class Implementation {
|
|
185
|
+
#private;
|
|
186
|
+
constructor(version: Version, access: string, parameters: Parameter[], executable: Function);
|
|
187
|
+
get version(): Version;
|
|
188
|
+
get public(): boolean;
|
|
189
|
+
get parameters(): Parameter[];
|
|
190
|
+
get executable(): Function;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
declare class NamedParameter extends Parameter {
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
declare class ObjectParameter extends DestructuredParameter {
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
declare class Procedure {
|
|
200
|
+
#private;
|
|
201
|
+
constructor(fqn: string);
|
|
202
|
+
get fqn(): string;
|
|
203
|
+
get public(): boolean;
|
|
204
|
+
addImplementation(implementation: Implementation): Procedure;
|
|
205
|
+
getImplementation(version: Version): Implementation | undefined;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
declare class Segment {
|
|
209
|
+
#private;
|
|
210
|
+
constructor(id: string);
|
|
211
|
+
get id(): string;
|
|
212
|
+
addProcedure(procedure: Procedure): Segment;
|
|
213
|
+
hasProcedure(fqn: string): boolean;
|
|
214
|
+
getProcedure(fqn: string): Procedure | undefined;
|
|
215
|
+
getPublicProcedures(): Procedure[];
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
interface Runner {
|
|
219
|
+
run(fqn: string, version: Version, args: Map<string, unknown>, headers: Map<string, string>): Promise<unknown>;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
declare abstract class Runtime {
|
|
223
|
+
#private;
|
|
224
|
+
constructor(url?: string);
|
|
225
|
+
get url(): string | undefined;
|
|
226
|
+
addHealthCheck(name: string, healthCheck: HealthCheck): void;
|
|
227
|
+
isHealthy(): Promise<boolean>;
|
|
228
|
+
getHealth(): Promise<Map<string, boolean>>;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
declare abstract class ProcedureRuntime extends Runtime implements Runner {
|
|
232
|
+
#private;
|
|
233
|
+
constructor(url?: string);
|
|
234
|
+
abstract getProcedureNames(): string[];
|
|
235
|
+
abstract hasProcedure(name: string): boolean;
|
|
236
|
+
abstract run(fqn: string, version: Version, args: Map<string, unknown>, headers: Map<string, string>): Promise<unknown>;
|
|
237
|
+
addMiddleware(middleware: Middleware): void;
|
|
238
|
+
getMiddleware(type: Function): Middleware | undefined;
|
|
239
|
+
handle(fqn: string, version: Version, args: Map<string, unknown>, headers: Map<string, string>): Promise<unknown>;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
declare abstract class Node extends ProcedureRuntime {
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
declare abstract class Gateway extends ProcedureRuntime {
|
|
246
|
+
abstract addNode(node: Node): Promise<void>;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
type Module = Record<string, unknown>;
|
|
250
|
+
|
|
251
|
+
declare abstract class Repository extends Runtime {
|
|
252
|
+
abstract registerClient(segmentFiles: string[]): Promise<string>;
|
|
253
|
+
abstract loadAsset(filename: string): Promise<File>;
|
|
254
|
+
abstract getModuleLocation(clientId: string): Promise<string>;
|
|
255
|
+
abstract loadModule(clientId: string, filename: string): Promise<File>;
|
|
256
|
+
abstract importModule(clientId: string, filename: string): Promise<Module>;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
declare class ArgumentExtractor {
|
|
260
|
+
#private;
|
|
261
|
+
extract(parameters: Parameter[], args: Map<string, unknown>): unknown[];
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
declare class LocalNode extends Node {
|
|
265
|
+
#private;
|
|
266
|
+
constructor(url?: string, argumentConstructor?: ArgumentExtractor);
|
|
267
|
+
getProcedureNames(): string[];
|
|
268
|
+
loadSegment(name: string): Promise<void>;
|
|
269
|
+
addSegment(segment: Segment): void;
|
|
270
|
+
hasProcedure(fqn: string): boolean;
|
|
271
|
+
setGateway(gateway: Gateway): Promise<void>;
|
|
272
|
+
setRepository(repository: Repository, segmentNames: string[]): Promise<void>;
|
|
273
|
+
import(url: string, base?: string): Promise<Module>;
|
|
274
|
+
run(fqn: string, version: Version, args: Map<string, unknown>, headers: Map<string, string>): Promise<unknown>;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
type Loadable = {
|
|
278
|
+
name: string;
|
|
279
|
+
source?: string;
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
interface ClassLoader {
|
|
283
|
+
loadClass(loadable: Loadable): Promise<Function>;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
declare abstract class ValueSerializer {
|
|
287
|
+
#private;
|
|
288
|
+
set parent(parent: Serializer);
|
|
289
|
+
abstract canSerialize(value: unknown): boolean;
|
|
290
|
+
abstract canDeserialize(value: unknown): boolean;
|
|
291
|
+
abstract serialize(value: unknown): Promise<unknown>;
|
|
292
|
+
abstract deserialize(value: unknown): Promise<unknown>;
|
|
293
|
+
serializeOther(value: unknown): Promise<unknown>;
|
|
294
|
+
deserializeOther(value: unknown): Promise<unknown>;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
declare class Serializer {
|
|
298
|
+
#private;
|
|
299
|
+
addSerializer(serializer: ValueSerializer): void;
|
|
300
|
+
serialize(value: unknown): Promise<unknown>;
|
|
301
|
+
deserialize(value: unknown): Promise<unknown>;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
type ModuleImporter = (name: string) => Promise<Module>;
|
|
305
|
+
|
|
306
|
+
declare function startClient(remoteUrl: string, segmentNames?: string[]): Promise<LocalNode>;
|
|
307
|
+
declare function getClient(): Promise<LocalNode>;
|
|
308
|
+
|
|
309
|
+
declare function getDependency(name: string): Promise<unknown>;
|
|
310
|
+
|
|
311
|
+
declare function runProcedure(fqn: string, versionNumber: string, args: object, context?: object): Promise<unknown>;
|
|
312
|
+
|
|
313
|
+
declare global {
|
|
314
|
+
const __getDependency: typeof getDependency;
|
|
315
|
+
const __runProcedure: typeof runProcedure;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
declare class CorsMiddleware implements Middleware {
|
|
319
|
+
#private;
|
|
320
|
+
constructor(origin?: string, headers?: string);
|
|
321
|
+
get allowOrigin(): string;
|
|
322
|
+
get allowMethods(): string;
|
|
323
|
+
get allowHeaders(): string;
|
|
324
|
+
handle(fqn: string, version: Version, args: Map<string, unknown>, headers: Map<string, string>, next: NextHandler): Promise<unknown>;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
declare class JitarServer {
|
|
328
|
+
#private;
|
|
329
|
+
constructor();
|
|
330
|
+
get classLoader(): ClassLoader;
|
|
331
|
+
build(): Promise<void>;
|
|
332
|
+
start(): Promise<void>;
|
|
333
|
+
registerHealthCheck(name: string, healthCheck: HealthCheck): void;
|
|
334
|
+
addSerializer(serializer: ValueSerializer): void;
|
|
335
|
+
addMiddleware(middleware: Middleware): void;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
declare function buildServer(moduleImporter: ModuleImporter): Promise<JitarServer>;
|
|
339
|
+
|
|
340
|
+
export { ArrayParameter, BadRequest, ClientNotFound, CorsMiddleware, FileNotFound, Forbidden, HealthCheck, Implementation, ImplementationNotFound, InvalidClientId, InvalidParameterValue, InvalidSegmentFile, InvalidVersionNumber, Middleware, MissingParameterValue, ModuleNotAccessible, ModuleNotLoaded, NamedParameter, NextHandler, NoNodeAvailable, NotFound, NotImplemented, ObjectParameter, PaymentRequired, Procedure, ProcedureNotAccessible, ProcedureNotFound, RepositoryNotAvailable, RuntimeNotAvailable, Segment, SegmentNotFound, ServerError, Teapot, Unauthorized, UnknownParameter, Version, buildServer, getClient, startClient };
|
package/dist/lib.js
CHANGED
|
@@ -1,30 +1,2 @@
|
|
|
1
|
-
export { default as Version } from './core/Version.js';
|
|
2
|
-
export { default as Forbidden } from './core/errors/Forbidden.js';
|
|
3
|
-
export { default as BadRequest } from './core/errors/BadRequest.js';
|
|
4
|
-
export { default as NotFound } from './core/errors/NotFound.js';
|
|
5
|
-
export { default as NotImplemented } from './core/errors/NotImplemented.js';
|
|
6
|
-
export { default as PaymentRequired } from './core/errors/PaymentRequired.js';
|
|
7
|
-
export { default as Teapot } from './core/errors/Teapot.js';
|
|
8
|
-
export { default as Unauthorized } from './core/errors/Unauthorized.js';
|
|
9
|
-
export { default as FileNotFound } from './runtime/errors/FileNotFound.js';
|
|
10
|
-
export { default as LocalRepository } from './runtime/LocalRepository.js';
|
|
11
|
-
export { default as LocalNode } from './runtime/LocalNode.js';
|
|
12
|
-
export { default as Proxy } from './runtime/Proxy.js';
|
|
13
|
-
export { default as ValueSerializer } from './runtime/serialization/ValueSerializer.js';
|
|
14
|
-
export { default as ClientId } from './runtime/ClientId.js';
|
|
15
|
-
export { default as RemoteNode } from './runtime/RemoteNode.js';
|
|
16
|
-
export { default as LocalGateway } from './runtime/LocalGateway.js';
|
|
17
|
-
export { default as ProcedureRuntime } from './runtime/ProcedureRuntime.js';
|
|
18
|
-
export { default as File } from './runtime/models/File.js';
|
|
19
|
-
export { default as CacheBuilder } from './runtime/caching/CacheBuilder.js';
|
|
20
|
-
export { default as Gateway } from './runtime/Gateway.js';
|
|
21
|
-
export { default as Node } from './runtime/Node.js';
|
|
22
|
-
export { default as NodeMonitor } from './runtime/NodeMonitor.js';
|
|
23
|
-
export { default as RemoteGateway } from './runtime/RemoteGateway.js';
|
|
24
|
-
export { default as Repository } from './runtime/Repository.js';
|
|
25
|
-
export { default as Runtime } from './runtime/Runtime.js';
|
|
26
|
-
export { default as RemoteRepository } from './runtime/RemoteRepository.js';
|
|
27
|
-
export { default as CorsMiddleware } from './runtime/middleware/CorsMiddleware.js';
|
|
28
|
-
export { default as ModuleLoader } from './runtime/utils/ModuleLoader.js';
|
|
29
1
|
export * from './client.js';
|
|
30
|
-
export * from './
|
|
2
|
+
export * from './server.js';
|
package/dist/server.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{R as Repository,M as ModuleLoader,I as InvalidSegmentFile,F as FileNotFound,a as InvalidClientId,C as ClientNotFound,i as isSegmentFilename,c as convertToLocalFilename,b as File,d as convertToRemoteFilename,e as createRepositoryFilename,P as ProcedureRuntime,N as Node,f as Remote,g as Reflector,A as AccessLevel,h as ReflectionField,j as ReflectionDestructuredArray,k as ReflectionDestructuredObject,l as ReflectionDestructuredValue,m as createNodeFilename,V as VersionParser,n as ReflectionFunction,o as Files,L as LocalGateway,p as LocalNode,q as RemoteRepository,r as RemoteGateway,B as BadRequest,U as Unauthorized,s as PaymentRequired,t as Forbidden,u as NotFound,T as Teapot,v as NotImplemented,w as Version,x as RemoteClassLoader,S as SerializerBuilder}from"./globals-9eff87d1.js";import express from"express";import{readFileSync}from"fs";import{z}from"zod";import fs from"fs-extra";import glob from"glob-promise";import mime from"mime-types";import path from"path";import yargs from"yargs";import{Logger}from"tslog";import{fileURLToPath}from"url";import expressProxy from"express-http-proxy";class CorsMiddleware{#allowOrigin;#allowMethods="GET, POST";#allowHeaders;constructor(origin="*",headers="*"){this.#allowOrigin=origin,this.#allowHeaders=headers}get allowOrigin(){return this.#allowOrigin}get allowMethods(){return this.#allowMethods}get allowHeaders(){return this.#allowHeaders}async handle(fqn,version,args,headers,next){const result=await next();return this.#setHeaders(headers),result}#setHeaders(headers){headers.set("Access-Control-Allow-Origin",this.#allowOrigin),headers.set("Access-Control-Allow-Methods",this.#allowMethods),headers.set("Access-Control-Allow-Headers",this.#allowHeaders)}}const CLIENT_ID_REGEX=/^CLIENT_\d+$/;let lastClientId=0;class ClientIdHelper{generate(){return"CLIENT_"+lastClientId++}validate(clientId){return CLIENT_ID_REGEX.test(clientId)}}const clientIdHelper$1=new ClientIdHelper;class LocalRepository extends Repository{#fileManager;#segments=new Map;#clients=new Map;#assets;constructor(fileManager,assets,url){super(url),this.#fileManager=fileManager,this.#assets=assets}async loadSegment(name){const filename=`./${createRepositoryFilename(name)}`,location=this.#fileManager.getAbsoluteLocation(filename),files=(await ModuleLoader.load(location)).files;if(void 0===files)throw new InvalidSegmentFile(location);this.registerSegment(name,files)}async registerSegment(name,files){files.forEach((file=>this.#segments.set(file,name)))}async registerClient(segmentFilenames){const clientId=clientIdHelper$1.generate();return this.#clients.set(clientId,segmentFilenames),clientId}loadAsset(filename){if(!1===this.#assets.includes(filename))throw new FileNotFound(filename);return this.#readFile(filename)}async getModuleLocation(clientId){return this.#fileManager.getRootLocation()}loadModule(clientId,filename){this.#validateClientId(clientId);const segmentFilename=this.#segments.get(filename);return void 0===segmentFilename||this.#hasClientSegmentFile(clientId,segmentFilename)?this.#getNodeModule(filename):this.#getRemoteModule(filename)}importModule(clientId,filename){filename=ModuleLoader.assureExtension(filename);const location=this.#fileManager.getAbsoluteLocation(filename);return ModuleLoader.import(location)}#validateClientId(clientId){if(!1===clientIdHelper$1.validate(clientId))throw new InvalidClientId(clientId);if(!1===this.#clients.has(clientId))throw new ClientNotFound(clientId)}#hasClientSegmentFile(clientId,segmentFilename){const clientSegmentFiles=this.#clients.get(clientId);if(void 0===clientSegmentFiles)throw new ClientNotFound(clientId);return clientSegmentFiles.some((clientSegmentFilename=>segmentFilename.endsWith(clientSegmentFilename)))}async#getNodeModule(filename){const localFilename=isSegmentFilename(filename)?filename:convertToLocalFilename(filename),code=(await this.#readFile(localFilename)).content.toString();return new File(filename,"application/javascript",code)}#getRemoteModule(filename){const remoteFilename=convertToRemoteFilename(filename);return this.#readFile(remoteFilename)}#readFile(filename){return this.#fileManager.read(filename)}}class NodeMonitor{#gateway;#frequency;#interval=null;constructor(gateway,frequency=5e3){this.#gateway=gateway,this.#frequency=frequency}start(){this.#interval=setInterval((async()=>this.#monitor()),this.#frequency)}stop(){null!==this.#interval&&clearInterval(this.#interval)}async#monitor(){const promises=this.#gateway.nodes.map((async node=>this.#monitorNode(node)));await Promise.all(promises)}async#monitorNode(node){!1===await this.#checkNodeAvailable(node)&&this.#gateway.removeNode(node)}async#checkNodeAvailable(node){try{return await node.isHealthy()}catch(error){return!1}}}class Proxy extends ProcedureRuntime{#repository;#runner;constructor(repository,runner,url){super(url),this.#repository=repository,this.#runner=runner}get repository(){return this.#repository}get runner(){return this.#runner}getProcedureNames(){return this.#runner.getProcedureNames()}hasProcedure(fqn){return this.getProcedureNames().includes(fqn)}loadAsset(filename){return this.#repository.loadAsset(filename)}registerClient(segmentFiles){return this.#repository.registerClient(segmentFiles)}loadModule(clientId,filename){return this.#repository.loadModule(clientId,filename)}run(name,version,args,headers){return this.#runner.run(name,version,args,headers)}}class RemoteNode extends Node{#remote;#procedureNames=new Set;constructor(url,procedureNames){super(url),this.#remote=new Remote(url),this.registerProcedures(procedureNames)}getProcedureNames(){return[...this.#procedureNames.values()]}registerProcedures(procedureNames){procedureNames.forEach((procedureName=>this.#procedureNames.add(procedureName)))}hasProcedure(name){return this.#procedureNames.has(name)}isHealthy(){return this.#remote.isHealthy()}getHealth(){return this.#remote.getHealth()}run(fqn,version,args,headers){return this.#remote.run(fqn,version,args,headers)}}const gatewaySchema=z.object({monitor:z.number().optional(),repository:z.string().url().optional()}).strict().transform((value=>new GatewayConfiguration(value.monitor,value.repository)));class GatewayConfiguration{#monitor;#repository;constructor(monitor,repository){this.#monitor=monitor,this.#repository=repository}get monitor(){return this.#monitor}get repository(){return this.#repository}}const nodeSchema=z.object({gateway:z.string().url().optional(),repository:z.string().url().optional(),segments:z.array(z.string()).nonempty()}).strict().transform((value=>new NodeConfiguration(value.gateway,value.repository,value.segments)));class NodeConfiguration{#gateway;#repository;#segments;constructor(gateway,repository,segments){this.#gateway=gateway,this.#repository=repository,this.#segments=segments}get gateway(){return this.#gateway}get repository(){return this.#repository}get segments(){return this.#segments}}const proxySchema=z.object({node:z.string().url().optional(),gateway:z.string().url().optional(),repository:z.string().url()}).strict().superRefine(((value,ctx)=>{void 0===value.node&&void 0===value.gateway&&ctx.addIssue({code:z.ZodIssueCode.custom,message:"Either node or gateway must be defined",path:["node","gateway"]}),void 0!==value.node&&void 0!==value.gateway&&ctx.addIssue({code:z.ZodIssueCode.custom,message:"Only node or gateway must be defined",path:["node","gateway"]})})).transform((value=>new ProxyConfiguration(value.node,value.gateway,value.repository)));class ProxyConfiguration{#node;#gateway;#repository;constructor(node,gateway,repository){this.#node=node,this.#gateway=gateway,this.#repository=repository}get node(){return this.#node}get gateway(){return this.#gateway}get repository(){return this.#repository}}const repositorySchema=z.object({source:z.string().optional(),cache:z.string().optional(),index:z.string().optional(),assets:z.array(z.string()).optional()}).strict().transform((value=>new RepositoryConfiguration(value.source,value.cache,value.index,value.assets)));class RepositoryConfiguration{#source;#cache;#index;#assets;constructor(source,cache,index,assets){this.#source=source,this.#cache=cache,this.#index=index,this.#assets=assets}get source(){return this.#source}get cache(){return this.#cache}get index(){return this.#index}get assets(){return this.#assets}}const standaloneSchema=z.object({source:z.string().optional(),cache:z.string().optional(),index:z.string().optional(),segments:z.array(z.string()).optional(),assets:z.array(z.string()).optional()}).strict().transform((value=>new StandaloneConfiguration(value.source,value.cache,value.index,value.segments,value.assets)));class StandaloneConfiguration{#source;#cache;#index;#segments;#assets;constructor(source,cache,index,segments,assets){this.#source=source,this.#cache=cache,this.#index=index,this.#segments=segments,this.#assets=assets}get source(){return this.#source}get cache(){return this.#cache}get index(){return this.#index}get segments(){return this.#segments}get assets(){return this.#assets}}const runtimeSchema=z.object({url:z.string().optional(),healthChecks:z.array(z.string()).optional(),standalone:standaloneSchema.optional(),repository:repositorySchema.optional(),gateway:gatewaySchema.optional(),node:nodeSchema.optional(),proxy:proxySchema.optional()}).strict().transform((value=>new RuntimeConfiguration(value.url,value.healthChecks,value.standalone,value.repository,value.gateway,value.node,value.proxy)));class RuntimeConfiguration{#url;#healthChecks;#standalone;#repository;#gateway;#node;#proxy;constructor(url,healthChecks,standalone,repository,gateway,node,proxy){this.#url=url,this.#healthChecks=healthChecks,this.#standalone=standalone,this.#repository=repository,this.#gateway=gateway,this.#node=node,this.#proxy=proxy}get url(){return this.#url}get healthChecks(){return this.#healthChecks}get standalone(){return this.#standalone}get repository(){return this.#repository}get gateway(){return this.#gateway}get node(){return this.#node}get proxy(){return this.#proxy}}class DataConverter{static convert(schema,dataObject){return schema.parse(dataObject)}}class RuntimeConfigurationLoader{static load(filename){const plainContents=readFileSync(filename,"utf-8"),parsedContents=JSON.parse(plainContents);return DataConverter.convert(runtimeSchema,parsedContents)}}class ApplicationCache{#segments;#modules;constructor(segments,modules){this.#segments=segments,this.#modules=modules}get segments(){return this.#segments}get modules(){return this.#modules}}class ModuleCache{#module;#segment;constructor(module,segment){this.#module=module,this.#segment=segment}get module(){return this.#module}get segment(){return this.#segment}}class ModuleCacheBuilder{build(application,module){const segment=application.getSegmentModule(module.filename);return new ModuleCache(module,segment)}}class DuplicateImplementation extends Error{constructor(fqn,version){super(`Duplicate implementation found for '${fqn}' with version '${version}'.`)}}class SegmentCache{#name;#imports;#procedures;#files;constructor(name,files,imports,procedures){this.#name=name,this.#files=files,this.#imports=imports,this.#procedures=procedures}get name(){return this.#name}get files(){return this.#files}get imports(){return this.#imports}get procedures(){return this.#procedures}}class SegmentImport{#members;#from;constructor(members,from){this.#members=members,this.#from=from}get members(){return this.#members}get from(){return this.#from}}class SegmentProcedure{#fqn;#implementations=[];constructor(fqn,implementations=[]){this.#fqn=fqn,this.#implementations=implementations}get fqn(){return this.#fqn}get implementations(){return this.#implementations}addImplementation(implementation){this.#implementations.push(implementation)}}class SegmentCacheBuilder{build(segment){const files=this.#extractFiles(segment),imports=this.#createImports(segment),procedures=this.#mergeProcedures(segment);return this.#validateProcedures(procedures),new SegmentCache(segment.name,files,imports,procedures)}#extractFiles(segment){return segment.modules.map((module=>module.filename))}#createImports(segment){const imports=[];for(const module of segment.modules){let members=[];for(const procedure of module.procedures){const ids=procedure.implementations.map((implementation=>this.#createImportMember(implementation)));members=[...members,...ids]}imports.push(new SegmentImport(members,module.filename))}return imports}#createImportMember(implementation){return`${implementation.importKey} as ${implementation.id}`}#mergeProcedures(segment){const procedures=new Map;for(const module of segment.modules)for(const procedure of module.procedures){if(procedures.has(procedure.fqn)){const existingProcedure=procedures.get(procedure.fqn);for(const implementation of procedure.implementations)existingProcedure.addImplementation(implementation);continue}const procedureCopy=new SegmentProcedure(procedure.fqn,[...procedure.implementations]);procedures.set(procedure.fqn,procedureCopy)}return[...procedures.values()]}#validateProcedures(procedures){for(const procedure of procedures)this.#checkForDuplicateImplementations(procedure)}#checkForDuplicateImplementations(procedure){for(const implementation of procedure.implementations){if(void 0!==procedure.implementations.find((other=>other.id!==implementation.id&&other.version===implementation.version)))throw new DuplicateImplementation(procedure.fqn,implementation.version)}}}class ApplicationCacheBuilder{#moduleCacheBuilder;#segmentCacheBuilder;constructor(){this.#moduleCacheBuilder=new ModuleCacheBuilder,this.#segmentCacheBuilder=new SegmentCacheBuilder}build(application){const segments=this.#buildSegmentCaches(application),modules=this.#buildModuleCaches(application);return new ApplicationCache(segments,modules)}#buildSegmentCaches(application){return application.segments.map((segment=>this.#segmentCacheBuilder.build(segment)))}#buildModuleCaches(application){return application.modules.map((module=>this.#moduleCacheBuilder.build(application,module)))}}const Keyword={DEFAULT:"default"};Object.freeze(Keyword);const IMPORT_PATTERN=/import\s(?:["'\s]*([\w*{}\n, ]+)from\s*)?["'\s]*([@\w/_-]+)["'\s].*/g,NON_SYSTEM_INDICATORS=[".","/","http:","https:"],reflector$2=new Reflector;const importRewriter=new class{rewrite(code,includeSystem){return code.replaceAll(IMPORT_PATTERN,(statement=>this.#replaceImport(statement,includeSystem)))}#replaceImport(statement,includeSystem){const dependency=reflector$2.parseImport(statement);return this.#isSystemDependency(dependency)?includeSystem?this.#rewriteSystemImport(dependency):statement:this.#rewriteApplicationImport(dependency)}#isSystemDependency(dependency){return!1===NON_SYSTEM_INDICATORS.some((indicator=>dependency.from.startsWith(indicator,1)))}#rewriteSystemImport(dependency){const from=this.#rewriteImportFrom(dependency);if(0===dependency.members.length)return`await __getDependency('${from}');`;return`const ${this.#rewriteImportMembers(dependency,":")} = await __getDependency('${from}');`}#rewriteApplicationImport(dependency){return`import ${this.#rewriteImportMembers(dependency,"as")} from '${this.#rewriteImportFrom(dependency)}';`}#rewriteImportMembers(dependency,aliasSpecifier){if(this.#mustUseAs(dependency))return dependency.members[0].as;return`{ ${dependency.members.map((member=>member.name!==member.as?`${member.name} ${aliasSpecifier} ${member.as}`:member.name)).join(", ")} }`}#rewriteImportFrom(dependency){const from=dependency.from.substring(1,dependency.from.length-1);return NON_SYSTEM_INDICATORS.some((indicator=>from.startsWith(indicator)))?from.endsWith(".js")?from:`${from}.js`:from}#mustUseAs(dependency){return this.#doesImportAll(dependency)||this.#doesImportDefault(dependency)}#doesImportAll(dependency){return 1===dependency.members.length&&"*"===dependency.members[0].name}#doesImportDefault(dependency){return 1===dependency.members.length&&dependency.members[0].name===Keyword.DEFAULT}},remoteBuilder=new class{build(module){let code="";for(const procedure of module.procedures)for(const implementation of procedure.implementations){const asDefault=implementation.importKey===Keyword.DEFAULT;code+=implementation.access===AccessLevel.PRIVATE?this.#createPrivateCode(procedure.fqn,implementation,asDefault):this.#createPublicCode(procedure.fqn,implementation,asDefault)}return code.trim()}#createPrivateCode(fqn,implementation,asDefault){const version=implementation.version,declaration=this.#createDeclaration(implementation,asDefault),body=`throw new ProcedureNotAccessible('${fqn}', '${version}');`;return this.#createFunction(declaration,body)}#createPublicCode(fqn,implementation,asDefault){const version=implementation.version,args=this.#createArguments(implementation.executable.parameters),declaration=this.#createDeclaration(implementation,asDefault),body=`return __runProcedure('${fqn}', '${version}', { ${args} }, this);`;return this.#createFunction(declaration,body)}#createParameters(parameters){const result=[];for(const parameter of parameters)parameter instanceof ReflectionField?result.push(parameter.name):(parameter instanceof ReflectionDestructuredArray||parameter instanceof ReflectionDestructuredObject)&&result.push(parameter.toString());return result.join(", ")}#createArguments(parameters){return this.#extractArguments(parameters).join(", ")}#extractArguments(parameters){const result=[];for(const parameter of parameters)if(parameter instanceof ReflectionDestructuredValue){const argumentz=this.#extractArguments(parameter.members);result.push(...argumentz)}else if(parameter instanceof ReflectionField){const argument=this.#createNamedArgument(parameter);result.push(argument)}return result}#createNamedArgument(parameter){const key=parameter.name,value=key.startsWith("...")?key.substring(3):key;return`'${key}': ${value}`}#createDeclaration(implementation,asDefault){const name=implementation.executable.name,parameters=this.#createParameters(implementation.executable.parameters);return`\nexport ${asDefault?`${Keyword.DEFAULT} `:""}async function ${name}(${parameters})`}#createFunction(declaration,body){return`${declaration} {\n\t${body}\n}\n`}};class ModuleCacheWriter{#fileManager;constructor(fileManager){this.#fileManager=fileManager}async write(cache){return Promise.all([this.#writeOriginal(cache),this.#writeLocal(cache),this.#writeRemote(cache)]).then((()=>{}))}async#writeOriginal(cache){const importCode=this.#rewriteApplicationImports(cache.module),sourceCode=this.#createSourceCode(cache.module),filename=cache.module.filename,code=`${importCode}\n${sourceCode}`;return this.#fileManager.write(filename,code.trim())}async#writeLocal(cache){const importCode=this.#rewriteAllImports(cache.module),sourceCode=this.#createSourceCode(cache.module),filename=convertToLocalFilename(cache.module.filename),code=`${importCode}\n${sourceCode}`;return this.#fileManager.write(filename,code.trim())}#rewriteApplicationImports(module){return importRewriter.rewrite(module.code,!1)}#rewriteAllImports(module){return importRewriter.rewrite(module.code,!0)}#createSourceCode(module){const filename=module.filename;return module.content.exportedClasses.map((clazz=>clazz.name)).map((className=>`${className}.source = "${filename}";`)).join("\n")}async#writeRemote(cache){if(void 0===cache.segment)return;const filename=convertToRemoteFilename(cache.module.filename),code=this.#createRemoteCode(cache.segment);return this.#fileManager.write(filename,code.trim())}#createRemoteCode(module){return remoteBuilder.build(module)}}class SegmentCacheWriter{#fileManager;constructor(fileManager){this.#fileManager=fileManager}async write(cache){return Promise.all([this.#writeNodeCache(cache),this.#writeRepositoryCache(cache)]).then((()=>{}))}async#writeNodeCache(cache){const importCode=this.#createImportCode(cache.imports),segmentCode=this.#createSegmentCode(cache.name,cache.procedures),filename=createNodeFilename(cache.name),code=`${importCode}\n${segmentCode}`;return this.#fileManager.write(filename,code)}async#writeRepositoryCache(cache){const filename=createRepositoryFilename(cache.name),code=`export const files = [\n\t"${[...cache.files].join('",\n\t"')}"\n];`;return this.#fileManager.write(filename,code)}#createImportCode(imports){const codes=[];for(const{members:members,from:from}of imports)codes.push(`import { ${members.join(", ")} } from "./${from}";`);return codes.join("\n")}#createSegmentCode(name,procedures){const codes=[];codes.push('const { Segment, Procedure, Implementation, Version, NamedParameter, ArrayParameter, ObjectParameter } = await __getDependency("jitar");'),codes.push(`export const segment = new Segment("${name}")`);for(const procedure of procedures){codes.push(`\t.addProcedure(new Procedure("${procedure.fqn}")`);for(const implementation of procedure.implementations){const version=this.#createVersionCode(implementation.version),parameters=this.#createParametersCode(implementation.executable);codes.push(`\t\t.addImplementation(new Implementation(${version}, "${implementation.access}", ${parameters}, ${implementation.id}))`)}codes.push("\t)")}return codes.join("\n")}#createVersionCode(versionString){const version=VersionParser.parse(versionString);return`new Version(${version.major}, ${version.minor}, ${version.patch})`}#createParametersCode(executable){return`[${this.#extractParameters(executable.parameters).join(", ")}]`}#extractParameters(parameters){const result=[];for(const parameter of parameters)result.push(this.#extractParameter(parameter));return result}#extractParameter(parameter){return parameter instanceof ReflectionDestructuredArray?this.#createArrayParameter(parameter):parameter instanceof ReflectionDestructuredObject?this.#createObjectParameter(parameter):this.#createNamedParameter(parameter)}#createNamedParameter(parameter){return`new NamedParameter("${parameter.name}", ${void 0!==parameter.value})`}#createArrayParameter(parameter){return`new ArrayParameter([${this.#extractParameters(parameter.members).join(", ")}])`}#createObjectParameter(parameter){return`new ObjectParameter([${this.#extractParameters(parameter.members).join(", ")}])`}}class ApplicationCacheWriter{#moduleWriter;#segmentWriter;constructor(fileManager){this.#moduleWriter=new ModuleCacheWriter(fileManager),this.#segmentWriter=new SegmentCacheWriter(fileManager)}async write(cache){return Promise.all([this.#writeSegmentCache(cache.segments),this.#writeModuleCache(cache.modules)]).then((()=>{}))}async#writeSegmentCache(segments){return Promise.all(segments.map((async segment=>this.#segmentWriter.write(segment)))).then((()=>{}))}async#writeModuleCache(modules){return Promise.all(modules.map((async module=>this.#moduleWriter.write(module)))).then((()=>{}))}}class Application{#segments;#modules;constructor(segments,modules){this.#segments=segments,this.#modules=modules}get segments(){return this.#segments}get modules(){return this.#modules}getSegmentModule(filename){const segment=this.#segments.find((segment=>segment.hasModule(filename)));if(void 0!==segment)return segment.getModule(filename)}}class ModuleFileNotLoaded extends Error{constructor(filename,message){super(`Failed to load module file '${filename}' because of: ${message}`)}}class Module{#filename;#code;#content;constructor(filename,code,content){this.#code=code,this.#filename=filename,this.#content=content}get filename(){return this.#filename}get code(){return this.#code}get content(){return this.#content}}const reflector$1=new Reflector;class ModuleReader{#fileManager;constructor(fileManager){this.#fileManager=fileManager}async read(filename){const relativeLocation=this.#fileManager.getRelativeLocation(filename),code=await this.#loadCode(filename),module=reflector$1.parse(code);return new Module(relativeLocation,code,module)}async#loadCode(filename){try{return(await this.#fileManager.getContent(filename)).toString()}catch(error){const message=error instanceof Error?error.message:String(error);throw new ModuleFileNotLoaded(filename,message)}}}class FunctionNotAsync extends Error{constructor(filename,functionName){super(`Function '${functionName}' from file '${filename}' is not async`)}}class InvalidSegmentFilename extends Error{constructor(filename){super(`Segment filename '${filename}' is invalid`)}}class MissingModuleExport extends Error{constructor(filename,key){super(`Module '${filename}' does not export '${key}'`)}}class SegmentFileNotLoaded extends Error{constructor(filename,message){super(`Failed to load segment file '${filename}' because of: ${message}`)}}class SegmentModuleNotLoaded extends Error{constructor(filename,message){super(`Segment module could not be loaded from '${filename}' because of: ${message}`)}}class Segment{#name;#modules;constructor(name,modules){this.#name=name,this.#modules=modules}get name(){return this.#name}get modules(){return this.#modules}hasModule(filename){return this.#modules.some((module=>module.filename===filename))}getModule(filename){return this.#modules.find((module=>module.filename===filename))}}class SegmentImplementation{#id;#importKey;#access;#version;#executable;constructor(id,importKey,access,version,executable){this.#id=id,this.#importKey=importKey,this.#access=access,this.#version=version,this.#executable=executable}get id(){return this.#id}get importKey(){return this.#importKey}get access(){return this.#access}get version(){return this.#version}get executable(){return this.#executable}}class SegmentModule{#filename;#procedures=[];constructor(filename,procedures){this.#filename=filename,this.#procedures=procedures}get filename(){return this.#filename}get procedures(){return this.#procedures}}class IdGenerator{#id=0;next(){return"$"+ ++this.#id}}const reflector=new Reflector;class SegmentReader{#fileManager;constructor(fileManager){this.#fileManager=fileManager}async read(filename){const name=this.#extractSegmentName(filename),definition=await this.#loadSegmentDefinition(filename),modules=await this.#createSegmentModules(definition);return new Segment(name,modules)}#extractSegmentName(filename){const file=filename.split("/").pop();if(void 0===file||""===file)throw new InvalidSegmentFilename(filename);return file.replace(".segment.json","")}async#loadSegmentDefinition(filename){try{const content=await this.#fileManager.getContent(filename);return JSON.parse(content.toString())}catch(error){const message=error instanceof Error?error.message:String(error);throw new SegmentFileNotLoaded(filename,message)}}async#createSegmentModules(definition){const modules=[],idGenerator=new IdGenerator;for(const[filename,moduleImports]of Object.entries(definition)){const fullFilename=filename.endsWith(".js")?filename:`${filename}.js`,absoluteFilename=this.#fileManager.getAbsoluteLocation(fullFilename),module=await this.#createSegmentModule(absoluteFilename,moduleImports,idGenerator);modules.push(module)}return modules}async#createSegmentModule(absoluteFilename,imports,idGenerator){const module=await this.#loadSegmentModule(absoluteFilename),relativeFilename=this.#fileManager.getRelativeLocation(absoluteFilename),moduleName=this.#extractModuleName(relativeFilename),procedures=this.#extractSegmentProcedures(module,moduleName,imports,idGenerator);return new SegmentModule(relativeFilename,procedures)}async#loadSegmentModule(absoluteLocation){try{const code=await this.#fileManager.getContent(absoluteLocation);return reflector.parse(code.toString())}catch(error){const message=error instanceof Error?error.message:String(error);throw new SegmentModuleNotLoaded(absoluteLocation,message)}}#extractModuleName(relativeFilename){const moduleParts=relativeFilename.split("/");return moduleParts.pop(),moduleParts.join("/")}#extractSegmentProcedures(module,moduleName,imports,idGenerator){const procedures=new Map;for(const[importKey,properties]of Object.entries(imports)){const executable=module.getExported(importKey);if(void 0===executable)throw new MissingModuleExport(moduleName,importKey);if(executable instanceof ReflectionFunction==!1)continue;if(!1===executable.isAsync)throw new FunctionNotAsync(moduleName,executable.name);const procedureName=properties.as??executable.name,access=properties.access??"private",version=properties.version??"0.0.0",id=idGenerator.next(),fqn=""!==moduleName?`${moduleName}/${procedureName}`:procedureName,implementation=new SegmentImplementation(id,importKey,access,version,executable),procedure=procedures.has(fqn)?procedures.get(fqn):new SegmentProcedure(fqn);procedure.addImplementation(implementation),procedures.set(fqn,procedure)}return[...procedures.values()]}}class ApplicationReader{#moduleReader;#segmentReader;constructor(fileManager){this.#moduleReader=new ModuleReader(fileManager),this.#segmentReader=new SegmentReader(fileManager)}async read(segmentFiles,moduleFiles){return Promise.all([this.#readSegments(segmentFiles),this.#readModules(moduleFiles)]).then((([segments,modules])=>new Application(segments,modules)))}async#readSegments(segmentFiles){return Promise.all(segmentFiles.map((async segmentFile=>this.#segmentReader.read(segmentFile))))}async#readModules(moduleFiles){return Promise.all(moduleFiles.map((async moduleFile=>this.#moduleReader.read(moduleFile))))}}class CacheManager{#projectFileManager;#appFileManager;#reader;#builder;#writer;constructor(projectFileManager,appFileManager){this.#projectFileManager=projectFileManager,this.#appFileManager=appFileManager,this.#reader=new ApplicationReader(appFileManager),this.#builder=new ApplicationCacheBuilder,this.#writer=new ApplicationCacheWriter(appFileManager)}async build(){const segmentFiles=await this.#projectFileManager.filter(Files.SEGMENT_PATTERN),moduleFiles=await this.#appFileManager.filter(Files.MODULE_PATTERN),application=await this.#reader.read(segmentFiles,moduleFiles),cache=this.#builder.build(application);return this.#writer.write(cache)}}class LocalFileManager{#location;constructor(location){this.#location=location}getRootLocation(){return path.resolve(this.#location)}getAbsoluteLocation(filename){const location=filename.startsWith("/")?filename:path.join(this.#location,filename);return path.resolve(location)}getRelativeLocation(filename){return path.relative(this.#location,filename)}async getType(filename){const location=this.getAbsoluteLocation(filename);return mime.lookup(location)||"application/octet-stream"}async getContent(filename){const location=this.getAbsoluteLocation(filename);if(!1===fs.existsSync(location))throw new FileNotFound(filename);return fs.readFile(location)}async read(filename){const type=await this.getType(filename),content=await this.getContent(filename);return new File(filename,type,content)}async write(filename,content){const location=this.getAbsoluteLocation(filename),directory=path.dirname(location);return await fs.mkdir(directory,{recursive:!0}),fs.writeFile(location,content)}async copy(source,destination){const sourceLocation=this.getAbsoluteLocation(source),destinationLocation=this.getAbsoluteLocation(destination);return fs.copy(sourceLocation,destinationLocation,{overwrite:!0})}async delete(filename){const location=this.getAbsoluteLocation(filename);return fs.remove(location)}async filter(pattern){const location=this.getAbsoluteLocation("./");return glob(`${location}/${pattern}`)}async getNodeSegmentFiles(){return this.filter("**/*.segment.node.js")}async getRepositorySegmentFiles(){return this.filter("**/*.segment.repository.js")}async getAssetFiles(patterns){const promises=patterns.map((pattern=>this.filter(pattern)));return(await Promise.all(promises)).flat().map((filename=>this.getRelativeLocation(filename))).filter((filename=>!1===this.#isGeneratedFile(filename)))}#isGeneratedFile(filename){return filename.endsWith(".local.js")||filename.endsWith(".node.js")||filename.endsWith(".repository.js")||filename.endsWith(".remote.js")}}var RuntimeDefaults;!function(RuntimeDefaults){RuntimeDefaults.URL="http://localhost:3000",RuntimeDefaults.SOURCE="./dist",RuntimeDefaults.CACHE="./.jitar",RuntimeDefaults.INDEX="index.html"}(RuntimeDefaults||(RuntimeDefaults={}));var LogLevel,RuntimeDefaults$1=RuntimeDefaults;class UnknownRuntimeMode extends Error{constructor(){super("Unknown runtime mode")}}class RuntimeConfigurator{static async configure(configuration){const url=configuration.url??RuntimeDefaults$1.URL;if(void 0!==configuration.standalone)return this.#configureStandAlone(url,configuration.standalone);if(void 0!==configuration.repository)return this.#configureRepository(url,configuration.repository);if(void 0!==configuration.gateway)return this.#configureGateway(url,configuration.gateway);if(void 0!==configuration.node)return this.#configureNode(url,configuration.node);if(void 0!==configuration.proxy)return this.#configureProxy(url,configuration.proxy);throw new UnknownRuntimeMode}static async#configureStandAlone(url,configuration){const sourceLocation=configuration.source??RuntimeDefaults$1.SOURCE,cacheLocation=configuration.cache??RuntimeDefaults$1.CACHE,assetFilePatterns=configuration.assets;await this.#buildCache(sourceLocation,cacheLocation);const segmentNames=void 0===configuration.segments?await this.#getSegmentNames(cacheLocation):configuration.segments,repository=await this.#buildRepository(url,cacheLocation,assetFilePatterns),node=await this.#buildNode(url,segmentNames,repository);return this.#buildProxy(url,repository,node)}static async#configureRepository(url,configuration){const sourceLocation=configuration.source??RuntimeDefaults$1.SOURCE,cacheLocation=configuration.cache??RuntimeDefaults$1.CACHE,assetFilePatterns=configuration.assets??[];return await this.#buildCache(sourceLocation,cacheLocation),this.#buildRepository(url,cacheLocation,assetFilePatterns)}static async#configureGateway(url,configuration){const repository=this.#getRemoteRepository(configuration.repository);return this.#buildGateway(url,configuration.monitor,repository)}static async#configureNode(url,configuration){const segmentNames=configuration.segments??[],repository=this.#getRemoteRepository(configuration.repository),gateway=this.#getRemoteGateway(configuration.gateway);return this.#buildNode(url,segmentNames,repository,gateway)}static async#configureProxy(url,configuration){const repository=this.#getRemoteRepository(configuration.repository),gateway=this.#getRemoteGateway(configuration.gateway),node=void 0!==configuration.node?new RemoteNode(configuration.node,[]):void 0,runner=gateway??node;return this.#buildProxy(url,repository,runner)}static async#buildCache(sourceLocation,cacheLocation){const projectFileManager=new LocalFileManager("./");await projectFileManager.delete(cacheLocation),await projectFileManager.copy(sourceLocation,cacheLocation);const appFileManager=new LocalFileManager(cacheLocation),cacheManager=new CacheManager(projectFileManager,appFileManager);await cacheManager.build()}static async#getSegmentNames(cacheLocation){const fileManager=new LocalFileManager(cacheLocation);return(await fileManager.getNodeSegmentFiles()).map((filename=>this.#extractSegmentName(filename)))}static#extractSegmentName(filename){const name=filename.split("/").pop()??"",endIndex=name.indexOf(".segment");return name.substring(0,endIndex)}static async#buildRepository(url,cacheLocation,assetFilePatterns){const fileManager=new LocalFileManager(cacheLocation),assetFiles=void 0!==assetFilePatterns?await fileManager.getAssetFiles(assetFilePatterns):[],repository=new LocalRepository(fileManager,assetFiles,url),segmentNames=(await fileManager.getRepositorySegmentFiles()).map((filename=>this.#extractSegmentName(filename)));for(const name of segmentNames)await repository.loadSegment(name);return repository}static async#buildGateway(url,monitorInterval,repository){const gateway=new LocalGateway(url);void 0!==repository&&await gateway.setBaseUrl(repository);return new NodeMonitor(gateway,monitorInterval).start(),gateway}static async#buildNode(url,segmentNames,repository,gateway){const node=new LocalNode(url);void 0!==repository&&await node.setRepository(repository,segmentNames);for(const segmentName of segmentNames)await node.loadSegment(segmentName);return void 0!==gateway&&node.setGateway(gateway),node}static async#buildProxy(url,repository,runner){return new Proxy(repository,runner,url)}static#getRemoteRepository(url){return void 0!==url?new RemoteRepository(url):void 0}static#getRemoteGateway(url){return void 0!==url?new RemoteGateway(url):void 0}}!function(LogLevel){LogLevel.DEBUG="debug",LogLevel.INFO="info",LogLevel.WARN="warn",LogLevel.ERROR="error",LogLevel.FATAL="fatal"}(LogLevel||(LogLevel={}));class LogBuilder{static build(level){const logConfiguration=this.#getLogConfiguration(level);return new Logger(logConfiguration)}static#getLogConfiguration(level){return{prettyLogTemplate:"{{dateIsoStr}}\t{{logLevelName}}\t",minLevel:this.#getLogLevel(level)}}static#getLogLevel(level){switch(level){case LogLevel.FATAL:return 6;case LogLevel.ERROR:return 5;case LogLevel.WARN:return 4;case LogLevel.INFO:return 3;default:return 2}}}const serverOptionsSchema=z.object({loglevel:z.nativeEnum(LogLevel).optional(),config:z.string().endsWith(".json")}).transform((value=>new ServerOptions(value.config,value.loglevel)));class ServerOptions{#config;#loglevel;constructor(config,loglevel="info"){this.#config=config,this.#loglevel=loglevel}get config(){return this.#config}get loglevel(){return this.#loglevel}}class ServerOptionsReader{static read(){const args=yargs(process.argv).argv;return DataConverter.convert(serverOptionsSchema,args)}}class AssetsController{#repository;#indexFile;#logger;constructor(app,repository,indexFile,logger){this.#repository=repository,this.#indexFile=indexFile,this.#logger=logger,app.get("*",((request,response)=>{this.#getContent(request,response)}))}async#getContent(request,response){this.#logger.info(`Got asset -> '${request.path}'`);const path=request.path.substring(1).trim(),filename=0===path.length?this.#indexFile:path;try{const file=await this.#repository.loadAsset(filename);response.set("Content-Type",file.type),response.set("Content-Length",String(file.size)),response.status(200).send(file.content)}catch(error){if(error instanceof FileNotFound)return this.#logger.warn(`Failed to get asset -> '${filename}' | ${error.message}`),void response.status(404).send(error.message);const message=error instanceof Error?error.message:String(error);this.#logger.error(`Failed to get file content -> '${filename}' | ${message}`),response.status(500).send(message)}}}class HealthController{#node;#logger;constructor(app,node,logger){this.#node=node,this.#logger=logger,app.get("/health",((request,response)=>{this.getHealth(request,response)})),app.get("/health/status",((request,response)=>{this.isHealthy(request,response)}))}async getHealth(request,response){const health=await this.#node.getHealth(),data=Object.fromEntries(health);return this.#logger.debug("Got health"),response.status(200).send(data)}async isHealthy(request,response){const healthy=await this.#node.isHealthy();return this.#logger.debug("Got health status"),response.setHeader("Content-Type","text/plain"),response.status(200).send(healthy)}}const filePath=fileURLToPath(import.meta.url),fileLocation=path.dirname(filePath);class JitarController{constructor(app){app.use("/jitar",express.static(fileLocation))}}const clientIdHelper=new ClientIdHelper;class ModulesController{#repository;#serializer;#logger;constructor(app,repository,serializer,logger){this.#repository=repository,this.#serializer=serializer,this.#logger=logger,app.post("/modules",((request,response)=>{this.registerClient(request,response)})),app.get("/modules/:clientId/*",((request,response)=>{this.getModule(request,response)}))}async registerClient(request,response){this.#logger.info("Register client"),request.body;const segmentFiles=request.body,clientId=await this.#repository.registerClient(segmentFiles);return this.#logger.info(`Registered client -> ${clientId} [${segmentFiles.join(",")}]`),response.status(200).send(clientId)}async getModule(request,response){this.#logger.info(`Get module for -> '${request.params.clientId}'`);const clientId=request.params.clientId;if("string"!=typeof clientId||!1===clientIdHelper.validate(clientId))return response.status(400).send("Invalid client id.");const pathKey=`/${clientId}/`,pathIndex=request.path.indexOf(pathKey)+pathKey.length,filename=request.path.substring(pathIndex);try{const file=await this.#repository.loadModule(clientId,filename);return this.#logger.info(`Got module -> '${filename}' (${clientId})`),response.set("Content-Type",file.type),response.status(200).send(file.content)}catch(error){const message=error instanceof Error?error.message:String(error);this.#logger.error(`Failed to get module -> '${filename}' (${clientId}) | ${message}`);const data=this.#serializer.serialize(error);return response.setHeader("Content-Type","application/json"),response.status(500).send(data)}}}const nodeDtoSchema=z.object({url:z.string().url(),procedureNames:z.array(z.string()).optional()}).strict().transform((value=>new NodeDto(value.url,value.procedureNames)));class NodeDto{url;procedureNames;constructor(url,procedureNames=[]){this.url=url,this.procedureNames=procedureNames}}class NodesController{#gateway;#logger;constructor(app,gateway,logger){this.#gateway=gateway,this.#logger=logger,app.get("/nodes",((request,response)=>{this.getNodes(request,response)})),app.post("/nodes",((request,response)=>{this.add(request,response)}))}async getNodes(request,response){const nodes=this.#gateway.nodes.map((node=>({url:node.url,procedureNames:node.getProcedureNames()})));return this.#logger.info("Got nodes"),response.status(200).send(nodes)}async add(request,response){try{const nodeDto=DataConverter.convert(nodeDtoSchema,request.body),node=new RemoteNode(nodeDto.url,nodeDto.procedureNames);return this.#gateway.addNode(node),this.#logger.info(`Added node -> ${node.url}`),response.status(201).send()}catch(error){const status=error instanceof Array?400:500,message=error instanceof Error?error.message:String(error);return this.#logger.error(`Failed to add node | ${message}`),response.status(status).send(error)}}}class ProceduresController{#runtime;#logger;constructor(app,runtime,logger){this.#runtime=runtime,this.#logger=logger,app.get("/procedures",((request,response)=>{this.getProcedureNames(request,response)}))}async getProcedureNames(request,response){const names=this.#runtime.getProcedureNames();return this.#logger.info("Got procedure names"),response.status(200).send(names)}}class ProxyController{#logger;#repositoryUrl;#runnerUrl;constructor(app,proxy,logger){this.#logger=logger,this.#repositoryUrl=proxy.repository.url??"",this.#runnerUrl=proxy.runner.url??"",app.use("/",expressProxy((message=>this.#selectProxy(message))))}#selectProxy(message){const url=message.url??"";return this.#logger.info(`Forwarding -> ${url}`),url.startsWith("/rpc")?this.#runnerUrl:this.#repositoryUrl}}const RPC_PARAMETERS=["version","serialize"],IGNORED_HEADER_KEYS=["host","connection","content-length","accept-encoding","user-agent"],BAD_REQUEST_NAME=BadRequest.name,UNAUTHORIZED_NAME=Unauthorized.name,PAYMENT_REQUIRED_NAME=PaymentRequired.name,FORBIDDEN_NAME=Forbidden.name,NOT_FOUND_NAME=NotFound.name,TEAPOT_NAME=Teapot.name,NOT_IMPLEMENTED_NAME=NotImplemented.name;class RPCController{#runtime;#serializer;#logger;constructor(app,runtime,serializer,logger){this.#runtime=runtime,this.#serializer=serializer,this.#logger=logger,app.get("/rpc/*",((request,response)=>{this.runGet(request,response)})),app.post("/rpc/*",((request,response)=>{this.runPost(request,response)})),app.options("/rpc/*",((request,response)=>{this.runOptions(request,response)})),this.#showProcedureInfo()}#showProcedureInfo(){const procedureNames=this.#runtime.getProcedureNames();0!==procedureNames.length&&(procedureNames.sort(),this.#logger.info("Registered RPC entries",procedureNames))}async runGet(request,response){const fqn=this.#extractFqn(request),version=this.#extractVersion(request),args=this.#extractQueryArguments(request),headers=this.#extractHeaders(request),serialize=this.#extractSerialize(request);return this.#run(fqn,version,args,headers,response,serialize)}async runPost(request,response){const fqn=this.#extractFqn(request),version=this.#extractVersion(request),args=this.#extractBodyArguments(request),headers=this.#extractHeaders(request),serialize=this.#extractSerialize(request);return this.#run(fqn,version,args,headers,response,serialize)}async runOptions(request,response){return this.#setCors(response)}#extractFqn(request){return request.path.substring(5)}#extractVersion(request){return void 0!==request.query.version?VersionParser.parse(request.query.version.toString()):Version.DEFAULT}#extractSerialize(request){return"true"===request.query.serialize}#extractQueryArguments(request){const args={};for(const[key,value]of Object.entries(request.query))RPC_PARAMETERS.includes(key)||(args[key]=value);return args}#extractBodyArguments(request){return request.body}#extractHeaders(request){const headers=new Map;for(const[key,value]of Object.entries(request.headers)){if(void 0===value)continue;const lowerKey=key.toLowerCase(),stringValue=value.toString();IGNORED_HEADER_KEYS.includes(lowerKey)||headers.set(lowerKey,stringValue)}return headers}async#run(fqn,version,args,headers,response,serialize){if(!1===this.#runtime.hasProcedure(fqn))return response.status(404).send(`Procedure not found -> ${fqn}`);try{const deserializedArgs=await this.#serializer.deserialize(args),argsMap=new Map(Object.entries(deserializedArgs)),result=await this.#runtime.handle(fqn,version,argsMap,headers);return this.#logger.info(`Ran procedure -> ${fqn} (v${version.toString()})`),this.#setResponseHeaders(response,headers),this.#createResultResponse(result,response,serialize)}catch(error){const message=error instanceof Error?error.message:String(error),errorData=serialize?error:message;return this.#logger.error(`Failed to run procedure -> ${fqn} (v${version.toString()}) | ${message}`),this.#createErrorResponse(error,errorData,response,serialize)}}async#setCors(response){const cors=this.#runtime.getMiddleware(CorsMiddleware);return void 0===cors||(response.setHeader("Access-Control-Allow-Origin",cors.allowOrigin),response.setHeader("Access-Control-Allow-Methods",cors.allowMethods),response.setHeader("Access-Control-Allow-Headers",cors.allowHeaders),response.setHeader("Access-Control-Max-Age",86400)),response.status(204).send()}async#createResultResponse(result,response,serialize){const content=await this.#createResponseContent(result,serialize),contentType=this.#createResponseContentType(content),responseContent="text/plain"===contentType?String(content):content;return response.setHeader("Content-Type",contentType),response.status(200).send(responseContent)}async#createErrorResponse(error,errorData,response,serialize){const content=await this.#createResponseContent(errorData,serialize),contentType=this.#createResponseContentType(content),statusCode=this.#createResponseStatusCode(error);return response.setHeader("Content-Type",contentType),response.status(statusCode).send(content)}async#createResponseContent(data,serialize){return serialize?this.#serializer.serialize(data):data}#createResponseContentType(content){return"object"==typeof content?"application/json":"text/plain"}#setResponseHeaders(response,headers){headers.forEach(((value,key)=>response.setHeader(key,value)))}#createResponseStatusCode(error){if(error instanceof Object==!1)return 500;const errorClass=error.constructor;return this.#isClassType(errorClass,BAD_REQUEST_NAME)?400:this.#isClassType(errorClass,UNAUTHORIZED_NAME)?401:this.#isClassType(errorClass,PAYMENT_REQUIRED_NAME)?402:this.#isClassType(errorClass,FORBIDDEN_NAME)?403:this.#isClassType(errorClass,NOT_FOUND_NAME)?404:this.#isClassType(errorClass,TEAPOT_NAME)?418:this.#isClassType(errorClass,NOT_IMPLEMENTED_NAME)?501:500}#isClassType(clazz,className){if(clazz.name===className)return!0;const parentClass=Object.getPrototypeOf(clazz);return""!==parentClass.name&&this.#isClassType(parentClass,className)}}class UnknownHealthCheck extends Error{constructor(name){super(`Health check '${name}' is not registered.`)}}class DuplicateHealthCheck extends Error{constructor(name){super(`Health check '${name}' is already registered.`)}}class RuntimeNotAvailable extends Error{constructor(){super("Runtime is not available")}}class MiddlewareNotSupported extends Error{constructor(){super("Middleware is not supported")}}class JitarServer{#app;#runtime;#serializer;#classLoader;#options;#configuration;#logger;#registeredHealthChecks=new Map;constructor(){this.#classLoader=new RemoteClassLoader,this.#serializer=SerializerBuilder.build(this.#classLoader),this.#app=express(),this.#app.use(express.json()),this.#app.use(express.urlencoded({extended:!0})),this.#app.disable("x-powered-by"),this.#options=ServerOptionsReader.read(),this.#configuration=RuntimeConfigurationLoader.load(this.#options.config),this.#logger=LogBuilder.build(this.#options.loglevel),this.#printStartupMessage()}get classLoader(){return this.#classLoader}async build(){this.#runtime=await RuntimeConfigurator.configure(this.#configuration),this.#addControllers()}async start(){const url=new URL(this.#configuration.url??RuntimeDefaults$1.URL);this.#addHealthChecks(),await this.#startServer(url.port),this.#logger.info(`Server started and listening at port ${url.port}`)}registerHealthCheck(name,healthCheck){if(this.#registeredHealthChecks.has(name))throw new DuplicateHealthCheck(name);this.#registeredHealthChecks.set(name,healthCheck)}addSerializer(serializer){this.#serializer.addSerializer(serializer)}addMiddleware(middleware){if(void 0===this.#runtime)throw new RuntimeNotAvailable;if(!(this.#runtime instanceof ProcedureRuntime))throw new MiddlewareNotSupported;this.#runtime.addMiddleware(middleware)}#addHealthChecks(){if(void 0===this.#runtime)throw new RuntimeNotAvailable;if(void 0!==this.#configuration.healthChecks)for(const name of this.#configuration.healthChecks){const healthCheck=this.#registeredHealthChecks.get(name);if(void 0===healthCheck)throw new UnknownHealthCheck(name);this.#runtime.addHealthCheck(name,healthCheck)}}#addControllers(){if(void 0!==this.#configuration.standalone&&this.#runtime instanceof Proxy){const index=this.#configuration.standalone.index??RuntimeDefaults$1.INDEX;this.#addStandAloneControllers(this.#runtime,index)}else if(void 0!==this.#configuration.repository&&this.#runtime instanceof LocalRepository){const index=this.#configuration.repository.index??RuntimeDefaults$1.INDEX;this.#addRepositoryControllers(this.#runtime,index)}else void 0!==this.#configuration.gateway&&this.#runtime instanceof LocalGateway?this.#addGatewayControllers(this.#runtime):void 0!==this.#configuration.node&&this.#runtime instanceof LocalNode?this.#addNodeControllers(this.#runtime):void 0!==this.#configuration.proxy&&this.#runtime instanceof Proxy&&this.#addProxyControllers(this.#runtime)}#addStandAloneControllers(proxy,index){new HealthController(this.#app,proxy,this.#logger),new JitarController(this.#app),new ModulesController(this.#app,proxy,this.#serializer,this.#logger),new ProceduresController(this.#app,proxy,this.#logger),new RPCController(this.#app,proxy,this.#serializer,this.#logger),new AssetsController(this.#app,proxy,index,this.#logger)}#addRepositoryControllers(repository,index){new JitarController(this.#app),new ModulesController(this.#app,repository,this.#serializer,this.#logger),new AssetsController(this.#app,repository,index,this.#logger)}#addGatewayControllers(gateway){new NodesController(this.#app,gateway,this.#logger),new ProceduresController(this.#app,gateway,this.#logger),new RPCController(this.#app,gateway,this.#serializer,this.#logger)}#addNodeControllers(node){new HealthController(this.#app,node,this.#logger),new ProceduresController(this.#app,node,this.#logger),new RPCController(this.#app,node,this.#serializer,this.#logger)}#addProxyControllers(proxy){new ProxyController(this.#app,proxy,this.#logger)}async#startServer(port){return new Promise((resolve=>{this.#app.listen(port,resolve)}))}#printStartupMessage(){console.log("\n ██ ██ ████████ █████ ██████ \n ██ ██ ██ ██ ██ ██ ██ \n ██ ██ ██ ███████ ██████ \n ██ ██ ██ ██ ██ ██ ██ ██ \n █████ ██ ██ ██ ██ ██ ██\n ____________________________________\n By Masking Technology (masking.tech)\n")}}async function buildServer(moduleImporter){ModuleLoader.setImporter(moduleImporter);const server=new JitarServer;return await server.build(),server}export{CorsMiddleware,buildServer};
|
package/package.json
CHANGED
|
@@ -1,27 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jitar",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Distributed runtime for JavaScript and TypeScript to chop monolithic applications into micros.",
|
|
5
5
|
"author": "Masking Technology <info@masking.tech> (https://jitar.dev)",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|
|
8
|
-
"types": "dist/lib.d.ts",
|
|
8
|
+
"types": "./dist/lib.d.ts",
|
|
9
9
|
"sideEffects": true,
|
|
10
10
|
"exports": {
|
|
11
11
|
".": "./dist/lib.js",
|
|
12
|
-
"./
|
|
13
|
-
"./
|
|
12
|
+
"./server": "./dist/server.js",
|
|
13
|
+
"./client": "./dist/client.js"
|
|
14
14
|
},
|
|
15
|
+
"files": ["CHANGELOG.md", "README.md", "dist", "!dist/types"],
|
|
15
16
|
"scripts": {
|
|
16
|
-
"test": "vitest run",
|
|
17
|
-
"test-coverage": "vitest run --coverage",
|
|
18
17
|
"lint": "eslint . --ext .ts",
|
|
19
|
-
"
|
|
20
|
-
"
|
|
18
|
+
"validate": "tsc -p tsconfig.json --noEmit",
|
|
19
|
+
"build": "npm run clean && rollup -c",
|
|
20
|
+
"clean": "rm -rf dist",
|
|
21
21
|
"release": "npm run clean && npm run build && npm publish"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"
|
|
24
|
+
"express": "^4.18.2",
|
|
25
|
+
"express-http-proxy": "^1.6.3",
|
|
26
|
+
"fs-extra": "^11.1.1",
|
|
27
|
+
"glob-promise": "6.0.3",
|
|
28
|
+
"mime-types": "^2.1.35",
|
|
29
|
+
"tslog": "^4.8.2",
|
|
30
|
+
"yargs": "^17.7.2",
|
|
31
|
+
"zod": "^3.21.4"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@jitar/runtime": "^0.4.1",
|
|
35
|
+
"@jitar/server-nodejs": "^0.4.1"
|
|
25
36
|
},
|
|
26
37
|
"engines": {
|
|
27
38
|
"node": ">=18.7"
|
|
@@ -43,6 +54,5 @@
|
|
|
43
54
|
"monolith",
|
|
44
55
|
"full stack",
|
|
45
56
|
"web applications"
|
|
46
|
-
]
|
|
47
|
-
|
|
48
|
-
}
|
|
57
|
+
]
|
|
58
|
+
}
|
package/LICENCE
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
(The MIT License)
|
|
3
|
-
|
|
4
|
-
Copyright (c) 2023 Masking Technology B.V. <https://masking.tech>
|
|
5
|
-
|
|
6
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
|
7
|
-
a copy of this software and associated documentation files (the
|
|
8
|
-
'Software'), to deal in the Software without restriction, including
|
|
9
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
|
10
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
|
11
|
-
permit persons to whom the Software is furnished to do so, subject to
|
|
12
|
-
the following conditions:
|
|
13
|
-
|
|
14
|
-
The above copyright notice and this permission notice shall be
|
|
15
|
-
included in all copies or substantial portions of the Software.
|
|
16
|
-
|
|
17
|
-
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
|
18
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
19
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
20
|
-
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
21
|
-
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
22
|
-
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
23
|
-
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/dist/client.d.ts
DELETED
package/dist/core/Context.d.ts
DELETED
package/dist/core/Context.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export default class ErrorManager {
|
|
2
|
-
static handle(error, name, version) {
|
|
3
|
-
const parentMessage = error instanceof Error ? error.message : String(error);
|
|
4
|
-
const newMessage = `${parentMessage}\n[${name} | v${version}]`;
|
|
5
|
-
if (error instanceof Error) {
|
|
6
|
-
error.message = newMessage;
|
|
7
|
-
return error;
|
|
8
|
-
}
|
|
9
|
-
return new Error(newMessage);
|
|
10
|
-
}
|
|
11
|
-
}
|