@getexception/cli 0.1.23 → 0.1.25
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/README.md +56 -48
- package/dist/index.js +488 -69
- package/dist/integration.d.ts +44 -4
- package/dist/integration.js +215 -35
- package/package.json +2 -2
package/dist/integration.d.ts
CHANGED
|
@@ -31,10 +31,10 @@ declare function validateGitLabContext(value: unknown, env: NodeJS.ProcessEnv, o
|
|
|
31
31
|
release: string;
|
|
32
32
|
assetPrefix: string;
|
|
33
33
|
deployment: {
|
|
34
|
-
environment:
|
|
34
|
+
environment: string;
|
|
35
35
|
review?: {
|
|
36
|
-
provider: "gitlab";
|
|
37
|
-
repositoryId: number;
|
|
36
|
+
provider: "gitlab" | "github" | "other";
|
|
37
|
+
repositoryId: string | number;
|
|
38
38
|
number: number;
|
|
39
39
|
} | undefined;
|
|
40
40
|
};
|
|
@@ -60,4 +60,44 @@ declare function assertPublicOutput(root: string, options?: {
|
|
|
60
60
|
mapsEnabled?: boolean;
|
|
61
61
|
}): Promise<void>;
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
type PrepareSourceMapsOptions = {
|
|
64
|
+
directory: string;
|
|
65
|
+
output: string;
|
|
66
|
+
release: string;
|
|
67
|
+
buildId: string;
|
|
68
|
+
urlPrefix?: string;
|
|
69
|
+
format?: "esm" | "classic";
|
|
70
|
+
credentials?: string[];
|
|
71
|
+
signal?: AbortSignal;
|
|
72
|
+
};
|
|
73
|
+
declare function prepareSourceMaps(options: PrepareSourceMapsOptions): Promise<{
|
|
74
|
+
directory: string;
|
|
75
|
+
release: string;
|
|
76
|
+
buildId: string;
|
|
77
|
+
}>;
|
|
78
|
+
type SourceMapDeliveryOptions = {
|
|
79
|
+
directory: string;
|
|
80
|
+
url: string;
|
|
81
|
+
projectId: string;
|
|
82
|
+
token: string | undefined;
|
|
83
|
+
environment: string;
|
|
84
|
+
timeoutMs?: number;
|
|
85
|
+
signal?: AbortSignal;
|
|
86
|
+
};
|
|
87
|
+
declare function uploadSourceMaps(options: SourceMapDeliveryOptions, transport?: typeof fetch): Promise<{
|
|
88
|
+
status: "ready";
|
|
89
|
+
batches: number;
|
|
90
|
+
diagnostic?: undefined;
|
|
91
|
+
} | {
|
|
92
|
+
status: "unavailable";
|
|
93
|
+
diagnostic: string;
|
|
94
|
+
batches?: undefined;
|
|
95
|
+
}>;
|
|
96
|
+
|
|
97
|
+
type CiCredential = string | {
|
|
98
|
+
gitlabIdToken: string;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
declare function registerRelease(address: string, project: string, token: CiCredential, value: unknown, transport?: typeof fetch): Promise<void>;
|
|
102
|
+
|
|
103
|
+
export { type GitLabDeploymentOptions, type GitLabDeploymentResult, type PrepareSourceMapsOptions, type SourceMapDeliveryOptions, assertPublicOutput, deployWithGetException, prepareSourceMaps, registerRelease, uploadSourceMaps, validateGitLabContext };
|
package/dist/integration.js
CHANGED
|
@@ -1820,18 +1820,18 @@ var validateAsync = async (schema, value, _ctx) => {
|
|
|
1820
1820
|
return result.issues.length === 0;
|
|
1821
1821
|
};
|
|
1822
1822
|
var _encode = (_Err) => {
|
|
1823
|
-
const
|
|
1823
|
+
const parse5 = _parse(_Err);
|
|
1824
1824
|
const fn = (schema, value, _ctx, _params) => {
|
|
1825
1825
|
const ctx = _ctx ? { ..._ctx, direction: "backward" } : { direction: "backward" };
|
|
1826
|
-
return
|
|
1826
|
+
return parse5(schema, value, ctx, finalizeParams(fn, _params));
|
|
1827
1827
|
};
|
|
1828
1828
|
return fn;
|
|
1829
1829
|
};
|
|
1830
1830
|
var encode = /* @__PURE__ */ _encode($ZodRealError);
|
|
1831
1831
|
var _decode = (_Err) => {
|
|
1832
|
-
const
|
|
1832
|
+
const parse5 = _parse(_Err);
|
|
1833
1833
|
const fn = (schema, value, _ctx, _params) => {
|
|
1834
|
-
return
|
|
1834
|
+
return parse5(schema, value, _ctx, finalizeParams(fn, _params));
|
|
1835
1835
|
};
|
|
1836
1836
|
return fn;
|
|
1837
1837
|
};
|
|
@@ -18885,7 +18885,12 @@ var SOURCE_MAP_LIMITS = {
|
|
|
18885
18885
|
diskReserveBytes: 5 * 1024 * 1024 * 1024,
|
|
18886
18886
|
manifestBytes: 64 * 1024
|
|
18887
18887
|
};
|
|
18888
|
-
var releaseNameSchema = external_exports.string().regex(/^[
|
|
18888
|
+
var releaseNameSchema = external_exports.string().max(160).regex(/^[A-Za-z0-9][A-Za-z0-9._+-]*(?:@[A-Za-z0-9][A-Za-z0-9._+-]*)?$/).refine((value) => !/^[^@]+@[a-zA-Z][^@]*\.[a-zA-Z]{2,}$/.test(value));
|
|
18889
|
+
var environmentNameSchema = external_exports.string().max(64).regex(/^[a-z][a-z0-9_-]{0,63}$/).refine(
|
|
18890
|
+
(value) => !["all", "constructor", "prototype", "__proto__"].includes(value)
|
|
18891
|
+
);
|
|
18892
|
+
var buildIdSchema = external_exports.string().max(64).regex(/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/);
|
|
18893
|
+
var environmentListSchema = external_exports.array(environmentNameSchema).max(20).refine((values) => new Set(values).size === values.length);
|
|
18889
18894
|
var artifactPathSchema = external_exports.string().max(512).regex(/^[a-zA-Z0-9_@~.-]+(?:\/[a-zA-Z0-9_@~.-]+)*\.(?:js|mjs)$/).refine(
|
|
18890
18895
|
(value) => !value.split("/").some((part) => part === "." || part === "..")
|
|
18891
18896
|
);
|
|
@@ -18897,9 +18902,13 @@ var sourceArtifactSchema = external_exports.object({
|
|
|
18897
18902
|
}).strict();
|
|
18898
18903
|
var sourceUploadSchema = external_exports.object({
|
|
18899
18904
|
release: releaseNameSchema,
|
|
18905
|
+
environment: environmentNameSchema.optional(),
|
|
18906
|
+
buildId: buildIdSchema.optional(),
|
|
18907
|
+
batchIndex: external_exports.number().int().min(0).max(4095).optional(),
|
|
18908
|
+
batchCount: external_exports.number().int().min(1).max(4096).optional(),
|
|
18900
18909
|
artifacts: external_exports.array(sourceArtifactSchema).min(1).max(SOURCE_MAP_LIMITS.files)
|
|
18901
18910
|
}).strict().superRefine((value, ctx) => {
|
|
18902
|
-
if (value.artifacts.reduce((sum, file2) => sum + file2.size, 0) > SOURCE_MAP_LIMITS.releaseBytes || new Set(value.artifacts.map((file2) => file2.path)).size !== value.artifacts.length || new Set(value.artifacts.map((file2) => file2.debugId)).size !== value.artifacts.length) {
|
|
18911
|
+
if ((value.batchIndex !== void 0 || value.batchCount !== void 0) && (value.batchIndex === void 0 || value.batchCount === void 0 || value.batchIndex >= value.batchCount) || value.artifacts.reduce((sum, file2) => sum + file2.size, 0) > SOURCE_MAP_LIMITS.releaseBytes || new Set(value.artifacts.map((file2) => file2.path)).size !== value.artifacts.length || new Set(value.artifacts.map((file2) => file2.debugId)).size !== value.artifacts.length) {
|
|
18903
18912
|
ctx.addIssue({ code: "custom", message: "Invalid artifact manifest" });
|
|
18904
18913
|
}
|
|
18905
18914
|
});
|
|
@@ -18924,20 +18933,18 @@ function sanitizeAppVersion(value) {
|
|
|
18924
18933
|
const parsed = appVersionSchema.safeParse(value);
|
|
18925
18934
|
return parsed.success ? parsed.data : void 0;
|
|
18926
18935
|
}
|
|
18927
|
-
var RELEASE_ENVIRONMENTS = [
|
|
18928
|
-
"production",
|
|
18929
|
-
"staging",
|
|
18930
|
-
"development"
|
|
18931
|
-
];
|
|
18932
18936
|
var deploymentSchema = external_exports.object({
|
|
18933
|
-
environment:
|
|
18937
|
+
environment: environmentNameSchema,
|
|
18934
18938
|
review: external_exports.object({
|
|
18935
|
-
provider: external_exports.
|
|
18936
|
-
repositoryId: external_exports.
|
|
18939
|
+
provider: external_exports.enum(["gitlab", "github", "other"]),
|
|
18940
|
+
repositoryId: external_exports.union([
|
|
18941
|
+
external_exports.number().int().min(1).max(2147483647),
|
|
18942
|
+
external_exports.string().max(200).regex(/^[A-Za-z0-9_.-]+(?:\/[A-Za-z0-9_.-]+)+$/)
|
|
18943
|
+
]),
|
|
18937
18944
|
number: external_exports.number().int().min(1).max(2147483647)
|
|
18938
18945
|
}).strict().optional()
|
|
18939
|
-
}).strict().refine((value) => !value.review || value.environment
|
|
18940
|
-
message: "
|
|
18946
|
+
}).strict().refine((value) => !value.review || value.environment !== "production", {
|
|
18947
|
+
message: "Reviews belong to non-production environments"
|
|
18941
18948
|
});
|
|
18942
18949
|
var releaseRegistrationSchema = external_exports.object({
|
|
18943
18950
|
release: releaseNameSchema,
|
|
@@ -19061,7 +19068,7 @@ var safeEventSchema = external_exports.object({
|
|
|
19061
19068
|
message: external_exports.string().max(1024),
|
|
19062
19069
|
exceptionType: external_exports.string().max(120),
|
|
19063
19070
|
handled: external_exports.boolean(),
|
|
19064
|
-
environment:
|
|
19071
|
+
environment: environmentNameSchema,
|
|
19065
19072
|
release: external_exports.string().max(160).optional(),
|
|
19066
19073
|
appVersion: appVersionSchema.optional(),
|
|
19067
19074
|
dist: external_exports.string().max(64).optional(),
|
|
@@ -19088,7 +19095,13 @@ var codeSchema = external_exports.enum([
|
|
|
19088
19095
|
"HTTP_ERROR",
|
|
19089
19096
|
"CONTRACT_JSON",
|
|
19090
19097
|
"CONTRACT_RESPONSE",
|
|
19091
|
-
"COMMAND_FAILED"
|
|
19098
|
+
"COMMAND_FAILED",
|
|
19099
|
+
"ENVIRONMENT_FORBIDDEN",
|
|
19100
|
+
"BUILD_CONFLICT",
|
|
19101
|
+
"INVALID_UPLOAD",
|
|
19102
|
+
"STORAGE_FULL",
|
|
19103
|
+
"RATE_LIMITED",
|
|
19104
|
+
"UPLOAD_UNAVAILABLE"
|
|
19092
19105
|
]);
|
|
19093
19106
|
var diagnosticSchema = external_exports.object({
|
|
19094
19107
|
version: external_exports.literal(1),
|
|
@@ -19107,6 +19120,17 @@ var CliError = class extends Error {
|
|
|
19107
19120
|
httpStatus;
|
|
19108
19121
|
requestId;
|
|
19109
19122
|
};
|
|
19123
|
+
function formatDiagnostic(error61) {
|
|
19124
|
+
const safe = diagnosticSchema.safeParse({
|
|
19125
|
+
version: 1,
|
|
19126
|
+
code: error61 instanceof CliError ? error61.code : "COMMAND_FAILED",
|
|
19127
|
+
...error61 instanceof CliError ? { httpStatus: error61.httpStatus, requestId: error61.requestId } : {}
|
|
19128
|
+
});
|
|
19129
|
+
return `GETEXCEPTION_DIAGNOSTIC ${JSON.stringify(
|
|
19130
|
+
safe.success ? safe.data : { version: 1, code: "COMMAND_FAILED" }
|
|
19131
|
+
)}
|
|
19132
|
+
`;
|
|
19133
|
+
}
|
|
19110
19134
|
function networkError(error61, httpStatus) {
|
|
19111
19135
|
let current = error61;
|
|
19112
19136
|
for (let depth = 0; depth < 4 && current instanceof Error; depth++) {
|
|
@@ -19159,6 +19183,17 @@ function authorizationHeader(credential) {
|
|
|
19159
19183
|
}
|
|
19160
19184
|
|
|
19161
19185
|
// packages/cli/src/api-response.ts
|
|
19186
|
+
var uploadFailureSchema = external_exports.object({
|
|
19187
|
+
code: external_exports.enum([
|
|
19188
|
+
"ENVIRONMENT_FORBIDDEN",
|
|
19189
|
+
"BUILD_CONFLICT",
|
|
19190
|
+
"INVALID_UPLOAD",
|
|
19191
|
+
"STORAGE_FULL",
|
|
19192
|
+
"RATE_LIMITED",
|
|
19193
|
+
"UPLOAD_UNAVAILABLE"
|
|
19194
|
+
]),
|
|
19195
|
+
requestId: external_exports.string().uuid()
|
|
19196
|
+
});
|
|
19162
19197
|
async function responseJson(response) {
|
|
19163
19198
|
const reader = response.body?.getReader();
|
|
19164
19199
|
const chunks = [];
|
|
@@ -19208,6 +19243,14 @@ async function httpError(response) {
|
|
|
19208
19243
|
result.data.requestId
|
|
19209
19244
|
);
|
|
19210
19245
|
}
|
|
19246
|
+
const upload = uploadFailureSchema.safeParse(candidate);
|
|
19247
|
+
if (upload.success) {
|
|
19248
|
+
return new CliError(
|
|
19249
|
+
upload.data.code,
|
|
19250
|
+
response.status,
|
|
19251
|
+
upload.data.requestId
|
|
19252
|
+
);
|
|
19253
|
+
}
|
|
19211
19254
|
}
|
|
19212
19255
|
} catch {
|
|
19213
19256
|
}
|
|
@@ -19242,6 +19285,9 @@ function projectApi(address, project, token, transport = fetch, options = {}) {
|
|
|
19242
19285
|
const requestTimeout = options.requestTimeoutMs ?? 3e4;
|
|
19243
19286
|
return async function request(path, method = "GET", body, contentEncoding) {
|
|
19244
19287
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
19288
|
+
if (options.signal?.aborted) {
|
|
19289
|
+
throw new CliError("NETWORK_TIMEOUT");
|
|
19290
|
+
}
|
|
19245
19291
|
if (Date.now() >= deadline) {
|
|
19246
19292
|
throw new CliError("NETWORK_TIMEOUT");
|
|
19247
19293
|
}
|
|
@@ -19257,14 +19303,21 @@ function projectApi(address, project, token, transport = fetch, options = {}) {
|
|
|
19257
19303
|
body,
|
|
19258
19304
|
redirect: "error",
|
|
19259
19305
|
credentials: "omit",
|
|
19260
|
-
signal: AbortSignal.
|
|
19261
|
-
|
|
19262
|
-
|
|
19306
|
+
signal: AbortSignal.any([
|
|
19307
|
+
AbortSignal.timeout(
|
|
19308
|
+
Math.min(requestTimeout, deadline - Date.now())
|
|
19309
|
+
),
|
|
19310
|
+
...options.signal ? [options.signal] : []
|
|
19311
|
+
])
|
|
19263
19312
|
});
|
|
19264
19313
|
} catch (error61) {
|
|
19265
19314
|
const failure = networkError(error61);
|
|
19266
19315
|
if (retryableNetworkError(failure) && attempt < 2) {
|
|
19267
|
-
await delay(
|
|
19316
|
+
await delay(
|
|
19317
|
+
Math.min(1e3 * 2 ** attempt, Math.max(1, deadline - Date.now())),
|
|
19318
|
+
void 0,
|
|
19319
|
+
{ signal: options.signal }
|
|
19320
|
+
);
|
|
19268
19321
|
continue;
|
|
19269
19322
|
}
|
|
19270
19323
|
throw failure;
|
|
@@ -19274,7 +19327,11 @@ function projectApi(address, project, token, transport = fetch, options = {}) {
|
|
|
19274
19327
|
}
|
|
19275
19328
|
if ((response.status === 429 || response.status >= 500) && attempt < 2) {
|
|
19276
19329
|
await response.body?.cancel().catch(() => void 0);
|
|
19277
|
-
await delay(
|
|
19330
|
+
await delay(
|
|
19331
|
+
Math.min(1e3 * 2 ** attempt, Math.max(1, deadline - Date.now())),
|
|
19332
|
+
void 0,
|
|
19333
|
+
{ signal: options.signal }
|
|
19334
|
+
);
|
|
19278
19335
|
continue;
|
|
19279
19336
|
}
|
|
19280
19337
|
throw await httpError(response);
|
|
@@ -19314,6 +19371,7 @@ import { dirname as dirname2, join as join3, relative as relative3 } from "path"
|
|
|
19314
19371
|
|
|
19315
19372
|
// packages/cli/src/prepare.ts
|
|
19316
19373
|
import { createHash, randomUUID } from "crypto";
|
|
19374
|
+
import { parse as parse3 } from "acorn";
|
|
19317
19375
|
import {
|
|
19318
19376
|
lstat,
|
|
19319
19377
|
mkdir,
|
|
@@ -19359,7 +19417,7 @@ async function files(root, directory = root, result = []) {
|
|
|
19359
19417
|
}
|
|
19360
19418
|
return result;
|
|
19361
19419
|
}
|
|
19362
|
-
async function prepareMaps(directory, output2, release, prefix = "") {
|
|
19420
|
+
async function prepareMaps(directory, output2, release, prefix = "", options = {}) {
|
|
19363
19421
|
const root = await realpath(directory);
|
|
19364
19422
|
const destination = join(
|
|
19365
19423
|
await realpath(dirname(resolve(output2))),
|
|
@@ -19367,6 +19425,9 @@ async function prepareMaps(directory, output2, release, prefix = "") {
|
|
|
19367
19425
|
);
|
|
19368
19426
|
const child = relative(root, destination);
|
|
19369
19427
|
releaseNameSchema.parse(release);
|
|
19428
|
+
if (options.buildId) {
|
|
19429
|
+
buildIdSchema.parse(options.buildId);
|
|
19430
|
+
}
|
|
19370
19431
|
if (!child || !isAbsolute(child) && child !== ".." && !child.startsWith(`..${sep}`)) {
|
|
19371
19432
|
throw new Error(
|
|
19372
19433
|
"Private artifacts must be outside the public build directory"
|
|
@@ -19392,7 +19453,7 @@ async function prepareMaps(directory, output2, release, prefix = "") {
|
|
|
19392
19453
|
(await regular(join(root, mapPath), SOURCE_MAP_LIMITS.fileBytes)).toString("utf8")
|
|
19393
19454
|
);
|
|
19394
19455
|
const source = (await regular(join(root, jsPath), SOURCE_MAP_LIMITS.fileBytes)).toString("utf8");
|
|
19395
|
-
if (map2.version !== 3 || typeof map2.mappings !== "string" || map2.sections || map2.debug_id || source.startsWith(
|
|
19456
|
+
if (map2.version !== 3 || typeof map2.mappings !== "string" || map2.sections || map2.debug_id || source.startsWith("#!") || source.startsWith(
|
|
19396
19457
|
";(globalThis.__GETEXCEPTION_DEBUG_IDS__??=Object.create(null))"
|
|
19397
19458
|
)) {
|
|
19398
19459
|
throw new Error("Expected a fresh, non-indexed v3 source map");
|
|
@@ -19417,12 +19478,29 @@ async function prepareMaps(directory, output2, release, prefix = "") {
|
|
|
19417
19478
|
/(?:^|\n)[ \t]*(?:\/\/[#@][ \t]*sourceMappingURL=[^\r\n]*|\/\*[#@][ \t]*sourceMappingURL=[^\r\n]*?\*\/)[ \t]*(?:\r?\n)?$/,
|
|
19418
19479
|
(comment) => comment.replace(/[^\r\n]/g, " ")
|
|
19419
19480
|
);
|
|
19420
|
-
const
|
|
19481
|
+
const directives = [];
|
|
19482
|
+
if (options.format === "classic") {
|
|
19483
|
+
const program = parse3(source, {
|
|
19484
|
+
ecmaVersion: "latest",
|
|
19485
|
+
sourceType: "script"
|
|
19486
|
+
});
|
|
19487
|
+
for (const statement of program.body) {
|
|
19488
|
+
if (!("directive" in statement) || typeof statement.directive !== "string") {
|
|
19489
|
+
break;
|
|
19490
|
+
}
|
|
19491
|
+
directives.push(statement.directive);
|
|
19492
|
+
}
|
|
19493
|
+
}
|
|
19494
|
+
const injection = options.format === "classic" ? `${directives.map((value) => JSON.stringify(value) + ";").join("")};(()=>{const s=typeof document!=="undefined"?document.currentScript?.src:undefined;if(s)(globalThis.__GETEXCEPTION_DEBUG_IDS__??=Object.create(null))[s]=${JSON.stringify(debugId)};})();` : `;(globalThis.__GETEXCEPTION_DEBUG_IDS__??=Object.create(null))[import.meta.url]=${JSON.stringify(debugId)};`;
|
|
19495
|
+
const js = `${injection}
|
|
19421
19496
|
${body}`;
|
|
19422
19497
|
prepared.push({ mapPath, jsPath, bytes, js, entry });
|
|
19423
19498
|
}
|
|
19424
19499
|
const manifest = sourceUploadSchema.parse({
|
|
19425
19500
|
release,
|
|
19501
|
+
...options.buildId ? { buildId: options.buildId } : {},
|
|
19502
|
+
...options.environment ? { environment: options.environment } : {},
|
|
19503
|
+
...options.batchIndex !== void 0 ? { batchIndex: options.batchIndex, batchCount: options.batchCount } : {},
|
|
19426
19504
|
artifacts: prepared.map((item) => item.entry)
|
|
19427
19505
|
});
|
|
19428
19506
|
await mkdir(destination, { mode: 448 });
|
|
@@ -19472,7 +19550,7 @@ import { lstat as lstat2, readFile as readFile2, readdir as readdir2 } from "fs/
|
|
|
19472
19550
|
import { basename as basename2, extname, join as join2, relative as relative2, sep as sep2 } from "path";
|
|
19473
19551
|
import { brotliDecompress, gunzip } from "zlib";
|
|
19474
19552
|
import { promisify } from "util";
|
|
19475
|
-
import { parse as
|
|
19553
|
+
import { parse as parse4 } from "acorn";
|
|
19476
19554
|
import postcss from "postcss";
|
|
19477
19555
|
var gunzipAsync = promisify(gunzip);
|
|
19478
19556
|
var brotliAsync = promisify(brotliDecompress);
|
|
@@ -19512,7 +19590,7 @@ function hasInlineMap(source, extension) {
|
|
|
19512
19590
|
return found2;
|
|
19513
19591
|
}
|
|
19514
19592
|
let found = false;
|
|
19515
|
-
|
|
19593
|
+
parse4(source, {
|
|
19516
19594
|
ecmaVersion: "latest",
|
|
19517
19595
|
sourceType: extension === ".cjs" ? "script" : "module",
|
|
19518
19596
|
onComment: (_block, comment) => {
|
|
@@ -19568,7 +19646,7 @@ async function assertPublicOutput(root, options = {}) {
|
|
|
19568
19646
|
|
|
19569
19647
|
// packages/cli/src/prepare-build.ts
|
|
19570
19648
|
var maxBuildMaps = 4096;
|
|
19571
|
-
async function prepareBuild(output2, privateRoot, release, signal = AbortSignal.timeout(5 * 6e4)) {
|
|
19649
|
+
async function prepareBuild(output2, privateRoot, release, signal = AbortSignal.timeout(5 * 6e4), options = {}) {
|
|
19572
19650
|
signal.throwIfAborted();
|
|
19573
19651
|
const paths = await listPublicFiles(output2);
|
|
19574
19652
|
const maps = paths.filter((file2) => /\.(?:m?js)\.map$/i.test(file2)).sort();
|
|
@@ -19618,7 +19696,10 @@ async function prepareBuild(output2, privateRoot, release, signal = AbortSignal.
|
|
|
19618
19696
|
await copyFile(file2, copy);
|
|
19619
19697
|
}
|
|
19620
19698
|
}
|
|
19621
|
-
await prepareMaps(staging, destination, release
|
|
19699
|
+
await prepareMaps(staging, destination, release, options.urlPrefix, {
|
|
19700
|
+
...options,
|
|
19701
|
+
...options.buildId ? { batchIndex: index, batchCount: batches.length } : {}
|
|
19702
|
+
});
|
|
19622
19703
|
signal.throwIfAborted();
|
|
19623
19704
|
for (const map2 of batch) {
|
|
19624
19705
|
const js = map2.slice(0, -4);
|
|
@@ -19676,11 +19757,16 @@ var receiptSchema = external_exports.object({
|
|
|
19676
19757
|
var uploadConcurrency = 8;
|
|
19677
19758
|
var uploadDeadlineMs = 20 * 6e4;
|
|
19678
19759
|
var gzipAsync = promisify2(gzip);
|
|
19679
|
-
async function uploadMaps(directory, address, project, token, transport = fetch) {
|
|
19680
|
-
const
|
|
19760
|
+
async function uploadMaps(directory, address, project, token, transport = fetch, options = {}) {
|
|
19761
|
+
const prepared = await readPrepared(directory);
|
|
19762
|
+
const manifest = sourceUploadSchema.parse({
|
|
19763
|
+
...prepared,
|
|
19764
|
+
...options.environment ? { environment: options.environment } : {}
|
|
19765
|
+
});
|
|
19681
19766
|
const api = projectApi(address, project, token, transport, {
|
|
19682
|
-
deadlineMs: uploadDeadlineMs,
|
|
19683
|
-
requestTimeoutMs: 6e4
|
|
19767
|
+
deadlineMs: options.deadlineMs ?? uploadDeadlineMs,
|
|
19768
|
+
requestTimeoutMs: 6e4,
|
|
19769
|
+
signal: options.signal
|
|
19684
19770
|
});
|
|
19685
19771
|
const request = (path, method = "GET", body, contentEncoding) => api("/source-maps" + path, method, body, contentEncoding);
|
|
19686
19772
|
const receipt = receiptSchema.parse(
|
|
@@ -19728,7 +19814,7 @@ async function uploadMaps(directory, address, project, token, transport = fetch)
|
|
|
19728
19814
|
if (result.status === "failed") {
|
|
19729
19815
|
throw new Error("Source map validation failed; rebuild the artifacts");
|
|
19730
19816
|
}
|
|
19731
|
-
await delay2(1e3);
|
|
19817
|
+
await delay2(1e3, void 0, { signal: options.signal });
|
|
19732
19818
|
}
|
|
19733
19819
|
}
|
|
19734
19820
|
|
|
@@ -19936,8 +20022,102 @@ async function deployWithGetException(options) {
|
|
|
19936
20022
|
}
|
|
19937
20023
|
}
|
|
19938
20024
|
}
|
|
20025
|
+
|
|
20026
|
+
// packages/cli/src/source-map-delivery.ts
|
|
20027
|
+
import { mkdir as mkdir3, realpath as realpath2, readdir as readdir4, rm as rm3 } from "fs/promises";
|
|
20028
|
+
import { dirname as dirname3, resolve as resolve2, relative as relative4, isAbsolute as isAbsolute2, sep as sep3, join as join5 } from "path";
|
|
20029
|
+
async function prepareSourceMaps(options) {
|
|
20030
|
+
releaseNameSchema.parse(options.release);
|
|
20031
|
+
buildIdSchema.parse(options.buildId);
|
|
20032
|
+
const directory = await realpath2(options.directory);
|
|
20033
|
+
const target = resolve2(options.output);
|
|
20034
|
+
const output2 = join5(
|
|
20035
|
+
await realpath2(dirname3(target)),
|
|
20036
|
+
target.slice(dirname3(target).length + 1)
|
|
20037
|
+
);
|
|
20038
|
+
const child = relative4(directory, output2);
|
|
20039
|
+
if (!child || !isAbsolute2(child) && child !== ".." && !child.startsWith(`..${sep3}`)) {
|
|
20040
|
+
throw new CliError("CLI_CONFIGURATION");
|
|
20041
|
+
}
|
|
20042
|
+
await mkdir3(output2, { mode: 448 });
|
|
20043
|
+
try {
|
|
20044
|
+
const maps = await prepareBuild(
|
|
20045
|
+
directory,
|
|
20046
|
+
output2,
|
|
20047
|
+
options.release,
|
|
20048
|
+
options.signal,
|
|
20049
|
+
options
|
|
20050
|
+
);
|
|
20051
|
+
await assertPublicOutput(directory, {
|
|
20052
|
+
mapsEnabled: true,
|
|
20053
|
+
credentials: options.credentials
|
|
20054
|
+
});
|
|
20055
|
+
await rm3(join5(output2, "work"), { recursive: true });
|
|
20056
|
+
return {
|
|
20057
|
+
directory: maps,
|
|
20058
|
+
release: options.release,
|
|
20059
|
+
buildId: options.buildId
|
|
20060
|
+
};
|
|
20061
|
+
} catch (error61) {
|
|
20062
|
+
await rm3(output2, { recursive: true, force: true });
|
|
20063
|
+
throw error61;
|
|
20064
|
+
}
|
|
20065
|
+
}
|
|
20066
|
+
async function uploadSourceMaps(options, transport = fetch) {
|
|
20067
|
+
try {
|
|
20068
|
+
options.signal?.throwIfAborted();
|
|
20069
|
+
if (typeof options.token !== "string") {
|
|
20070
|
+
throw new CliError("CLI_CONFIGURATION");
|
|
20071
|
+
}
|
|
20072
|
+
authorizationHeader(options.token);
|
|
20073
|
+
const environment = environmentNameSchema.parse(options.environment);
|
|
20074
|
+
const budget = options.timeoutMs ?? 30 * 6e4;
|
|
20075
|
+
if (!Number.isInteger(budget) || budget < 1e3 || budget > 60 * 6e4) {
|
|
20076
|
+
throw new CliError("CLI_CONFIGURATION");
|
|
20077
|
+
}
|
|
20078
|
+
const deadline = Date.now() + budget;
|
|
20079
|
+
const entries = await readdir4(options.directory, { withFileTypes: true });
|
|
20080
|
+
const batches = entries.filter((entry) => /^batch-[0-9]{3,4}$/.test(entry.name)).sort((a, b) => Number(a.name.slice(6)) - Number(b.name.slice(6)));
|
|
20081
|
+
if (!batches.length || batches.length > 4096 || batches.some((entry) => !entry.isDirectory() || entry.isSymbolicLink()) || batches.length !== entries.length) {
|
|
20082
|
+
throw new CliError("CLI_CONFIGURATION");
|
|
20083
|
+
}
|
|
20084
|
+
const manifests = await Promise.all(
|
|
20085
|
+
batches.map((entry) => readPrepared(join5(options.directory, entry.name)))
|
|
20086
|
+
);
|
|
20087
|
+
const first = manifests[0];
|
|
20088
|
+
if (!first.buildId || manifests.some(
|
|
20089
|
+
(manifest, index) => manifest.buildId !== first.buildId || manifest.release !== first.release || manifest.batchCount !== batches.length || manifest.batchIndex !== index
|
|
20090
|
+
)) {
|
|
20091
|
+
throw new CliError("CLI_CONFIGURATION");
|
|
20092
|
+
}
|
|
20093
|
+
for (const batch of batches) {
|
|
20094
|
+
options.signal?.throwIfAborted();
|
|
20095
|
+
const remaining = deadline - Date.now();
|
|
20096
|
+
if (remaining < 1) {
|
|
20097
|
+
throw new CliError("NETWORK_TIMEOUT");
|
|
20098
|
+
}
|
|
20099
|
+
await uploadMaps(
|
|
20100
|
+
join5(options.directory, batch.name),
|
|
20101
|
+
options.url,
|
|
20102
|
+
options.projectId,
|
|
20103
|
+
options.token,
|
|
20104
|
+
transport,
|
|
20105
|
+
{ environment, deadlineMs: remaining, signal: options.signal }
|
|
20106
|
+
);
|
|
20107
|
+
}
|
|
20108
|
+
return { status: "ready", batches: batches.length };
|
|
20109
|
+
} catch (error61) {
|
|
20110
|
+
return {
|
|
20111
|
+
status: "unavailable",
|
|
20112
|
+
diagnostic: formatDiagnostic(error61).trim()
|
|
20113
|
+
};
|
|
20114
|
+
}
|
|
20115
|
+
}
|
|
19939
20116
|
export {
|
|
19940
20117
|
assertPublicOutput,
|
|
19941
20118
|
deployWithGetException,
|
|
20119
|
+
prepareSourceMaps,
|
|
20120
|
+
registerRelease,
|
|
20121
|
+
uploadSourceMaps,
|
|
19942
20122
|
validateGitLabContext
|
|
19943
20123
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getexception/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.25",
|
|
4
4
|
"description": "Private source map uploads for GetException",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"repository": {
|
|
33
33
|
"type": "git",
|
|
34
|
-
"url": "git+https://
|
|
34
|
+
"url": "git+https://gitlab.sndsy.ru/sendsay-ru/frontend/getexception.git",
|
|
35
35
|
"directory": "packages/cli"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|