@apicircle/shared 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +110 -0
- package/README.md +27 -0
- package/dist/index.cjs +547 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1245 -0
- package/dist/index.d.ts +1245 -0
- package/dist/index.js +487 -0
- package/dist/index.js.map +1 -0
- package/package.json +47 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
APICircle Studio License
|
|
2
|
+
Custom Source-Available License, v1.0
|
|
3
|
+
|
|
4
|
+
Copyright (c) 2026 Deva Prakash ("Licensor")
|
|
5
|
+
|
|
6
|
+
The source code in this repository ("the Software") is made available for
|
|
7
|
+
the purposes of transparency, security review, contribution, and personal
|
|
8
|
+
evaluation. This is NOT an open-source license as defined by the Open
|
|
9
|
+
Source Initiative.
|
|
10
|
+
|
|
11
|
+
0. Definitions
|
|
12
|
+
|
|
13
|
+
"Commercial Use" means any use of the Software that is intended for
|
|
14
|
+
or directed toward commercial advantage or monetary compensation,
|
|
15
|
+
whether direct or indirect, including without limitation:
|
|
16
|
+
|
|
17
|
+
(a) using the Software to build, test, develop, deploy, or operate
|
|
18
|
+
any product, service, application, or system that is sold,
|
|
19
|
+
licensed, hosted, distributed, or otherwise made available to
|
|
20
|
+
any third party for a fee or other consideration;
|
|
21
|
+
(b) using the Software in the course of paid employment, paid
|
|
22
|
+
consulting, paid contracting, freelance work, or any other
|
|
23
|
+
revenue-generating activity, regardless of whether the Software
|
|
24
|
+
itself is sold or transferred;
|
|
25
|
+
(c) using the Software internally within a for-profit organization
|
|
26
|
+
beyond the Evaluation Period defined below;
|
|
27
|
+
(d) integrating the Software, or any portion of it, into any tool,
|
|
28
|
+
pipeline, automation, or workflow that supports the commercial
|
|
29
|
+
operations of any business;
|
|
30
|
+
(e) using the Software to provide a hosted, managed, or embedded
|
|
31
|
+
service of any kind to a third party, whether free or paid.
|
|
32
|
+
|
|
33
|
+
"Non-Commercial Use" means any use that is not Commercial Use,
|
|
34
|
+
including personal hobby projects, individual learning, academic
|
|
35
|
+
research, classroom instruction, and good-faith contribution to
|
|
36
|
+
this repository.
|
|
37
|
+
|
|
38
|
+
"Evaluation Period" means a single, continuous period of up to
|
|
39
|
+
thirty (30) days during which a for-profit organization may
|
|
40
|
+
internally evaluate the Software at no charge. After the Evaluation
|
|
41
|
+
Period expires, any further use of the Software by that organization
|
|
42
|
+
constitutes Commercial Use and requires a separate commercial
|
|
43
|
+
license from the Licensor.
|
|
44
|
+
|
|
45
|
+
1. Permitted Use
|
|
46
|
+
|
|
47
|
+
You may, without charge:
|
|
48
|
+
|
|
49
|
+
(a) view, read, and study the source code of the Software;
|
|
50
|
+
(b) run the Software, in source or compiled form, for your own
|
|
51
|
+
Non-Commercial Use, or for Commercial Use solely within the
|
|
52
|
+
Evaluation Period;
|
|
53
|
+
(c) submit improvements to the Software back to this repository via
|
|
54
|
+
pull request, subject to Section 3 (Contributions).
|
|
55
|
+
|
|
56
|
+
2. Prohibited Use
|
|
57
|
+
|
|
58
|
+
Without prior written permission from the Licensor, you may NOT:
|
|
59
|
+
|
|
60
|
+
(a) make any Commercial Use of the Software, in whole or in part,
|
|
61
|
+
except during the Evaluation Period as defined in Section 0;
|
|
62
|
+
(b) redistribute the Software, in source or compiled form, whether
|
|
63
|
+
modified or unmodified, to any third party;
|
|
64
|
+
(c) sublicense, sell, rent, lease, or otherwise transfer the
|
|
65
|
+
Software or any rights granted herein;
|
|
66
|
+
(d) remove, obscure, or alter any copyright, trademark, attribution,
|
|
67
|
+
or license notice contained in the Software;
|
|
68
|
+
(e) use the names "APICircle", "API Circle Studio", or any related
|
|
69
|
+
logos or trademarks, except as required for accurate attribution.
|
|
70
|
+
|
|
71
|
+
3. Contributions
|
|
72
|
+
|
|
73
|
+
By submitting any contribution (including but not limited to code,
|
|
74
|
+
documentation, or assets) to this repository, you grant the Licensor
|
|
75
|
+
a perpetual, worldwide, irrevocable, royalty-free, sublicensable
|
|
76
|
+
license to use, modify, distribute, and relicense your contribution
|
|
77
|
+
under any terms, including the terms of this license or any future
|
|
78
|
+
version thereof.
|
|
79
|
+
|
|
80
|
+
4. No Trademark License
|
|
81
|
+
|
|
82
|
+
This license does not grant permission to use the trade names,
|
|
83
|
+
trademarks, service marks, or product names of the Licensor, except
|
|
84
|
+
as required for reasonable and customary use in describing the
|
|
85
|
+
origin of the Software.
|
|
86
|
+
|
|
87
|
+
5. Termination
|
|
88
|
+
|
|
89
|
+
The rights granted in Section 1 terminate automatically if you
|
|
90
|
+
breach any term of this license. Upon termination, you must cease
|
|
91
|
+
all use of the Software and destroy all copies in your possession.
|
|
92
|
+
|
|
93
|
+
6. Disclaimer of Warranty
|
|
94
|
+
|
|
95
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
96
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
97
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
|
|
98
|
+
NON-INFRINGEMENT.
|
|
99
|
+
|
|
100
|
+
7. Limitation of Liability
|
|
101
|
+
|
|
102
|
+
IN NO EVENT SHALL THE LICENSOR BE LIABLE FOR ANY CLAIM, DAMAGES, OR
|
|
103
|
+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR
|
|
104
|
+
OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE
|
|
105
|
+
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
106
|
+
|
|
107
|
+
8. Commercial Licensing
|
|
108
|
+
|
|
109
|
+
For commercial licensing, redistribution, or any use not permitted
|
|
110
|
+
under Section 1, contact: apicircle365@gmail.com
|
package/README.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/apicircle/studio/main/assets/logo.png" alt="APICircle Studio" width="120" height="120" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">@apicircle/shared</h1>
|
|
6
|
+
|
|
7
|
+
Shared foundation for [APICircle Studio](https://github.com/apicircle/studio) — the TypeScript types, ID generation, validators, and encryption helpers every other `@apicircle/*` package builds on.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @apicircle/shared
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## What's inside
|
|
16
|
+
|
|
17
|
+
- **Workspace types** — the canonical `WorkspaceSynced` / `WorkspaceLocal` schema and every entity type (requests, folders, environments, mock servers, plans, releases).
|
|
18
|
+
- **`generateId()`** — collision-resistant ID generation; the only sanctioned way to mint entity IDs.
|
|
19
|
+
- **Validators** — shape checks for workspace documents and imported specs.
|
|
20
|
+
- **Encryption helpers** — AES-GCM via WebCrypto for at-rest secret material.
|
|
21
|
+
- **MCP envelopes** — the request/response envelope types shared with `@apicircle/mcp-server`.
|
|
22
|
+
|
|
23
|
+
This package is mostly consumed indirectly through the other APICircle packages — install it directly when you are building tooling against the workspace format.
|
|
24
|
+
|
|
25
|
+
## License
|
|
26
|
+
|
|
27
|
+
Released under the **APICircle Studio License** — a custom source-available license, not an OSI-approved open-source license. Free for personal, educational, and non-commercial use, plus a 30-day commercial evaluation period; ongoing commercial use requires a separate license. See [LICENSE](./LICENSE) for the full terms, or contact **apicircle365@gmail.com** for commercial licensing.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,547 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
DEFAULT_WORKSPACE_NAME: () => DEFAULT_WORKSPACE_NAME,
|
|
24
|
+
FONT_SIZE_PERCENT_DEFAULT: () => FONT_SIZE_PERCENT_DEFAULT,
|
|
25
|
+
FONT_SIZE_PERCENT_MAX: () => FONT_SIZE_PERCENT_MAX,
|
|
26
|
+
FONT_SIZE_PERCENT_MIN: () => FONT_SIZE_PERCENT_MIN,
|
|
27
|
+
FONT_SIZE_PERCENT_STEP: () => FONT_SIZE_PERCENT_STEP,
|
|
28
|
+
MCP_TOOL_NAMES: () => MCP_TOOL_NAMES,
|
|
29
|
+
REQUEST_AUTH_TYPES: () => REQUEST_AUTH_TYPES,
|
|
30
|
+
RUN_BODY_PREVIEW_LIMIT: () => RUN_BODY_PREVIEW_LIMIT,
|
|
31
|
+
coerceMockResponseBodyTypeForStatus: () => coerceMockResponseBodyTypeForStatus,
|
|
32
|
+
defaultAuthFor: () => defaultAuthFor,
|
|
33
|
+
envPriorityDisplayName: () => envPriorityDisplayName,
|
|
34
|
+
envPriorityKey: () => envPriorityKey,
|
|
35
|
+
envPriorityRefEqual: () => envPriorityRefEqual,
|
|
36
|
+
formatBytes: () => formatBytes,
|
|
37
|
+
generateId: () => generateId,
|
|
38
|
+
getAllowedMockResponseBodyTypes: () => getAllowedMockResponseBodyTypes,
|
|
39
|
+
makeDefaultMockResponse: () => makeDefaultMockResponse,
|
|
40
|
+
makeDefaultMockResponseBody: () => makeDefaultMockResponseBody,
|
|
41
|
+
makeDefaultRequestSchema: () => makeDefaultRequestSchema,
|
|
42
|
+
normalizeAuth: () => normalizeAuth,
|
|
43
|
+
parseEnvPriorityKey: () => parseEnvPriorityKey,
|
|
44
|
+
safeExternalHref: () => safeExternalHref,
|
|
45
|
+
utf8ByteLength: () => utf8ByteLength,
|
|
46
|
+
validateAwsRegion: () => validateAwsRegion,
|
|
47
|
+
validateEnvVarName: () => validateEnvVarName,
|
|
48
|
+
validateHttpHeaderName: () => validateHttpHeaderName,
|
|
49
|
+
validateJsonPath: () => validateJsonPath,
|
|
50
|
+
validateJsonString: () => validateJsonString,
|
|
51
|
+
validateMockPath: () => validateMockPath,
|
|
52
|
+
validatePRTitle: () => validatePRTitle,
|
|
53
|
+
validatePlanName: () => validatePlanName,
|
|
54
|
+
validatePositiveDuration: () => validatePositiveDuration,
|
|
55
|
+
validateRegex: () => validateRegex,
|
|
56
|
+
validateUrl: () => validateUrl
|
|
57
|
+
});
|
|
58
|
+
module.exports = __toCommonJS(src_exports);
|
|
59
|
+
|
|
60
|
+
// src/ids.ts
|
|
61
|
+
function generateId() {
|
|
62
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
63
|
+
return crypto.randomUUID();
|
|
64
|
+
}
|
|
65
|
+
const bytes = new Uint8Array(16);
|
|
66
|
+
if (typeof crypto !== "undefined") {
|
|
67
|
+
crypto.getRandomValues(bytes);
|
|
68
|
+
} else {
|
|
69
|
+
for (let i = 0; i < 16; i++) bytes[i] = Math.floor(Math.random() * 256);
|
|
70
|
+
}
|
|
71
|
+
bytes[6] = bytes[6] & 15 | 64;
|
|
72
|
+
bytes[8] = bytes[8] & 63 | 128;
|
|
73
|
+
const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
74
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// src/validators.ts
|
|
78
|
+
var OK = { ok: true };
|
|
79
|
+
var fail = (reason) => ({ ok: false, reason });
|
|
80
|
+
function validateUrl(value) {
|
|
81
|
+
const trimmed = value.trim();
|
|
82
|
+
if (!trimmed) return fail("URL is required.");
|
|
83
|
+
if (/^\s*\{\{\s*[^{}]+\s*\}\}/.test(trimmed)) return OK;
|
|
84
|
+
const probe = trimmed.replace(/\{\{[^{}]+\}\}/g, "placeholder");
|
|
85
|
+
try {
|
|
86
|
+
const u = new URL(probe);
|
|
87
|
+
if (!/^https?:|^file:$/i.test(u.protocol)) {
|
|
88
|
+
return fail(`Unsupported scheme "${u.protocol}". Use http(s):// or file://.`);
|
|
89
|
+
}
|
|
90
|
+
if (u.protocol !== "file:" && !u.host) return fail("URL is missing a host.");
|
|
91
|
+
return OK;
|
|
92
|
+
} catch {
|
|
93
|
+
return fail("Not a valid URL. Expected http(s)://host/path.");
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
var AWS_DIRECTIONS = /* @__PURE__ */ new Set([
|
|
97
|
+
"east",
|
|
98
|
+
"west",
|
|
99
|
+
"north",
|
|
100
|
+
"south",
|
|
101
|
+
"central",
|
|
102
|
+
"northeast",
|
|
103
|
+
"northwest",
|
|
104
|
+
"southeast",
|
|
105
|
+
"southwest"
|
|
106
|
+
]);
|
|
107
|
+
function validateAwsRegion(value) {
|
|
108
|
+
const v = value.trim().toLowerCase();
|
|
109
|
+
if (!v) return fail("Region is required (e.g. us-east-1).");
|
|
110
|
+
const m = /^([a-z]{2,3})-(?:([a-z]+)-)?([a-z]+)-(\d+)$/.exec(v);
|
|
111
|
+
if (!m) return fail('Region must look like "us-east-1" or "us-gov-west-1".');
|
|
112
|
+
const direction = m[3];
|
|
113
|
+
if (!AWS_DIRECTIONS.has(direction)) {
|
|
114
|
+
return fail(`Unknown direction "${direction}". Expected east/west/north/south/central/etc.`);
|
|
115
|
+
}
|
|
116
|
+
return OK;
|
|
117
|
+
}
|
|
118
|
+
function validateMockPath(value) {
|
|
119
|
+
const v = value.trim();
|
|
120
|
+
if (!v) return fail("Path is required.");
|
|
121
|
+
if (!v.startsWith("/")) return fail('Path must start with "/".');
|
|
122
|
+
if (/\s/.test(v)) return fail("Path must not contain whitespace.");
|
|
123
|
+
if (v.includes("?")) return fail("Path must not include a query string.");
|
|
124
|
+
if (v.includes("#")) return fail("Path must not include a fragment.");
|
|
125
|
+
return OK;
|
|
126
|
+
}
|
|
127
|
+
function validateEnvVarName(value) {
|
|
128
|
+
const v = value.trim();
|
|
129
|
+
if (!v) return fail("Variable name is required.");
|
|
130
|
+
if (/[\s{}]/.test(v)) return fail("Variable name cannot contain spaces or braces.");
|
|
131
|
+
if (!/^[A-Za-z_][A-Za-z0-9_-]*$/.test(v)) {
|
|
132
|
+
return fail("Use letters, digits, underscores, hyphens. Must start with a letter or _.");
|
|
133
|
+
}
|
|
134
|
+
return OK;
|
|
135
|
+
}
|
|
136
|
+
function validatePlanName(value) {
|
|
137
|
+
const v = value.trim();
|
|
138
|
+
if (!v) return fail("Plan name is required.");
|
|
139
|
+
if (v.length > 80) return fail("Plan name must be 80 characters or fewer.");
|
|
140
|
+
return OK;
|
|
141
|
+
}
|
|
142
|
+
function validatePRTitle(value) {
|
|
143
|
+
const v = value.trim();
|
|
144
|
+
if (!v) return fail("Title is required.");
|
|
145
|
+
if (v.length > 256) return fail("Title must be 256 characters or fewer.");
|
|
146
|
+
return OK;
|
|
147
|
+
}
|
|
148
|
+
function validateJsonString(value, opts = {}) {
|
|
149
|
+
const v = value.trim();
|
|
150
|
+
if (!v) {
|
|
151
|
+
if (opts.allowEmpty) return OK;
|
|
152
|
+
return fail("JSON cannot be empty.");
|
|
153
|
+
}
|
|
154
|
+
let parsed;
|
|
155
|
+
try {
|
|
156
|
+
parsed = JSON.parse(v);
|
|
157
|
+
} catch (e) {
|
|
158
|
+
return fail(`Invalid JSON: ${e instanceof Error ? e.message : "parse failed"}.`);
|
|
159
|
+
}
|
|
160
|
+
const allow = opts.allowRoots ?? "any";
|
|
161
|
+
if (allow === "object" && (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))) {
|
|
162
|
+
return fail("JSON root must be an object.");
|
|
163
|
+
}
|
|
164
|
+
if (allow === "array" && !Array.isArray(parsed)) {
|
|
165
|
+
return fail("JSON root must be an array.");
|
|
166
|
+
}
|
|
167
|
+
return OK;
|
|
168
|
+
}
|
|
169
|
+
var HEADER_TOKEN_RE = /^[A-Za-z0-9!#$%&'*+\-.^_`|~]+$/;
|
|
170
|
+
function validateHttpHeaderName(value) {
|
|
171
|
+
const v = value.trim();
|
|
172
|
+
if (!v) return fail("Header name is required.");
|
|
173
|
+
if (!HEADER_TOKEN_RE.test(v)) {
|
|
174
|
+
return fail("Header name must be a valid HTTP token (letters, digits, and -_.!#$%&'*+^`|~).");
|
|
175
|
+
}
|
|
176
|
+
return OK;
|
|
177
|
+
}
|
|
178
|
+
function validateRegex(value, flags) {
|
|
179
|
+
if (value === "") return fail("Regex cannot be empty.");
|
|
180
|
+
try {
|
|
181
|
+
new RegExp(value, flags);
|
|
182
|
+
return OK;
|
|
183
|
+
} catch (e) {
|
|
184
|
+
return fail(`Invalid regex: ${e instanceof Error ? e.message : "parse failed"}.`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
var JSON_PATH_RE = /^\$(\.\.?[A-Za-z_$][\w$]*|\[(?:\*|\d+|'[^']*')\])*$/;
|
|
188
|
+
function validateJsonPath(value) {
|
|
189
|
+
const v = value.trim();
|
|
190
|
+
if (!v) return fail("JSONPath cannot be empty.");
|
|
191
|
+
if (!v.startsWith("$")) return fail('JSONPath must start with "$".');
|
|
192
|
+
if (!JSON_PATH_RE.test(v)) {
|
|
193
|
+
return fail("JSONPath syntax looks malformed \u2014 expected $.foo.bar or $.items[0].name.");
|
|
194
|
+
}
|
|
195
|
+
return OK;
|
|
196
|
+
}
|
|
197
|
+
function validatePositiveDuration(value) {
|
|
198
|
+
const n = typeof value === "string" ? Number(value) : value;
|
|
199
|
+
if (!Number.isFinite(n)) return fail("Duration must be a number.");
|
|
200
|
+
if (n < 0) return fail("Duration cannot be negative.");
|
|
201
|
+
if (!Number.isInteger(n)) return fail("Duration must be a whole number.");
|
|
202
|
+
return OK;
|
|
203
|
+
}
|
|
204
|
+
function safeExternalHref(value) {
|
|
205
|
+
if (typeof value !== "string" || value.length === 0) return null;
|
|
206
|
+
let parsed;
|
|
207
|
+
try {
|
|
208
|
+
parsed = new URL(value);
|
|
209
|
+
} catch {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return null;
|
|
213
|
+
return parsed.toString();
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// src/format.ts
|
|
217
|
+
function formatBytes(bytes) {
|
|
218
|
+
if (!Number.isFinite(bytes) || bytes < 0) return "\u2014";
|
|
219
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
220
|
+
const units = ["KB", "MB", "GB", "TB"];
|
|
221
|
+
let value = bytes / 1024;
|
|
222
|
+
let unitIdx = 0;
|
|
223
|
+
while (value >= 1024 && unitIdx < units.length - 1) {
|
|
224
|
+
value /= 1024;
|
|
225
|
+
unitIdx++;
|
|
226
|
+
}
|
|
227
|
+
return `${value.toFixed(value >= 100 ? 0 : value >= 10 ? 1 : 2)} ${units[unitIdx]}`;
|
|
228
|
+
}
|
|
229
|
+
function utf8ByteLength(s) {
|
|
230
|
+
if (typeof TextEncoder === "undefined") return s.length;
|
|
231
|
+
return new TextEncoder().encode(s).length;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// src/envPriority.ts
|
|
235
|
+
function envPriorityKey(ref) {
|
|
236
|
+
if (ref.kind === "local") return `local:${ref.name}`;
|
|
237
|
+
return `linked:${ref.linkedWorkspaceId}:${ref.envName}`;
|
|
238
|
+
}
|
|
239
|
+
function parseEnvPriorityKey(key) {
|
|
240
|
+
if (key.startsWith("local:")) {
|
|
241
|
+
return { kind: "local", name: key.slice("local:".length) };
|
|
242
|
+
}
|
|
243
|
+
if (key.startsWith("linked:")) {
|
|
244
|
+
const rest = key.slice("linked:".length);
|
|
245
|
+
const colonIdx = rest.indexOf(":");
|
|
246
|
+
if (colonIdx === -1) return null;
|
|
247
|
+
return {
|
|
248
|
+
kind: "linked",
|
|
249
|
+
linkedWorkspaceId: rest.slice(0, colonIdx),
|
|
250
|
+
envName: rest.slice(colonIdx + 1)
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
function envPriorityRefEqual(a, b) {
|
|
256
|
+
if (a.kind !== b.kind) return false;
|
|
257
|
+
if (a.kind === "local") return b.kind === "local" && a.name === b.name;
|
|
258
|
+
return b.kind === "linked" && a.linkedWorkspaceId === b.linkedWorkspaceId && a.envName === b.envName;
|
|
259
|
+
}
|
|
260
|
+
function envPriorityDisplayName(ref) {
|
|
261
|
+
return ref.kind === "local" ? ref.name : ref.envName;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// src/types.ts
|
|
265
|
+
var DEFAULT_WORKSPACE_NAME = "My Workspace";
|
|
266
|
+
var RUN_BODY_PREVIEW_LIMIT = 64 * 1024;
|
|
267
|
+
var FONT_SIZE_PERCENT_MIN = 80;
|
|
268
|
+
var FONT_SIZE_PERCENT_MAX = 150;
|
|
269
|
+
var FONT_SIZE_PERCENT_STEP = 10;
|
|
270
|
+
var FONT_SIZE_PERCENT_DEFAULT = 100;
|
|
271
|
+
|
|
272
|
+
// src/authDefaults.ts
|
|
273
|
+
var oauth2TokenDefaults = {
|
|
274
|
+
accessToken: "",
|
|
275
|
+
tokenType: "Bearer",
|
|
276
|
+
refreshToken: "",
|
|
277
|
+
expiresAt: null,
|
|
278
|
+
obtainedScope: ""
|
|
279
|
+
};
|
|
280
|
+
var FACTORIES = {
|
|
281
|
+
none: () => ({ type: "none" }),
|
|
282
|
+
inherit: () => ({ type: "inherit" }),
|
|
283
|
+
bearer: () => ({ type: "bearer", token: "" }),
|
|
284
|
+
basic: () => ({ type: "basic", username: "", password: "" }),
|
|
285
|
+
"api-key": () => ({ type: "api-key", key: "", value: "", addTo: "header" }),
|
|
286
|
+
"custom-header": () => ({ type: "custom-header", key: "", value: "" }),
|
|
287
|
+
"oauth2-client-credentials": () => ({
|
|
288
|
+
type: "oauth2-client-credentials",
|
|
289
|
+
tokenUrl: "",
|
|
290
|
+
clientId: "",
|
|
291
|
+
clientSecret: "",
|
|
292
|
+
scope: "",
|
|
293
|
+
clientAuthMethod: "header",
|
|
294
|
+
...oauth2TokenDefaults
|
|
295
|
+
}),
|
|
296
|
+
"oauth2-auth-code": () => ({
|
|
297
|
+
type: "oauth2-auth-code",
|
|
298
|
+
authUrl: "",
|
|
299
|
+
tokenUrl: "",
|
|
300
|
+
clientId: "",
|
|
301
|
+
clientSecret: "",
|
|
302
|
+
redirectUri: "",
|
|
303
|
+
scope: "",
|
|
304
|
+
state: "",
|
|
305
|
+
...oauth2TokenDefaults
|
|
306
|
+
}),
|
|
307
|
+
"oauth2-pkce": () => ({
|
|
308
|
+
type: "oauth2-pkce",
|
|
309
|
+
authUrl: "",
|
|
310
|
+
tokenUrl: "",
|
|
311
|
+
clientId: "",
|
|
312
|
+
clientSecret: "",
|
|
313
|
+
redirectUri: "",
|
|
314
|
+
scope: "",
|
|
315
|
+
state: "",
|
|
316
|
+
codeVerifier: "",
|
|
317
|
+
codeChallengeMethod: "S256",
|
|
318
|
+
...oauth2TokenDefaults
|
|
319
|
+
}),
|
|
320
|
+
"oauth2-password": () => ({
|
|
321
|
+
type: "oauth2-password",
|
|
322
|
+
tokenUrl: "",
|
|
323
|
+
clientId: "",
|
|
324
|
+
clientSecret: "",
|
|
325
|
+
username: "",
|
|
326
|
+
password: "",
|
|
327
|
+
scope: "",
|
|
328
|
+
...oauth2TokenDefaults
|
|
329
|
+
}),
|
|
330
|
+
"oauth2-implicit": () => ({
|
|
331
|
+
type: "oauth2-implicit",
|
|
332
|
+
authUrl: "",
|
|
333
|
+
clientId: "",
|
|
334
|
+
redirectUri: "",
|
|
335
|
+
scope: "",
|
|
336
|
+
accessToken: "",
|
|
337
|
+
tokenType: "Bearer",
|
|
338
|
+
expiresAt: null,
|
|
339
|
+
obtainedScope: ""
|
|
340
|
+
}),
|
|
341
|
+
"oauth2-device": () => ({
|
|
342
|
+
type: "oauth2-device",
|
|
343
|
+
deviceAuthUrl: "",
|
|
344
|
+
tokenUrl: "",
|
|
345
|
+
clientId: "",
|
|
346
|
+
scope: "",
|
|
347
|
+
deviceCode: "",
|
|
348
|
+
userCode: "",
|
|
349
|
+
verificationUri: "",
|
|
350
|
+
...oauth2TokenDefaults
|
|
351
|
+
}),
|
|
352
|
+
"aws-sigv4": () => ({
|
|
353
|
+
type: "aws-sigv4",
|
|
354
|
+
accessKeyId: "",
|
|
355
|
+
secretAccessKey: "",
|
|
356
|
+
sessionToken: "",
|
|
357
|
+
region: "us-east-1",
|
|
358
|
+
service: "",
|
|
359
|
+
addTo: "header"
|
|
360
|
+
}),
|
|
361
|
+
digest: () => ({ type: "digest", username: "", password: "" }),
|
|
362
|
+
ntlm: () => ({
|
|
363
|
+
type: "ntlm",
|
|
364
|
+
username: "",
|
|
365
|
+
password: "",
|
|
366
|
+
domain: "",
|
|
367
|
+
workstation: ""
|
|
368
|
+
}),
|
|
369
|
+
hawk: () => ({
|
|
370
|
+
type: "hawk",
|
|
371
|
+
hawkId: "",
|
|
372
|
+
hawkKey: "",
|
|
373
|
+
algorithm: "sha256",
|
|
374
|
+
ext: ""
|
|
375
|
+
}),
|
|
376
|
+
"jwt-bearer": () => ({
|
|
377
|
+
type: "jwt-bearer",
|
|
378
|
+
algorithm: "HS256",
|
|
379
|
+
secretOrKey: "",
|
|
380
|
+
payload: '{\n "sub": "user-id",\n "iat": 1700000000\n}',
|
|
381
|
+
jwtHeaders: '{\n "typ": "JWT"\n}',
|
|
382
|
+
token: ""
|
|
383
|
+
})
|
|
384
|
+
};
|
|
385
|
+
function defaultAuthFor(type) {
|
|
386
|
+
return FACTORIES[type]();
|
|
387
|
+
}
|
|
388
|
+
function normalizeAuth(input) {
|
|
389
|
+
if (input && typeof input === "object" && "type" in input && typeof input.type === "string" && input.type in FACTORIES) {
|
|
390
|
+
return input;
|
|
391
|
+
}
|
|
392
|
+
return { type: "none" };
|
|
393
|
+
}
|
|
394
|
+
var REQUEST_AUTH_TYPES = Object.keys(
|
|
395
|
+
FACTORIES
|
|
396
|
+
);
|
|
397
|
+
|
|
398
|
+
// src/mcp.ts
|
|
399
|
+
var MCP_TOOL_NAMES = [
|
|
400
|
+
"import.curl",
|
|
401
|
+
"import.openapi",
|
|
402
|
+
"import.postman",
|
|
403
|
+
"import.insomnia",
|
|
404
|
+
"import.har",
|
|
405
|
+
"generate.code",
|
|
406
|
+
"workspace.read",
|
|
407
|
+
"workspace.write",
|
|
408
|
+
"request.create",
|
|
409
|
+
"request.read",
|
|
410
|
+
"request.update",
|
|
411
|
+
"request.delete",
|
|
412
|
+
"folder.create",
|
|
413
|
+
"folder.read",
|
|
414
|
+
"folder.update",
|
|
415
|
+
"folder.delete",
|
|
416
|
+
"environment.create",
|
|
417
|
+
"environment.read",
|
|
418
|
+
"environment.update",
|
|
419
|
+
"environment.delete",
|
|
420
|
+
"environment.set_active",
|
|
421
|
+
"environment.set_priority",
|
|
422
|
+
"environment.export",
|
|
423
|
+
"environment.import",
|
|
424
|
+
"plan.create",
|
|
425
|
+
"plan.run",
|
|
426
|
+
"plan.read",
|
|
427
|
+
"plan.update",
|
|
428
|
+
"plan.delete",
|
|
429
|
+
"plan.add_step",
|
|
430
|
+
"plan.remove_step",
|
|
431
|
+
"plan.reorder_steps",
|
|
432
|
+
"plan.set_variables",
|
|
433
|
+
"assertion.create",
|
|
434
|
+
"assertion.read",
|
|
435
|
+
"assertion.update",
|
|
436
|
+
"assertion.delete",
|
|
437
|
+
"history.list_runs",
|
|
438
|
+
"history.get_run",
|
|
439
|
+
"history.delete_run",
|
|
440
|
+
"history.purge_by_age",
|
|
441
|
+
"codebase.extract_collection",
|
|
442
|
+
"prompt.create_environment",
|
|
443
|
+
"prompt.create_assertion",
|
|
444
|
+
"prompt.create_plan",
|
|
445
|
+
"prompt.create_request",
|
|
446
|
+
"prompt.update_request",
|
|
447
|
+
"prompt.create_folder_tree",
|
|
448
|
+
"prompt.add_plan_steps",
|
|
449
|
+
"prompt.set_plan_variables",
|
|
450
|
+
"prompt.create_mock_server",
|
|
451
|
+
"prompt.add_mock_endpoint",
|
|
452
|
+
"prompt.set_endpoint_validation_rules",
|
|
453
|
+
"prompt.set_endpoint_response_rules",
|
|
454
|
+
"prompt.set_endpoint_multipliers",
|
|
455
|
+
"mock.create_from_openapi",
|
|
456
|
+
"mock.create_from_postman",
|
|
457
|
+
"mock.create_from_insomnia",
|
|
458
|
+
"mock.create_manual",
|
|
459
|
+
"mock.list",
|
|
460
|
+
"mock.list_endpoints",
|
|
461
|
+
"mock.start",
|
|
462
|
+
"mock.stop",
|
|
463
|
+
"mock.delete",
|
|
464
|
+
"mock.add_endpoint",
|
|
465
|
+
"mock.update_endpoint",
|
|
466
|
+
"mock.delete_endpoint",
|
|
467
|
+
"mock.set_validation_rules",
|
|
468
|
+
"mock.set_response_rules",
|
|
469
|
+
"mock.set_multipliers",
|
|
470
|
+
"mock.import_postman_mock_collection"
|
|
471
|
+
];
|
|
472
|
+
|
|
473
|
+
// src/mock.ts
|
|
474
|
+
var NO_BODY_STATUSES = /* @__PURE__ */ new Set([100, 101, 102, 103, 204, 205, 304]);
|
|
475
|
+
function getAllowedMockResponseBodyTypes(status) {
|
|
476
|
+
if (NO_BODY_STATUSES.has(status)) return ["none"];
|
|
477
|
+
if (status === 200) {
|
|
478
|
+
return ["none", "json", "text", "xml", "urlencoded", "form-data", "binary"];
|
|
479
|
+
}
|
|
480
|
+
return ["none", "json", "text", "xml", "urlencoded", "form-data"];
|
|
481
|
+
}
|
|
482
|
+
function coerceMockResponseBodyTypeForStatus(currentBodyType, status) {
|
|
483
|
+
const allowed = getAllowedMockResponseBodyTypes(status);
|
|
484
|
+
if (allowed.includes(currentBodyType)) return null;
|
|
485
|
+
if (allowed.includes("json")) return "json";
|
|
486
|
+
return "none";
|
|
487
|
+
}
|
|
488
|
+
function makeDefaultMockResponseBody(type) {
|
|
489
|
+
switch (type) {
|
|
490
|
+
case "none":
|
|
491
|
+
return { type: "none", content: "" };
|
|
492
|
+
case "form-data":
|
|
493
|
+
return { type: "form-data", content: "", formRows: [] };
|
|
494
|
+
case "binary":
|
|
495
|
+
return { type: "binary", content: "" };
|
|
496
|
+
default:
|
|
497
|
+
return { type, content: "" };
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
function makeDefaultMockResponse() {
|
|
501
|
+
return {
|
|
502
|
+
status: 200,
|
|
503
|
+
headers: [{ key: "Content-Type", value: "application/json", enabled: true }],
|
|
504
|
+
body: { type: "json", content: '{\n "ok": true\n}' }
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
function makeDefaultRequestSchema() {
|
|
508
|
+
return { pathParams: [], queryParams: [], headers: [], cookies: [] };
|
|
509
|
+
}
|
|
510
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
511
|
+
0 && (module.exports = {
|
|
512
|
+
DEFAULT_WORKSPACE_NAME,
|
|
513
|
+
FONT_SIZE_PERCENT_DEFAULT,
|
|
514
|
+
FONT_SIZE_PERCENT_MAX,
|
|
515
|
+
FONT_SIZE_PERCENT_MIN,
|
|
516
|
+
FONT_SIZE_PERCENT_STEP,
|
|
517
|
+
MCP_TOOL_NAMES,
|
|
518
|
+
REQUEST_AUTH_TYPES,
|
|
519
|
+
RUN_BODY_PREVIEW_LIMIT,
|
|
520
|
+
coerceMockResponseBodyTypeForStatus,
|
|
521
|
+
defaultAuthFor,
|
|
522
|
+
envPriorityDisplayName,
|
|
523
|
+
envPriorityKey,
|
|
524
|
+
envPriorityRefEqual,
|
|
525
|
+
formatBytes,
|
|
526
|
+
generateId,
|
|
527
|
+
getAllowedMockResponseBodyTypes,
|
|
528
|
+
makeDefaultMockResponse,
|
|
529
|
+
makeDefaultMockResponseBody,
|
|
530
|
+
makeDefaultRequestSchema,
|
|
531
|
+
normalizeAuth,
|
|
532
|
+
parseEnvPriorityKey,
|
|
533
|
+
safeExternalHref,
|
|
534
|
+
utf8ByteLength,
|
|
535
|
+
validateAwsRegion,
|
|
536
|
+
validateEnvVarName,
|
|
537
|
+
validateHttpHeaderName,
|
|
538
|
+
validateJsonPath,
|
|
539
|
+
validateJsonString,
|
|
540
|
+
validateMockPath,
|
|
541
|
+
validatePRTitle,
|
|
542
|
+
validatePlanName,
|
|
543
|
+
validatePositiveDuration,
|
|
544
|
+
validateRegex,
|
|
545
|
+
validateUrl
|
|
546
|
+
});
|
|
547
|
+
//# sourceMappingURL=index.cjs.map
|