@monocle.sh/vite-plugin 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/vite.mjs +298 -1
  2. package/package.json +1 -1
package/dist/vite.mjs CHANGED
@@ -1,8 +1,305 @@
1
1
  import { dirname, join, resolve } from "node:path";
2
- import { ServiceVersionDetector } from "@monocle.sh/otel-utils/service-version";
2
+ import { readFileSync, statSync } from "node:fs";
3
3
  import MagicString from "magic-string";
4
4
  import { rm } from "node:fs/promises";
5
5
  import { injectDebugIds, uploadSourcemaps } from "@monocle.sh/sourcemaps";
6
+ //#region ../otel-utils/dist/service-version.mjs
7
+ var ServiceVersionDetector = class {
8
+ /**
9
+ * Ordered platform revision variables, before CI and the local checkout.
10
+ */
11
+ static #platformSources = [
12
+ ["VERCEL_GIT_COMMIT_SHA", "platform:vercel"],
13
+ ["RENDER_GIT_COMMIT", "platform:render"],
14
+ ["RAILWAY_GIT_COMMIT_SHA", "platform:railway"],
15
+ ["HEROKU_BUILD_COMMIT", "platform:heroku"],
16
+ ["HEROKU_SLUG_COMMIT", "platform:heroku"],
17
+ ["SOURCE_COMMIT", "platform:coolify"],
18
+ ["GIT_REV", "platform:dokku"],
19
+ ["K_REVISION", "platform:cloud-run"]
20
+ ];
21
+ /**
22
+ * CI detection adapted from env-ci 11.2.0 (MIT): https://github.com/semantic-release/env-ci
23
+ * See LICENSE.env-ci. Git subprocess and Java properties adapters are excluded.
24
+ */
25
+ static #ciSources = {
26
+ github: {
27
+ detect: (env) => Boolean(env.GITHUB_ACTIONS),
28
+ revisions: ["GITHUB_SHA"],
29
+ repository: (env) => this.#repositoryFromSlug({
30
+ host: env.GITHUB_SERVER_URL,
31
+ slug: env.GITHUB_REPOSITORY
32
+ })
33
+ },
34
+ gitlab: {
35
+ detect: (env) => Boolean(env.GITLAB_CI),
36
+ revisions: ["CI_COMMIT_SHA"],
37
+ repository: (env) => this.#normalizeRepositoryUrl(env.CI_PROJECT_URL) ?? this.#repositoryFromSlug({
38
+ host: env.CI_SERVER_URL,
39
+ slug: env.CI_PROJECT_PATH
40
+ })
41
+ },
42
+ woodpecker: {
43
+ detect: (env) => env.CI === "woodpecker",
44
+ revisions: ["CI_COMMIT_SHA"],
45
+ repository: (env) => env.CI_REPO_CLONE_URL
46
+ },
47
+ circleci: {
48
+ detect: (env) => Boolean(env.CIRCLECI),
49
+ revisions: ["CIRCLE_SHA1"],
50
+ repository: (env) => env.CIRCLE_REPOSITORY_URL
51
+ },
52
+ bitbucket: {
53
+ detect: (env) => Boolean(env.BITBUCKET_BUILD_NUMBER),
54
+ revisions: ["BITBUCKET_COMMIT"],
55
+ repository: (env) => this.#repositoryFromSlug({
56
+ host: "https://bitbucket.org",
57
+ slug: env.BITBUCKET_REPO_FULL_NAME
58
+ })
59
+ },
60
+ buildkite: {
61
+ detect: (env) => Boolean(env.BUILDKITE),
62
+ revisions: ["BUILDKITE_COMMIT"],
63
+ repository: (env) => env.BUILDKITE_REPO
64
+ },
65
+ jenkins: {
66
+ detect: (env) => Boolean(env.JENKINS_URL),
67
+ revisions: ["ghprbActualCommit", "GIT_COMMIT"],
68
+ repository: (env) => env.GIT_URL
69
+ },
70
+ "azure-pipelines": {
71
+ detect: (env) => Boolean(env.BUILD_BUILDURI),
72
+ revisions: ["BUILD_SOURCEVERSION"],
73
+ repository: (env) => env.BUILD_REPOSITORY_URI
74
+ },
75
+ travis: {
76
+ detect: (env) => Boolean(env.TRAVIS),
77
+ revisions: ["TRAVIS_COMMIT"]
78
+ },
79
+ netlify: {
80
+ detect: (env) => env.NETLIFY === "true",
81
+ revisions: ["COMMIT_REF"],
82
+ repository: (env) => env.REPOSITORY_URL
83
+ },
84
+ "cloudflare-pages": {
85
+ detect: (env) => env.CF_PAGES === "1",
86
+ revisions: ["CF_PAGES_COMMIT_SHA"]
87
+ },
88
+ drone: {
89
+ detect: (env) => Boolean(env.DRONE),
90
+ revisions: ["DRONE_COMMIT_SHA"],
91
+ repository: (env) => env.DRONE_REMOTE_URL
92
+ },
93
+ bitrise: {
94
+ detect: (env) => Boolean(env.BITRISE_IO),
95
+ revisions: ["BITRISE_GIT_COMMIT"]
96
+ },
97
+ appveyor: {
98
+ detect: (env) => Boolean(env.APPVEYOR),
99
+ revisions: ["APPVEYOR_REPO_COMMIT"]
100
+ },
101
+ semaphore: {
102
+ detect: (env) => Boolean(env.SEMAPHORE),
103
+ revisions: ["SEMAPHORE_GIT_SHA"]
104
+ },
105
+ codefresh: {
106
+ detect: (env) => Boolean(env.CF_BUILD_ID),
107
+ revisions: ["CF_REVISION"]
108
+ },
109
+ buddy: {
110
+ detect: (env) => Boolean(env.BUDDY_WORKSPACE_ID),
111
+ revisions: ["BUDDY_EXECUTION_REVISION"]
112
+ },
113
+ cirrus: {
114
+ detect: (env) => Boolean(env.CIRRUS_CI),
115
+ revisions: ["CIRRUS_CHANGE_IN_REPO"]
116
+ },
117
+ vela: {
118
+ detect: (env) => Boolean(env.VELA),
119
+ revisions: ["VELA_BUILD_COMMIT"]
120
+ },
121
+ screwdriver: {
122
+ detect: (env) => Boolean(env.SCREWDRIVER),
123
+ revisions: ["SD_BUILD_SHA"]
124
+ },
125
+ bamboo: {
126
+ detect: (env) => Boolean(env.bamboo_agentId),
127
+ revisions: ["bamboo_planRepository_1_revision"]
128
+ },
129
+ codeship: {
130
+ detect: (env) => env.CI_NAME === "codeship",
131
+ revisions: ["CI_COMMIT_ID"]
132
+ },
133
+ "jetbrains-space": {
134
+ detect: (env) => Boolean(env.JB_SPACE_EXECUTION_NUMBER),
135
+ revisions: ["JB_SPACE_GIT_REVISION"]
136
+ },
137
+ scrutinizer: {
138
+ detect: (env) => Boolean(env.SCRUTINIZER),
139
+ revisions: ["SCRUTINIZER_SHA1"]
140
+ }
141
+ };
142
+ static #value(value) {
143
+ const trimmed = value?.trim();
144
+ if (!trimmed || [
145
+ "0.0.0",
146
+ "0.0.1",
147
+ "1.0.0",
148
+ "unknown",
149
+ "dev",
150
+ "latest"
151
+ ].includes(trimmed.toLowerCase())) return;
152
+ return trimmed;
153
+ }
154
+ static #sha(value) {
155
+ if (value && /^(?:[a-f0-9]{40}|[a-f0-9]{64})$/i.test(value)) return value;
156
+ }
157
+ static #read(path) {
158
+ try {
159
+ return readFileSync(path, "utf8").trim();
160
+ } catch {
161
+ return;
162
+ }
163
+ }
164
+ static #gitDirectory(cwd) {
165
+ let directory = resolve(cwd);
166
+ while (true) {
167
+ const path = join(directory, ".git");
168
+ try {
169
+ if (statSync(path).isDirectory()) return path;
170
+ const target = this.#read(path)?.match(/^gitdir:\s*(.+)$/)?.[1];
171
+ return target ? resolve(directory, target) : void 0;
172
+ } catch {
173
+ const parent = dirname(directory);
174
+ if (parent === directory) return;
175
+ directory = parent;
176
+ }
177
+ }
178
+ }
179
+ static #gitRevision(cwd) {
180
+ const gitDirectory = this.#gitDirectory(cwd);
181
+ if (!gitDirectory) return;
182
+ const head = this.#read(join(gitDirectory, "HEAD"));
183
+ const detached = this.#sha(head);
184
+ if (detached) return detached;
185
+ const ref = head?.match(/^ref:\s*(refs\/[^\s]+)$/)?.[1];
186
+ if (!ref || ref.split("/").includes("..")) return;
187
+ const common = this.#read(join(gitDirectory, "commondir"));
188
+ const directories = common ? [gitDirectory, resolve(gitDirectory, common)] : [gitDirectory];
189
+ for (const directory of directories) {
190
+ const direct = this.#sha(this.#read(join(directory, ref)));
191
+ if (direct) return direct;
192
+ const packed = this.#read(join(directory, "packed-refs"));
193
+ for (const line of packed?.split("\n") ?? []) {
194
+ const [sha, name] = line.trim().split(/\s+/);
195
+ if (name === ref && this.#sha(sha)) return sha;
196
+ }
197
+ }
198
+ }
199
+ static #githubRevision(env) {
200
+ const fallback = this.#value(env.GITHUB_SHA);
201
+ if (env.GITHUB_EVENT_NAME !== "pull_request") return fallback;
202
+ if (!env.GITHUB_EVENT_PATH) return fallback;
203
+ try {
204
+ const sha = JSON.parse(this.#read(env.GITHUB_EVENT_PATH) ?? "")?.pull_request?.head?.sha;
205
+ return typeof sha === "string" ? this.#sha(sha) ?? fallback : fallback;
206
+ } catch {
207
+ return fallback;
208
+ }
209
+ }
210
+ static #repositoryFromSlug(options) {
211
+ const host = this.#normalizeRepositoryUrl(options.host);
212
+ const slug = this.#value(options.slug);
213
+ if (!host || !slug) return;
214
+ return `${host}/${slug.replace(/^\/+/, "")}`;
215
+ }
216
+ static #vercelRepository(env) {
217
+ const hosts = new Map([
218
+ ["github", "https://github.com"],
219
+ ["gitlab", "https://gitlab.com"],
220
+ ["bitbucket", "https://bitbucket.org"]
221
+ ]);
222
+ const owner = this.#value(env.VERCEL_GIT_REPO_OWNER);
223
+ const slug = this.#value(env.VERCEL_GIT_REPO_SLUG);
224
+ if (!owner || !slug) return;
225
+ return this.#repositoryFromSlug({
226
+ host: hosts.get(env.VERCEL_GIT_PROVIDER ?? ""),
227
+ slug: `${owner}/${slug}`
228
+ });
229
+ }
230
+ static #repositoryUrl(env) {
231
+ return [
232
+ env.VERCEL || env.NOW_GITHUB_DEPLOYMENT ? this.#vercelRepository(env) : void 0,
233
+ env.RENDER ? env.RENDER_GIT_REPO_URL : void 0,
234
+ env.RAILWAY_PROJECT_ID ? env.RAILWAY_GIT_REPO_URL : void 0,
235
+ ...Object.values(this.#ciSources).filter((provider) => provider.detect(env)).map((provider) => provider.repository?.(env))
236
+ ].map((candidate) => this.#normalizeRepositoryUrl(candidate)).find(Boolean);
237
+ }
238
+ static #normalizeRepositoryUrl(candidate) {
239
+ const value = this.#value(candidate);
240
+ if (!value) return;
241
+ try {
242
+ const url = new URL(value.replace(/^git@([^:/]+):/, "ssh://git@$1/"));
243
+ if (!url.host || ![
244
+ "https:",
245
+ "http:",
246
+ "ssh:"
247
+ ].includes(url.protocol)) return;
248
+ const path = url.pathname.replace(/\/+$/, "").replace(/\.git$/, "").replace(/\/+$/, "");
249
+ return `https://${url.protocol === "ssh:" ? url.hostname : url.host}${path}`;
250
+ } catch {
251
+ return;
252
+ }
253
+ }
254
+ static detect(options = {}) {
255
+ const env = options.env ?? process.env;
256
+ const candidates = [
257
+ {
258
+ version: this.#value(options.serviceVersion),
259
+ source: "config"
260
+ },
261
+ {
262
+ version: this.#value(env.MONOCLE_VERSION),
263
+ source: "env"
264
+ },
265
+ {
266
+ version: this.#value(env.APP_VERSION),
267
+ source: "env"
268
+ },
269
+ ...this.#platformSources.map(([key, source]) => ({
270
+ version: this.#value(env[key]),
271
+ source
272
+ })),
273
+ ...Object.entries(this.#ciSources).filter(([, provider]) => provider.detect(env)).flatMap(([name, provider]) => provider.revisions.map((key) => ({
274
+ version: name === "github" ? this.#githubRevision(env) : this.#value(env[key]),
275
+ source: `ci:${name}`
276
+ })))
277
+ ];
278
+ const selected = candidates.find(({ version }) => version);
279
+ const knownSha = candidates.map(({ version }) => this.#sha(version)).find(Boolean);
280
+ const gitSha = knownSha ? void 0 : this.#gitRevision(options.cwd ?? process.cwd());
281
+ return {
282
+ version: selected?.version ?? gitSha,
283
+ source: selected?.source ?? (gitSha ? "git" : "none"),
284
+ commitSha: knownSha ?? gitSha,
285
+ repositoryUrl: this.#repositoryUrl(env),
286
+ deploymentId: [
287
+ env.RAILWAY_DEPLOYMENT_ID,
288
+ env.VERCEL_DEPLOYMENT_ID,
289
+ env.RENDER_DEPLOY_ID
290
+ ].map((value) => this.#value(value)).find(Boolean)
291
+ };
292
+ }
293
+ static resourceAttributes(result) {
294
+ const attributes = { "monocle.service.version.source": result.source };
295
+ if (result.version) attributes["service.version"] = result.version;
296
+ if (result.commitSha) attributes["vcs.ref.head.revision"] = result.commitSha;
297
+ if (result.repositoryUrl) attributes["vcs.repository.url.full"] = result.repositoryUrl;
298
+ if (result.deploymentId) attributes["deployment.id"] = result.deploymentId;
299
+ return attributes;
300
+ }
301
+ };
302
+ //#endregion
6
303
  //#region src/core/build_metadata.ts
7
304
  /**
8
305
  * Resolve the release with the same priority chain as the server agents, without spawning Git
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monocle.sh/vite-plugin",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Vite plugin that injects your release into the Monocle Browser SDK and uploads source maps at build time",
5
5
  "keywords": [
6
6
  "monocle",