vanta-auditor-api-sdk 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.devcontainer/README.md +5 -0
- package/.devcontainer/devcontainer.json +45 -0
- package/FUNCTIONS.md +5 -22
- package/README.md +157 -58
- package/bin/mcp-server.js +39200 -0
- package/bin/mcp-server.js.map +322 -0
- package/docs/sdks/auditors/README.md +7 -11
- package/docs/sdks/audits/README.md +71 -102
- package/examples/README.md +31 -0
- package/examples/auditsList.example.ts +26 -0
- package/examples/package-lock.json +626 -0
- package/examples/package.json +18 -0
- package/funcs/auditorsCreate.d.ts +4 -2
- package/funcs/auditorsCreate.d.ts.map +1 -1
- package/funcs/auditorsCreate.js +17 -9
- package/funcs/auditorsCreate.js.map +1 -1
- package/funcs/auditsCreateCommentForEvidence.d.ts +4 -2
- package/funcs/auditsCreateCommentForEvidence.d.ts.map +1 -1
- package/funcs/auditsCreateCommentForEvidence.js +17 -9
- package/funcs/auditsCreateCommentForEvidence.js.map +1 -1
- package/funcs/auditsCreateCustomControl.d.ts +4 -2
- package/funcs/auditsCreateCustomControl.d.ts.map +1 -1
- package/funcs/auditsCreateCustomControl.js +17 -9
- package/funcs/auditsCreateCustomControl.js.map +1 -1
- package/funcs/auditsCreateCustomEvidenceRequest.d.ts +4 -2
- package/funcs/auditsCreateCustomEvidenceRequest.d.ts.map +1 -1
- package/funcs/auditsCreateCustomEvidenceRequest.js +17 -9
- package/funcs/auditsCreateCustomEvidenceRequest.js.map +1 -1
- package/funcs/auditsGetEvidenceUrls.d.ts +6 -3
- package/funcs/auditsGetEvidenceUrls.d.ts.map +1 -1
- package/funcs/auditsGetEvidenceUrls.js +19 -10
- package/funcs/auditsGetEvidenceUrls.js.map +1 -1
- package/funcs/auditsList.d.ts +4 -2
- package/funcs/auditsList.d.ts.map +1 -1
- package/funcs/auditsList.js +18 -9
- package/funcs/auditsList.js.map +1 -1
- package/funcs/auditsListComments.d.ts +4 -2
- package/funcs/auditsListComments.d.ts.map +1 -1
- package/funcs/auditsListComments.js +17 -9
- package/funcs/auditsListComments.js.map +1 -1
- package/funcs/auditsListControls.d.ts +4 -2
- package/funcs/auditsListControls.d.ts.map +1 -1
- package/funcs/auditsListControls.js +17 -9
- package/funcs/auditsListControls.js.map +1 -1
- package/funcs/auditsListEvidence.d.ts +4 -2
- package/funcs/auditsListEvidence.d.ts.map +1 -1
- package/funcs/auditsListEvidence.js +17 -9
- package/funcs/auditsListEvidence.js.map +1 -1
- package/funcs/auditsUpdateEvidence.d.ts +4 -2
- package/funcs/auditsUpdateEvidence.d.ts.map +1 -1
- package/funcs/auditsUpdateEvidence.js +17 -9
- package/funcs/auditsUpdateEvidence.js.map +1 -1
- package/hooks/types.d.ts +4 -1
- package/hooks/types.d.ts.map +1 -1
- package/index.d.ts +2 -0
- package/index.d.ts.map +1 -1
- package/index.js +3 -1
- package/index.js.map +1 -1
- package/jsr.json +27 -0
- package/lib/config.d.ts +11 -7
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +14 -3
- package/lib/config.js.map +1 -1
- package/lib/encodings.d.ts +10 -9
- package/lib/encodings.d.ts.map +1 -1
- package/lib/encodings.js +73 -47
- package/lib/encodings.js.map +1 -1
- package/lib/files.d.ts +5 -0
- package/lib/files.d.ts.map +1 -1
- package/lib/files.js +41 -0
- package/lib/files.js.map +1 -1
- package/lib/matchers.d.ts +6 -11
- package/lib/matchers.d.ts.map +1 -1
- package/lib/matchers.js +45 -31
- package/lib/matchers.js.map +1 -1
- package/lib/primitives.d.ts +4 -0
- package/lib/primitives.d.ts.map +1 -1
- package/lib/primitives.js +17 -0
- package/lib/primitives.js.map +1 -1
- package/lib/retries.js +0 -1
- package/lib/retries.js.map +1 -1
- package/lib/schemas.d.ts +1 -1
- package/lib/schemas.d.ts.map +1 -1
- package/lib/schemas.js +4 -1
- package/lib/schemas.js.map +1 -1
- package/lib/sdks.d.ts +5 -2
- package/lib/sdks.d.ts.map +1 -1
- package/lib/sdks.js +21 -24
- package/lib/sdks.js.map +1 -1
- package/lib/security.d.ts +6 -5
- package/lib/security.d.ts.map +1 -1
- package/lib/security.js +6 -1
- package/lib/security.js.map +1 -1
- package/mcp-server/build.d.mts.map +1 -0
- package/mcp-server/build.mjs +14 -0
- package/mcp-server/build.mjs.map +1 -0
- package/mcp-server/cli/start/command.d.ts +2 -0
- package/mcp-server/cli/start/command.d.ts.map +1 -0
- package/mcp-server/cli/start/command.js +126 -0
- package/mcp-server/cli/start/command.js.map +1 -0
- package/mcp-server/cli/start/impl.d.ts +16 -0
- package/mcp-server/cli/start/impl.d.ts.map +1 -0
- package/mcp-server/cli/start/impl.js +102 -0
- package/mcp-server/cli/start/impl.js.map +1 -0
- package/mcp-server/cli.d.ts +6 -0
- package/mcp-server/cli.d.ts.map +1 -0
- package/mcp-server/cli.js +10 -0
- package/mcp-server/cli.js.map +1 -0
- package/mcp-server/console-logger.d.ts +7 -0
- package/mcp-server/console-logger.d.ts.map +1 -0
- package/mcp-server/console-logger.js +59 -0
- package/mcp-server/console-logger.js.map +1 -0
- package/mcp-server/extensions.d.ts +11 -0
- package/mcp-server/extensions.d.ts.map +1 -0
- package/mcp-server/extensions.js +6 -0
- package/mcp-server/extensions.js.map +1 -0
- package/mcp-server/mcp-server.d.ts +2 -0
- package/mcp-server/mcp-server.d.ts.map +1 -0
- package/mcp-server/mcp-server.js +29 -0
- package/mcp-server/mcp-server.js.map +1 -0
- package/mcp-server/prompts.d.ts +26 -0
- package/mcp-server/prompts.d.ts.map +1 -0
- package/mcp-server/prompts.js +51 -0
- package/mcp-server/prompts.js.map +1 -0
- package/mcp-server/resources.d.ts +32 -0
- package/mcp-server/resources.d.ts.map +1 -0
- package/mcp-server/resources.js +87 -0
- package/mcp-server/resources.js.map +1 -0
- package/mcp-server/scopes.d.ts +3 -0
- package/mcp-server/scopes.d.ts.map +1 -0
- package/mcp-server/scopes.js +8 -0
- package/mcp-server/scopes.js.map +1 -0
- package/mcp-server/server.d.ts +13 -0
- package/mcp-server/server.d.ts.map +1 -0
- package/mcp-server/server.js +52 -0
- package/mcp-server/server.js.map +1 -0
- package/mcp-server/shared.d.ts +7 -0
- package/mcp-server/shared.d.ts.map +1 -0
- package/mcp-server/shared.js +98 -0
- package/mcp-server/shared.js.map +1 -0
- package/mcp-server/tools/auditorsCreate.d.ts +8 -0
- package/mcp-server/tools/auditorsCreate.d.ts.map +1 -0
- package/mcp-server/tools/auditorsCreate.js +64 -0
- package/mcp-server/tools/auditorsCreate.js.map +1 -0
- package/mcp-server/tools/auditsCreateCommentForEvidence.d.ts +8 -0
- package/mcp-server/tools/auditsCreateCommentForEvidence.d.ts.map +1 -0
- package/mcp-server/tools/auditsCreateCommentForEvidence.js +64 -0
- package/mcp-server/tools/auditsCreateCommentForEvidence.js.map +1 -0
- package/mcp-server/tools/auditsCreateCustomControl.d.ts +8 -0
- package/mcp-server/tools/auditsCreateCustomControl.d.ts.map +1 -0
- package/mcp-server/tools/auditsCreateCustomControl.js +64 -0
- package/mcp-server/tools/auditsCreateCustomControl.js.map +1 -0
- package/mcp-server/tools/auditsCreateCustomEvidenceRequest.d.ts +8 -0
- package/mcp-server/tools/auditsCreateCustomEvidenceRequest.d.ts.map +1 -0
- package/mcp-server/tools/auditsCreateCustomEvidenceRequest.js +64 -0
- package/mcp-server/tools/auditsCreateCustomEvidenceRequest.js.map +1 -0
- package/mcp-server/tools/auditsGetEvidenceUrls.d.ts +8 -0
- package/mcp-server/tools/auditsGetEvidenceUrls.d.ts.map +1 -0
- package/mcp-server/tools/auditsGetEvidenceUrls.js +65 -0
- package/mcp-server/tools/auditsGetEvidenceUrls.js.map +1 -0
- package/mcp-server/tools/auditsList.d.ts +8 -0
- package/mcp-server/tools/auditsList.d.ts.map +1 -0
- package/mcp-server/tools/auditsList.js +64 -0
- package/mcp-server/tools/auditsList.js.map +1 -0
- package/mcp-server/tools/auditsListComments.d.ts +8 -0
- package/mcp-server/tools/auditsListComments.d.ts.map +1 -0
- package/mcp-server/tools/auditsListComments.js +64 -0
- package/mcp-server/tools/auditsListComments.js.map +1 -0
- package/mcp-server/tools/auditsListControls.d.ts +8 -0
- package/mcp-server/tools/auditsListControls.d.ts.map +1 -0
- package/mcp-server/tools/auditsListControls.js +64 -0
- package/mcp-server/tools/auditsListControls.js.map +1 -0
- package/mcp-server/tools/auditsListEvidence.d.ts +8 -0
- package/mcp-server/tools/auditsListEvidence.d.ts.map +1 -0
- package/mcp-server/tools/auditsListEvidence.js +64 -0
- package/mcp-server/tools/auditsListEvidence.js.map +1 -0
- package/mcp-server/tools/auditsUpdateEvidence.d.ts +8 -0
- package/mcp-server/tools/auditsUpdateEvidence.d.ts.map +1 -0
- package/mcp-server/tools/auditsUpdateEvidence.js +64 -0
- package/mcp-server/tools/auditsUpdateEvidence.js.map +1 -0
- package/mcp-server/tools.d.ts +25 -0
- package/mcp-server/tools.d.ts.map +1 -0
- package/mcp-server/tools.js +82 -0
- package/mcp-server/tools.js.map +1 -0
- package/models/components/audit.d.ts +5 -2
- package/models/components/audit.d.ts.map +1 -1
- package/models/components/audit.js +5 -2
- package/models/components/audit.js.map +1 -1
- package/models/components/auditfocus.d.ts +28 -0
- package/models/components/auditfocus.d.ts.map +1 -0
- package/models/components/auditfocus.js +61 -0
- package/models/components/auditfocus.js.map +1 -0
- package/models/components/auditorcontrol.d.ts +14 -2
- package/models/components/auditorcontrol.d.ts.map +1 -1
- package/models/components/auditorcontrol.js +8 -2
- package/models/components/auditorcontrol.js.map +1 -1
- package/models/components/auditorenabledstatetransition.d.ts +3 -0
- package/models/components/auditorenabledstatetransition.d.ts.map +1 -1
- package/models/components/auditorenabledstatetransition.js +1 -0
- package/models/components/auditorenabledstatetransition.js.map +1 -1
- package/models/components/comment.d.ts +5 -0
- package/models/components/comment.d.ts.map +1 -1
- package/models/components/comment.js +2 -0
- package/models/components/comment.js.map +1 -1
- package/models/components/control.d.ts +8 -2
- package/models/components/control.d.ts.map +1 -1
- package/models/components/control.js +5 -2
- package/models/components/control.js.map +1 -1
- package/models/components/createcustomevidencerequestinput.d.ts +5 -0
- package/models/components/createcustomevidencerequestinput.d.ts.map +1 -1
- package/models/components/createcustomevidencerequestinput.js +2 -0
- package/models/components/createcustomevidencerequestinput.js.map +1 -1
- package/models/components/customfield.d.ts +52 -0
- package/models/components/customfield.d.ts.map +1 -0
- package/models/components/customfield.js +95 -0
- package/models/components/customfield.js.map +1 -0
- package/models/components/index.d.ts +3 -0
- package/models/components/index.d.ts.map +1 -1
- package/models/components/index.js +3 -0
- package/models/components/index.js.map +1 -1
- package/models/components/section.d.ts +37 -0
- package/models/components/section.d.ts.map +1 -0
- package/models/components/section.js +71 -0
- package/models/components/section.js.map +1 -0
- package/models/errors/apierror.d.ts +8 -6
- package/models/errors/apierror.d.ts.map +1 -1
- package/models/errors/apierror.js +23 -10
- package/models/errors/apierror.js.map +1 -1
- package/models/errors/index.d.ts +1 -0
- package/models/errors/index.d.ts.map +1 -1
- package/models/errors/index.js +1 -0
- package/models/errors/index.js.map +1 -1
- package/models/errors/responsevalidationerror.d.ts +26 -0
- package/models/errors/responsevalidationerror.d.ts.map +1 -0
- package/models/errors/responsevalidationerror.js +66 -0
- package/models/errors/responsevalidationerror.js.map +1 -0
- package/models/errors/sdkvalidationerror.d.ts +1 -0
- package/models/errors/sdkvalidationerror.d.ts.map +1 -1
- package/models/errors/sdkvalidationerror.js +14 -0
- package/models/errors/sdkvalidationerror.js.map +1 -1
- package/models/errors/vantaerror.d.ts +19 -0
- package/models/errors/vantaerror.d.ts.map +1 -0
- package/models/errors/vantaerror.js +20 -0
- package/models/errors/vantaerror.js.map +1 -0
- package/models/operations/listaudits.d.ts +5 -0
- package/models/operations/listaudits.d.ts.map +1 -1
- package/models/operations/listaudits.js +2 -0
- package/models/operations/listaudits.js.map +1 -1
- package/package.json +27 -10
- package/sdk/audits.d.ts +2 -1
- package/sdk/audits.d.ts.map +1 -1
- package/sdk/audits.js +2 -1
- package/sdk/audits.js.map +1 -1
- package/src/funcs/auditorsCreate.ts +58 -22
- package/src/funcs/auditsCreateCommentForEvidence.ts +58 -22
- package/src/funcs/auditsCreateCustomControl.ts +58 -22
- package/src/funcs/auditsCreateCustomEvidenceRequest.ts +58 -22
- package/src/funcs/auditsGetEvidenceUrls.ts +60 -23
- package/src/funcs/auditsList.ts +59 -22
- package/src/funcs/auditsListComments.ts +58 -22
- package/src/funcs/auditsListControls.ts +58 -22
- package/src/funcs/auditsListEvidence.ts +58 -22
- package/src/funcs/auditsUpdateEvidence.ts +58 -22
- package/src/hooks/types.ts +4 -1
- package/src/index.ts +2 -0
- package/src/lib/config.ts +21 -6
- package/src/lib/encodings.ts +95 -61
- package/src/lib/files.ts +43 -1
- package/src/lib/matchers.ts +64 -41
- package/src/lib/primitives.ts +28 -0
- package/src/lib/retries.ts +0 -1
- package/src/lib/schemas.ts +5 -0
- package/src/lib/sdks.ts +35 -25
- package/src/lib/security.ts +12 -5
- package/src/mcp-server/cli/start/command.ts +94 -0
- package/src/mcp-server/cli/start/impl.ts +130 -0
- package/src/mcp-server/cli.ts +13 -0
- package/src/mcp-server/console-logger.ts +71 -0
- package/src/mcp-server/extensions.ts +17 -0
- package/src/mcp-server/mcp-server.ts +26 -0
- package/src/mcp-server/prompts.ts +117 -0
- package/src/mcp-server/resources.ts +172 -0
- package/src/mcp-server/scopes.ts +7 -0
- package/src/mcp-server/server.ts +79 -0
- package/src/mcp-server/shared.ts +75 -0
- package/src/mcp-server/tools/auditorsCreate.ts +37 -0
- package/src/mcp-server/tools/auditsCreateCommentForEvidence.ts +38 -0
- package/src/mcp-server/tools/auditsCreateCustomControl.ts +37 -0
- package/src/mcp-server/tools/auditsCreateCustomEvidenceRequest.ts +39 -0
- package/src/mcp-server/tools/auditsGetEvidenceUrls.ts +38 -0
- package/src/mcp-server/tools/auditsList.ts +37 -0
- package/src/mcp-server/tools/auditsListComments.ts +37 -0
- package/src/mcp-server/tools/auditsListControls.ts +37 -0
- package/src/mcp-server/tools/auditsListEvidence.ts +37 -0
- package/src/mcp-server/tools/auditsUpdateEvidence.ts +37 -0
- package/src/mcp-server/tools.ts +129 -0
- package/src/models/components/audit.ts +13 -4
- package/src/models/components/auditfocus.ts +31 -0
- package/src/models/components/auditorcontrol.ts +30 -4
- package/src/models/components/auditorenabledstatetransition.ts +1 -0
- package/src/models/components/comment.ts +9 -0
- package/src/models/components/control.ts +17 -4
- package/src/models/components/createcustomevidencerequestinput.ts +7 -0
- package/src/models/components/customfield.ts +109 -0
- package/src/models/components/index.ts +3 -0
- package/src/models/components/section.ts +69 -0
- package/src/models/errors/apierror.ts +29 -16
- package/src/models/errors/index.ts +1 -0
- package/src/models/errors/responsevalidationerror.ts +50 -0
- package/src/models/errors/sdkvalidationerror.ts +12 -0
- package/src/models/errors/vantaerror.ts +35 -0
- package/src/models/operations/listaudits.ts +7 -0
- package/src/sdk/audits.ts +2 -1
- package/src/types/async.ts +68 -0
- package/src/types/constdatetime.ts +1 -1
- package/tsconfig.json +41 -0
- package/types/async.d.ts +23 -0
- package/types/async.d.ts.map +1 -0
- package/types/async.js +44 -0
- package/types/async.js.map +1 -0
- package/types/constdatetime.js +1 -1
package/src/lib/primitives.ts
CHANGED
|
@@ -120,3 +120,31 @@ export function abortSignalAny(signals: AbortSignal[]): AbortSignal {
|
|
|
120
120
|
|
|
121
121
|
return result;
|
|
122
122
|
}
|
|
123
|
+
|
|
124
|
+
export function compactMap<T>(
|
|
125
|
+
values: Record<string, T | undefined>,
|
|
126
|
+
): Record<string, T> {
|
|
127
|
+
const out: Record<string, T> = {};
|
|
128
|
+
|
|
129
|
+
for (const [k, v] of Object.entries(values)) {
|
|
130
|
+
if (typeof v !== "undefined") {
|
|
131
|
+
out[k] = v;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return out;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export function allRequired<V extends Record<string, unknown>>(
|
|
139
|
+
v: V,
|
|
140
|
+
):
|
|
141
|
+
| {
|
|
142
|
+
[K in keyof V]: NonNullable<V[K]>;
|
|
143
|
+
}
|
|
144
|
+
| undefined {
|
|
145
|
+
if (Object.values(v).every((x) => x == null)) {
|
|
146
|
+
return void 0;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return v as ReturnType<typeof allRequired<V>>;
|
|
150
|
+
}
|
package/src/lib/retries.ts
CHANGED
package/src/lib/schemas.ts
CHANGED
|
@@ -57,6 +57,7 @@ export function collectExtraKeys<
|
|
|
57
57
|
>(
|
|
58
58
|
obj: ZodObject<Shape, "strip", Catchall>,
|
|
59
59
|
extrasKey: K,
|
|
60
|
+
optional: boolean,
|
|
60
61
|
): ZodEffects<
|
|
61
62
|
typeof obj,
|
|
62
63
|
& output<ZodObject<Shape, "strict">>
|
|
@@ -81,6 +82,10 @@ export function collectExtraKeys<
|
|
|
81
82
|
delete val[key];
|
|
82
83
|
}
|
|
83
84
|
|
|
85
|
+
if (optional && Object.keys(extras).length === 0) {
|
|
86
|
+
return val;
|
|
87
|
+
}
|
|
88
|
+
|
|
84
89
|
return { ...val, [extrasKey]: extras };
|
|
85
90
|
});
|
|
86
91
|
}
|
package/src/lib/sdks.ts
CHANGED
|
@@ -47,12 +47,14 @@ export type RequestOptions = {
|
|
|
47
47
|
*/
|
|
48
48
|
serverURL?: string | URL;
|
|
49
49
|
/**
|
|
50
|
+
* @deprecated `fetchOptions` has been flattened into `RequestOptions`.
|
|
51
|
+
*
|
|
50
52
|
* Sets various request options on the `fetch` call made by an SDK method.
|
|
51
53
|
*
|
|
52
54
|
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request#options|Request}
|
|
53
55
|
*/
|
|
54
56
|
fetchOptions?: Omit<RequestInit, "method" | "body">;
|
|
55
|
-
}
|
|
57
|
+
} & Omit<RequestInit, "method" | "body">;
|
|
56
58
|
|
|
57
59
|
type RequestConfig = {
|
|
58
60
|
method: string;
|
|
@@ -63,6 +65,7 @@ type RequestConfig = {
|
|
|
63
65
|
headers?: HeadersInit;
|
|
64
66
|
security?: SecurityState | null;
|
|
65
67
|
uaHeader?: string;
|
|
68
|
+
userAgent?: string | undefined;
|
|
66
69
|
timeoutMs?: number;
|
|
67
70
|
};
|
|
68
71
|
|
|
@@ -79,7 +82,7 @@ export class ClientSDK {
|
|
|
79
82
|
readonly #httpClient: HTTPClient;
|
|
80
83
|
readonly #hooks: SDKHooks;
|
|
81
84
|
readonly #logger?: Logger | undefined;
|
|
82
|
-
|
|
85
|
+
public readonly _baseURL: URL | null;
|
|
83
86
|
public readonly _options: SDKOptions & { hooks?: SDKHooks };
|
|
84
87
|
|
|
85
88
|
constructor(options: SDKOptions = {}) {
|
|
@@ -94,19 +97,21 @@ export class ClientSDK {
|
|
|
94
97
|
} else {
|
|
95
98
|
this.#hooks = new SDKHooks();
|
|
96
99
|
}
|
|
97
|
-
this._options = { ...options, hooks: this.#hooks };
|
|
98
|
-
|
|
99
100
|
const url = serverURLFromOptions(options);
|
|
100
101
|
if (url) {
|
|
101
102
|
url.pathname = url.pathname.replace(/\/+$/, "") + "/";
|
|
102
103
|
}
|
|
104
|
+
|
|
103
105
|
const { baseURL, client } = this.#hooks.sdkInit({
|
|
104
106
|
baseURL: url,
|
|
105
107
|
client: options.httpClient || new HTTPClient(),
|
|
106
108
|
});
|
|
107
109
|
this._baseURL = baseURL;
|
|
108
110
|
this.#httpClient = client;
|
|
109
|
-
|
|
111
|
+
|
|
112
|
+
this._options = { ...options, hooks: this.#hooks };
|
|
113
|
+
|
|
114
|
+
this.#logger = this._options.debugLogger;
|
|
110
115
|
if (!this.#logger && env().VANTA_DEBUG) {
|
|
111
116
|
this.#logger = console;
|
|
112
117
|
}
|
|
@@ -135,7 +140,10 @@ export class ClientSDK {
|
|
|
135
140
|
|
|
136
141
|
const secQuery: string[] = [];
|
|
137
142
|
for (const [k, v] of Object.entries(security?.queryParams || {})) {
|
|
138
|
-
|
|
143
|
+
const q = encodeForm(k, v, { charEncoding: "percent" });
|
|
144
|
+
if (typeof q !== "undefined") {
|
|
145
|
+
secQuery.push(q);
|
|
146
|
+
}
|
|
139
147
|
}
|
|
140
148
|
if (secQuery.length) {
|
|
141
149
|
finalQuery += `&${secQuery.join("&")}`;
|
|
@@ -169,7 +177,9 @@ export class ClientSDK {
|
|
|
169
177
|
cookie = cookie.startsWith("; ") ? cookie.slice(2) : cookie;
|
|
170
178
|
headers.set("cookie", cookie);
|
|
171
179
|
|
|
172
|
-
const userHeaders = new Headers(
|
|
180
|
+
const userHeaders = new Headers(
|
|
181
|
+
options?.headers ?? options?.fetchOptions?.headers,
|
|
182
|
+
);
|
|
173
183
|
for (const [k, v] of userHeaders) {
|
|
174
184
|
headers.set(k, v);
|
|
175
185
|
}
|
|
@@ -177,29 +187,23 @@ export class ClientSDK {
|
|
|
177
187
|
// Only set user agent header in non-browser-like environments since CORS
|
|
178
188
|
// policy disallows setting it in browsers e.g. Chrome throws an error.
|
|
179
189
|
if (!isBrowserLike) {
|
|
180
|
-
headers.set(
|
|
190
|
+
headers.set(
|
|
191
|
+
conf.uaHeader ?? "user-agent",
|
|
192
|
+
conf.userAgent ?? SDK_METADATA.userAgent,
|
|
193
|
+
);
|
|
181
194
|
}
|
|
182
195
|
|
|
183
|
-
|
|
196
|
+
const fetchOptions: Omit<RequestInit, "method" | "body"> = {
|
|
197
|
+
...options?.fetchOptions,
|
|
198
|
+
...options,
|
|
199
|
+
};
|
|
184
200
|
if (!fetchOptions?.signal && conf.timeoutMs && conf.timeoutMs > 0) {
|
|
185
201
|
const timeoutSignal = AbortSignal.timeout(conf.timeoutMs);
|
|
186
|
-
|
|
187
|
-
fetchOptions = { signal: timeoutSignal };
|
|
188
|
-
} else {
|
|
189
|
-
fetchOptions.signal = timeoutSignal;
|
|
190
|
-
}
|
|
202
|
+
fetchOptions.signal = timeoutSignal;
|
|
191
203
|
}
|
|
192
204
|
|
|
193
205
|
if (conf.body instanceof ReadableStream) {
|
|
194
|
-
|
|
195
|
-
fetchOptions = {
|
|
196
|
-
// @ts-expect-error see https://github.com/node-fetch/node-fetch/issues/1769
|
|
197
|
-
duplex: "half",
|
|
198
|
-
};
|
|
199
|
-
} else {
|
|
200
|
-
// @ts-expect-error see https://github.com/node-fetch/node-fetch/issues/1769
|
|
201
|
-
fetchOptions.duplex = "half";
|
|
202
|
-
}
|
|
206
|
+
Object.assign(fetchOptions, { duplex: "half" });
|
|
203
207
|
}
|
|
204
208
|
|
|
205
209
|
let input;
|
|
@@ -304,7 +308,9 @@ export class ClientSDK {
|
|
|
304
308
|
}
|
|
305
309
|
}
|
|
306
310
|
|
|
307
|
-
const jsonLikeContentTypeRE =
|
|
311
|
+
const jsonLikeContentTypeRE = /(application|text)\/.*?\+*json.*/;
|
|
312
|
+
const jsonlLikeContentTypeRE =
|
|
313
|
+
/(application|text)\/(.*?\+*\bjsonl\b.*|.*?\+*\bx-ndjson\b.*)/;
|
|
308
314
|
async function logRequest(logger: Logger | undefined, req: Request) {
|
|
309
315
|
if (!logger) {
|
|
310
316
|
return;
|
|
@@ -370,9 +376,13 @@ async function logResponse(
|
|
|
370
376
|
logger.group("Body:");
|
|
371
377
|
switch (true) {
|
|
372
378
|
case matchContentType(res, "application/json")
|
|
373
|
-
|| jsonLikeContentTypeRE.test(ct):
|
|
379
|
+
|| jsonLikeContentTypeRE.test(ct) && !jsonlLikeContentTypeRE.test(ct):
|
|
374
380
|
logger.log(await res.clone().json());
|
|
375
381
|
break;
|
|
382
|
+
case matchContentType(res, "application/jsonl")
|
|
383
|
+
|| jsonlLikeContentTypeRE.test(ct):
|
|
384
|
+
logger.log(await res.clone().text());
|
|
385
|
+
break;
|
|
376
386
|
case matchContentType(res, "text/event-stream"):
|
|
377
387
|
logger.log(`<${contentType}>`);
|
|
378
388
|
break;
|
package/src/lib/security.ts
CHANGED
|
@@ -7,8 +7,8 @@ import { env } from "./env.js";
|
|
|
7
7
|
|
|
8
8
|
type OAuth2PasswordFlow = {
|
|
9
9
|
username: string;
|
|
10
|
-
password
|
|
11
|
-
clientID
|
|
10
|
+
password: string;
|
|
11
|
+
clientID?: string | undefined;
|
|
12
12
|
clientSecret?: string | undefined;
|
|
13
13
|
tokenURL: string;
|
|
14
14
|
};
|
|
@@ -86,7 +86,9 @@ type SecurityInputOAuth2ClientCredentials = {
|
|
|
86
86
|
value:
|
|
87
87
|
| { clientID?: string | undefined; clientSecret?: string | undefined }
|
|
88
88
|
| null
|
|
89
|
+
| string
|
|
89
90
|
| undefined;
|
|
91
|
+
fieldName?: string;
|
|
90
92
|
};
|
|
91
93
|
|
|
92
94
|
type SecurityInputOAuth2PasswordCredentials = {
|
|
@@ -95,13 +97,13 @@ type SecurityInputOAuth2PasswordCredentials = {
|
|
|
95
97
|
| string
|
|
96
98
|
| null
|
|
97
99
|
| undefined;
|
|
98
|
-
fieldName
|
|
100
|
+
fieldName?: string;
|
|
99
101
|
};
|
|
100
102
|
|
|
101
103
|
type SecurityInputCustom = {
|
|
102
104
|
type: "http:custom";
|
|
103
105
|
value: any | null | undefined;
|
|
104
|
-
fieldName
|
|
106
|
+
fieldName?: string;
|
|
105
107
|
};
|
|
106
108
|
|
|
107
109
|
export type SecurityInput =
|
|
@@ -138,6 +140,9 @@ export function resolveSecurity(
|
|
|
138
140
|
typeof o.value === "string" && !!o.value
|
|
139
141
|
);
|
|
140
142
|
} else if (o.type === "oauth2:client_credentials") {
|
|
143
|
+
if (typeof o.value == "string") {
|
|
144
|
+
return !!o.value;
|
|
145
|
+
}
|
|
141
146
|
return o.value.clientID != null || o.value.clientSecret != null;
|
|
142
147
|
} else if (typeof o.value === "string") {
|
|
143
148
|
return !!o.value;
|
|
@@ -226,7 +231,9 @@ function applyBearer(
|
|
|
226
231
|
value = `Bearer ${value}`;
|
|
227
232
|
}
|
|
228
233
|
|
|
229
|
-
|
|
234
|
+
if (spec.fieldName !== undefined) {
|
|
235
|
+
state.headers[spec.fieldName] = value;
|
|
236
|
+
}
|
|
230
237
|
}
|
|
231
238
|
|
|
232
239
|
export function resolveGlobalSecurity(
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { buildCommand } from "@stricli/core";
|
|
6
|
+
import { numberParser } from "@stricli/core";
|
|
7
|
+
import * as z from "zod";
|
|
8
|
+
import { consoleLoggerLevels } from "../../console-logger.js";
|
|
9
|
+
|
|
10
|
+
export const startCommand = buildCommand({
|
|
11
|
+
loader: async () => {
|
|
12
|
+
const { main } = await import("./impl.js");
|
|
13
|
+
return main;
|
|
14
|
+
},
|
|
15
|
+
parameters: {
|
|
16
|
+
flags: {
|
|
17
|
+
transport: {
|
|
18
|
+
kind: "enum",
|
|
19
|
+
brief: "The transport to use for communicating with the server",
|
|
20
|
+
default: "stdio",
|
|
21
|
+
values: ["stdio", "sse"],
|
|
22
|
+
},
|
|
23
|
+
port: {
|
|
24
|
+
kind: "parsed",
|
|
25
|
+
brief: "The port to use when the SSE transport is enabled",
|
|
26
|
+
default: "2718",
|
|
27
|
+
parse: (val: string) =>
|
|
28
|
+
z.coerce.number().int().gte(0).lt(65536).parse(val),
|
|
29
|
+
},
|
|
30
|
+
tool: {
|
|
31
|
+
kind: "parsed",
|
|
32
|
+
brief: "Specify tools to mount on the server",
|
|
33
|
+
optional: true,
|
|
34
|
+
variadic: true,
|
|
35
|
+
parse: (value) => {
|
|
36
|
+
return z.string().parse(value);
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
"bearer-auth": {
|
|
40
|
+
kind: "parsed",
|
|
41
|
+
brief: "Sets the bearerAuth auth field for the API",
|
|
42
|
+
optional: true,
|
|
43
|
+
parse: (value) => {
|
|
44
|
+
return z.string().parse(value);
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
"server-url": {
|
|
48
|
+
kind: "parsed",
|
|
49
|
+
brief: "Overrides the default server URL used by the SDK",
|
|
50
|
+
optional: true,
|
|
51
|
+
parse: (value) => new URL(value).toString(),
|
|
52
|
+
},
|
|
53
|
+
"server-index": {
|
|
54
|
+
kind: "parsed",
|
|
55
|
+
brief: "Selects a predefined server used by the SDK",
|
|
56
|
+
optional: true,
|
|
57
|
+
parse: numberParser,
|
|
58
|
+
},
|
|
59
|
+
"log-level": {
|
|
60
|
+
kind: "enum",
|
|
61
|
+
brief: "The log level to use for the server",
|
|
62
|
+
default: "info",
|
|
63
|
+
values: consoleLoggerLevels,
|
|
64
|
+
},
|
|
65
|
+
env: {
|
|
66
|
+
kind: "parsed",
|
|
67
|
+
brief: "Environment variables made available to the server",
|
|
68
|
+
optional: true,
|
|
69
|
+
variadic: true,
|
|
70
|
+
parse: (val: string) => {
|
|
71
|
+
const sepIdx = val.indexOf("=");
|
|
72
|
+
if (sepIdx === -1) {
|
|
73
|
+
throw new Error("Invalid environment variable format");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const key = val.slice(0, sepIdx);
|
|
77
|
+
const value = val.slice(sepIdx + 1);
|
|
78
|
+
|
|
79
|
+
return [
|
|
80
|
+
z.string().nonempty({
|
|
81
|
+
message: "Environment variable key must be a non-empty string",
|
|
82
|
+
}).parse(key),
|
|
83
|
+
z.string().nonempty({
|
|
84
|
+
message: "Environment variable value must be a non-empty string",
|
|
85
|
+
}).parse(value),
|
|
86
|
+
] satisfies [string, string];
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
docs: {
|
|
92
|
+
brief: "Run the Model Context Protocol server",
|
|
93
|
+
},
|
|
94
|
+
});
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
|
|
6
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
7
|
+
import express from "express";
|
|
8
|
+
import { SDKOptions } from "../../../lib/config.js";
|
|
9
|
+
import { LocalContext } from "../../cli.js";
|
|
10
|
+
import {
|
|
11
|
+
ConsoleLoggerLevel,
|
|
12
|
+
createConsoleLogger,
|
|
13
|
+
} from "../../console-logger.js";
|
|
14
|
+
import { createMCPServer } from "../../server.js";
|
|
15
|
+
|
|
16
|
+
interface StartCommandFlags {
|
|
17
|
+
readonly transport: "stdio" | "sse";
|
|
18
|
+
readonly port: number;
|
|
19
|
+
readonly tool?: string[];
|
|
20
|
+
readonly "bearer-auth"?: string | undefined;
|
|
21
|
+
readonly "server-url"?: string;
|
|
22
|
+
readonly "server-index"?: SDKOptions["serverIdx"];
|
|
23
|
+
readonly "log-level": ConsoleLoggerLevel;
|
|
24
|
+
readonly env?: [string, string][];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export async function main(this: LocalContext, flags: StartCommandFlags) {
|
|
28
|
+
flags.env?.forEach(([key, value]) => {
|
|
29
|
+
process.env[key] = value;
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
switch (flags.transport) {
|
|
33
|
+
case "stdio":
|
|
34
|
+
await startStdio(flags);
|
|
35
|
+
break;
|
|
36
|
+
case "sse":
|
|
37
|
+
await startSSE(flags);
|
|
38
|
+
break;
|
|
39
|
+
default:
|
|
40
|
+
throw new Error(`Invalid transport: ${flags.transport}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function startStdio(flags: StartCommandFlags) {
|
|
45
|
+
const logger = createConsoleLogger(flags["log-level"]);
|
|
46
|
+
const transport = new StdioServerTransport();
|
|
47
|
+
const server = createMCPServer({
|
|
48
|
+
logger,
|
|
49
|
+
allowedTools: flags.tool,
|
|
50
|
+
...{ bearerAuth: flags["bearer-auth"] ?? "" },
|
|
51
|
+
serverURL: flags["server-url"],
|
|
52
|
+
serverIdx: flags["server-index"],
|
|
53
|
+
});
|
|
54
|
+
await server.connect(transport);
|
|
55
|
+
|
|
56
|
+
const abort = async () => {
|
|
57
|
+
await server.close();
|
|
58
|
+
process.exit(0);
|
|
59
|
+
};
|
|
60
|
+
process.on("SIGTERM", abort);
|
|
61
|
+
process.on("SIGINT", abort);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async function startSSE(flags: StartCommandFlags) {
|
|
65
|
+
const logger = createConsoleLogger(flags["log-level"]);
|
|
66
|
+
const app = express();
|
|
67
|
+
const mcpServer = createMCPServer({
|
|
68
|
+
logger,
|
|
69
|
+
allowedTools: flags.tool,
|
|
70
|
+
...{ bearerAuth: flags["bearer-auth"] ?? "" },
|
|
71
|
+
serverURL: flags["server-url"],
|
|
72
|
+
serverIdx: flags["server-index"],
|
|
73
|
+
});
|
|
74
|
+
let transport: SSEServerTransport | undefined;
|
|
75
|
+
const controller = new AbortController();
|
|
76
|
+
|
|
77
|
+
app.get("/sse", async (_req, res) => {
|
|
78
|
+
transport = new SSEServerTransport("/message", res);
|
|
79
|
+
|
|
80
|
+
await mcpServer.connect(transport);
|
|
81
|
+
|
|
82
|
+
mcpServer.server.onclose = async () => {
|
|
83
|
+
res.end();
|
|
84
|
+
};
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
app.post("/message", async (req, res) => {
|
|
88
|
+
if (!transport) {
|
|
89
|
+
throw new Error("Server transport not initialized");
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
await transport.handlePostMessage(req, res);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const httpServer = app.listen(flags.port, "0.0.0.0", () => {
|
|
96
|
+
const ha = httpServer.address();
|
|
97
|
+
const host = typeof ha === "string" ? ha : `${ha?.address}:${ha?.port}`;
|
|
98
|
+
logger.info("MCP HTTP server started", { host });
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
let closing = false;
|
|
102
|
+
controller.signal.addEventListener("abort", async () => {
|
|
103
|
+
if (closing) {
|
|
104
|
+
logger.info("Received second signal. Forcing shutdown.");
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
closing = true;
|
|
108
|
+
|
|
109
|
+
logger.info("Shutting down MCP server");
|
|
110
|
+
|
|
111
|
+
await mcpServer.close();
|
|
112
|
+
|
|
113
|
+
logger.info("Shutting down HTTP server");
|
|
114
|
+
|
|
115
|
+
const timer = setTimeout(() => {
|
|
116
|
+
logger.info("Forcing shutdown");
|
|
117
|
+
process.exit(1);
|
|
118
|
+
}, 5000);
|
|
119
|
+
|
|
120
|
+
httpServer.close(() => {
|
|
121
|
+
clearTimeout(timer);
|
|
122
|
+
logger.info("Graceful shutdown complete");
|
|
123
|
+
process.exit(0);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
const abort = () => controller.abort();
|
|
128
|
+
process.on("SIGTERM", abort);
|
|
129
|
+
process.on("SIGINT", abort);
|
|
130
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { CommandContext, StricliProcess } from "@stricli/core";
|
|
6
|
+
|
|
7
|
+
export interface LocalContext extends CommandContext {
|
|
8
|
+
readonly process: StricliProcess;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function buildContext(process: NodeJS.Process): LocalContext {
|
|
12
|
+
return { process: process as StricliProcess };
|
|
13
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export const consoleLoggerLevels = [
|
|
6
|
+
"debug",
|
|
7
|
+
"warning",
|
|
8
|
+
"info",
|
|
9
|
+
"error",
|
|
10
|
+
] as const;
|
|
11
|
+
|
|
12
|
+
export type ConsoleLoggerLevel = (typeof consoleLoggerLevels)[number];
|
|
13
|
+
|
|
14
|
+
export type ConsoleLogger = {
|
|
15
|
+
[key in ConsoleLoggerLevel]: (
|
|
16
|
+
message: string,
|
|
17
|
+
data?: Record<string, unknown>,
|
|
18
|
+
) => void;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export function createConsoleLogger(level: ConsoleLoggerLevel): ConsoleLogger {
|
|
22
|
+
const min = consoleLoggerLevels.indexOf(level);
|
|
23
|
+
const noop = () => {};
|
|
24
|
+
|
|
25
|
+
const logger: ConsoleLogger = {
|
|
26
|
+
debug: noop,
|
|
27
|
+
warning: noop,
|
|
28
|
+
info: noop,
|
|
29
|
+
error: noop,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
return consoleLoggerLevels.reduce((logger, level, i) => {
|
|
33
|
+
if (i < min) {
|
|
34
|
+
return logger;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
logger[level] = log.bind(null, level);
|
|
38
|
+
|
|
39
|
+
return logger;
|
|
40
|
+
}, logger);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function log(
|
|
44
|
+
level: ConsoleLoggerLevel,
|
|
45
|
+
message: string,
|
|
46
|
+
data?: Record<string, unknown>,
|
|
47
|
+
) {
|
|
48
|
+
let line = "";
|
|
49
|
+
const allData = [{ msg: message, l: level }, data];
|
|
50
|
+
|
|
51
|
+
for (const ctx of allData) {
|
|
52
|
+
for (const [key, value] of Object.entries(ctx || {})) {
|
|
53
|
+
if (value == null) {
|
|
54
|
+
line += ` ${key}=<${value}>`;
|
|
55
|
+
} else if (typeof value === "function") {
|
|
56
|
+
line += ` ${key}=<function>`;
|
|
57
|
+
} else if (typeof value === "symbol") {
|
|
58
|
+
line += ` ${key}=${value.toString()}`;
|
|
59
|
+
} else if (typeof value === "string") {
|
|
60
|
+
const v = value.search(/\s/g) >= 0 ? JSON.stringify(value) : value;
|
|
61
|
+
line += ` ${key}=${v}`;
|
|
62
|
+
} else if (typeof value !== "object") {
|
|
63
|
+
line += ` ${key}=${value}`;
|
|
64
|
+
} else {
|
|
65
|
+
line += ` ${key}="${JSON.stringify(value)}"`;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
console.error(line);
|
|
71
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { ZodRawShape } from "zod";
|
|
6
|
+
import { PromptArgsRawShape, PromptDefinition } from "./prompts.js";
|
|
7
|
+
import { ResourceDefinition, ResourceTemplateDefinition } from "./resources.js";
|
|
8
|
+
import { ToolDefinition } from "./tools.js";
|
|
9
|
+
|
|
10
|
+
export type Register = {
|
|
11
|
+
tool: <A extends ZodRawShape | undefined>(def: ToolDefinition<A>) => void;
|
|
12
|
+
resource: (def: ResourceDefinition) => void;
|
|
13
|
+
resourceTemplate: (def: ResourceTemplateDefinition) => void;
|
|
14
|
+
prompt: <A extends PromptArgsRawShape | undefined>(
|
|
15
|
+
prompt: PromptDefinition<A>,
|
|
16
|
+
) => void;
|
|
17
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { buildApplication, buildRouteMap, run } from "@stricli/core";
|
|
6
|
+
import process from "node:process";
|
|
7
|
+
import { buildContext } from "./cli.js";
|
|
8
|
+
import { startCommand } from "./cli/start/command.js";
|
|
9
|
+
|
|
10
|
+
const routes = buildRouteMap({
|
|
11
|
+
routes: {
|
|
12
|
+
start: startCommand,
|
|
13
|
+
},
|
|
14
|
+
docs: {
|
|
15
|
+
brief: "MCP server CLI",
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export const app = buildApplication(routes, {
|
|
20
|
+
name: "mcp",
|
|
21
|
+
versionInfo: {
|
|
22
|
+
currentVersion: "0.3.0",
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
run(app, process.argv.slice(2), buildContext(process));
|