fimo 0.3.4-staging.27 → 0.3.5-experimental.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/bundle.json
CHANGED
package/dist/cli/index.js
CHANGED
|
@@ -103822,7 +103822,8 @@ async function loadPublicTenantLabels(cwd, locale) {
|
|
|
103822
103822
|
try {
|
|
103823
103823
|
const url2 = new URL("/labels", apiUrl);
|
|
103824
103824
|
url2.searchParams.set("locale", locale);
|
|
103825
|
-
const
|
|
103825
|
+
const headers = env2.VITE_FIMO_BRANCH ? { "X-Fimo-Branch": env2.VITE_FIMO_BRANCH } : {};
|
|
103826
|
+
const response = await fetchWithTimeout(url2, 4e3, headers);
|
|
103826
103827
|
if (!response.ok) {
|
|
103827
103828
|
return null;
|
|
103828
103829
|
}
|
|
@@ -103830,17 +103831,17 @@ async function loadPublicTenantLabels(cwd, locale) {
|
|
|
103830
103831
|
if (Array.isArray(body.data)) {
|
|
103831
103832
|
return labelsToRecord(body.data);
|
|
103832
103833
|
}
|
|
103833
|
-
return body.data?.labels ??
|
|
103834
|
+
return body.data?.labels ?? null;
|
|
103834
103835
|
} catch {
|
|
103835
103836
|
return null;
|
|
103836
103837
|
}
|
|
103837
103838
|
}
|
|
103838
103839
|
__name(loadPublicTenantLabels, "loadPublicTenantLabels");
|
|
103839
|
-
async function fetchWithTimeout(url2, timeoutMs) {
|
|
103840
|
+
async function fetchWithTimeout(url2, timeoutMs, headers) {
|
|
103840
103841
|
const controller = new AbortController();
|
|
103841
103842
|
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
103842
103843
|
try {
|
|
103843
|
-
return await fetch(url2, { signal: controller.signal });
|
|
103844
|
+
return await fetch(url2, { signal: controller.signal, headers });
|
|
103844
103845
|
} finally {
|
|
103845
103846
|
clearTimeout(timeout);
|
|
103846
103847
|
}
|
|
@@ -103854,6 +103855,9 @@ async function readProjectEnv(cwd) {
|
|
|
103854
103855
|
if (process.env.VITE_API_URL) {
|
|
103855
103856
|
values.VITE_API_URL = process.env.VITE_API_URL;
|
|
103856
103857
|
}
|
|
103858
|
+
if (process.env.VITE_FIMO_BRANCH) {
|
|
103859
|
+
values.VITE_FIMO_BRANCH = process.env.VITE_FIMO_BRANCH;
|
|
103860
|
+
}
|
|
103857
103861
|
return values;
|
|
103858
103862
|
}
|
|
103859
103863
|
__name(readProjectEnv, "readProjectEnv");
|
package/package.json
CHANGED
|
@@ -100,15 +100,44 @@ export function stripTemplateLockfile(cliRoot) {
|
|
|
100
100
|
return () => writeFileSync(file, original);
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Next per-version prerelease counter: one past the highest already-published
|
|
105
|
+
* `<base>-<distTag>.<n>` on npm. Counting from what's actually published
|
|
106
|
+
* (instead of resetting blindly to 1) keeps the counter collision-proof even
|
|
107
|
+
* when the projected base flaps back to a value that already has prereleases —
|
|
108
|
+
* npm versions are immutable, so a blind reset would make the publish fail.
|
|
109
|
+
*
|
|
110
|
+
* @param {readonly string[]} existingVersions - all published versions of the package
|
|
111
|
+
* @param {string} base - X.Y.Z base (no prerelease suffix)
|
|
112
|
+
* @param {string} distTag
|
|
113
|
+
* @returns {number}
|
|
114
|
+
*/
|
|
115
|
+
export function nextPrereleaseCounter(existingVersions, base, distTag) {
|
|
116
|
+
const prefix = `${base}-${distTag}.`;
|
|
117
|
+
let max = 0;
|
|
118
|
+
for (const version of existingVersions) {
|
|
119
|
+
if (!version.startsWith(prefix)) {
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
const n = Number(version.slice(prefix.length));
|
|
123
|
+
if (Number.isInteger(n) && n > max) {
|
|
124
|
+
max = n;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return max + 1;
|
|
128
|
+
}
|
|
129
|
+
|
|
103
130
|
/**
|
|
104
131
|
* Compute the version to publish for a channel.
|
|
105
132
|
* - Stable (`latest`) publishes the exact package.json version.
|
|
106
|
-
* - Prerelease channels synthesize a disposable `X.Y.Z-<distTag>.<n
|
|
107
|
-
*
|
|
133
|
+
* - Prerelease channels synthesize a disposable `X.Y.Z-<distTag>.<n>`.
|
|
134
|
+
* `n` counts per base version (`0.3.5-staging.1`, `.2`, …) when the
|
|
135
|
+
* published versions could be fetched from npm; otherwise it falls back
|
|
136
|
+
* to the CI run number, then a timestamp.
|
|
108
137
|
*
|
|
109
138
|
* @param {string} baseVersion - package.json version
|
|
110
139
|
* @param {import('./channels.mjs').Channel} channel
|
|
111
|
-
* @param {{ runId?: string }} [opts]
|
|
140
|
+
* @param {{ runId?: string, existingVersions?: readonly string[] }} [opts]
|
|
112
141
|
* @returns {string}
|
|
113
142
|
*/
|
|
114
143
|
export function computePublishVersion(baseVersion, channel, opts = {}) {
|
|
@@ -117,7 +146,9 @@ export function computePublishVersion(baseVersion, channel, opts = {}) {
|
|
|
117
146
|
}
|
|
118
147
|
// Strip any existing prerelease suffix from the base so we don't stack them.
|
|
119
148
|
const base = baseVersion.split('-')[0];
|
|
120
|
-
const n = opts.
|
|
149
|
+
const n = opts.existingVersions
|
|
150
|
+
? String(nextPrereleaseCounter(opts.existingVersions, base, channel.distTag))
|
|
151
|
+
: (opts.runId ?? String(Date.now()));
|
|
121
152
|
return `${base}-${channel.distTag}.${n}`;
|
|
122
153
|
}
|
|
123
154
|
|
|
@@ -5,7 +5,7 @@ import { join } from 'node:path';
|
|
|
5
5
|
import { afterEach, describe, expect, it } from 'vitest';
|
|
6
6
|
|
|
7
7
|
// @ts-expect-error plain mjs module without types
|
|
8
|
-
import { computePublishVersion, nextVersionFromChangesets } from './release-core.mjs';
|
|
8
|
+
import { computePublishVersion, nextPrereleaseCounter, nextVersionFromChangesets } from './release-core.mjs';
|
|
9
9
|
|
|
10
10
|
const stagingChannel = { prerelease: true, distTag: 'staging' };
|
|
11
11
|
const latestChannel = { prerelease: false, distTag: 'latest' };
|
|
@@ -22,6 +22,37 @@ describe('computePublishVersion', () => {
|
|
|
22
22
|
it('strips an existing prerelease suffix before synthesizing', () => {
|
|
23
23
|
expect(computePublishVersion('0.3.3-staging.9', stagingChannel, { runId: '26' })).toBe('0.3.3-staging.26');
|
|
24
24
|
});
|
|
25
|
+
|
|
26
|
+
it('counts per base version when published versions are provided', () => {
|
|
27
|
+
const existingVersions = ['0.3.4', '0.3.5-staging.1', '0.3.5-staging.2'];
|
|
28
|
+
expect(computePublishVersion('0.3.5', stagingChannel, { runId: '30', existingVersions })).toBe('0.3.5-staging.3');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('starts at 1 for a base with no published prereleases', () => {
|
|
32
|
+
const existingVersions = ['0.3.4', '0.3.4-staging.26', '0.3.4-staging.27'];
|
|
33
|
+
expect(computePublishVersion('0.3.5', stagingChannel, { runId: '30', existingVersions })).toBe('0.3.5-staging.1');
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe('nextPrereleaseCounter', () => {
|
|
38
|
+
it('returns 1 when nothing matches the base + tag', () => {
|
|
39
|
+
expect(nextPrereleaseCounter([], '0.3.5', 'staging')).toBe(1);
|
|
40
|
+
expect(nextPrereleaseCounter(['0.3.5', '0.3.5-experimental.4'], '0.3.5', 'staging')).toBe(1);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('continues past the highest published counter for the base', () => {
|
|
44
|
+
const versions = ['0.3.4-staging.26', '0.3.4-staging.27', '0.3.3-staging.25'];
|
|
45
|
+
expect(nextPrereleaseCounter(versions, '0.3.4', 'staging')).toBe(28);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('does not confuse prefix-sharing bases (0.3.4 vs 0.3.40)', () => {
|
|
49
|
+
expect(nextPrereleaseCounter(['0.3.40-staging.9'], '0.3.4', 'staging')).toBe(1);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('ignores non-integer counters (timestamps still count, garbage does not)', () => {
|
|
53
|
+
expect(nextPrereleaseCounter(['0.3.4-staging.abc', '0.3.4-staging.2.5'], '0.3.4', 'staging')).toBe(1);
|
|
54
|
+
expect(nextPrereleaseCounter(['0.3.3-experimental.1783410168478'], '0.3.3', 'experimental')).toBe(1783410168479);
|
|
55
|
+
});
|
|
25
56
|
});
|
|
26
57
|
|
|
27
58
|
describe('nextVersionFromChangesets', () => {
|
package/scripts/publish-npm.mjs
CHANGED
|
@@ -71,6 +71,23 @@ function run(cmd, args, cwd) {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
// All published versions of the package, or null when the registry can't be
|
|
75
|
+
// reached (offline, first-ever publish) — callers fall back to the
|
|
76
|
+
// run-number/timestamp counter.
|
|
77
|
+
function fetchPublishedVersions(name) {
|
|
78
|
+
const result = spawnSync('npm', ['view', name, 'versions', '--json'], { encoding: 'utf8' });
|
|
79
|
+
if (result.status !== 0) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
const parsed = JSON.parse(result.stdout);
|
|
84
|
+
// npm view returns a bare string when exactly one version is published.
|
|
85
|
+
return Array.isArray(parsed) ? parsed : [parsed];
|
|
86
|
+
} catch {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
74
91
|
const { channel: channelName, dryRun, bootstrap, plan } = parseArgs(process.argv.slice(2));
|
|
75
92
|
|
|
76
93
|
if (!channelName) {
|
|
@@ -98,7 +115,14 @@ const baseVersion = channel.prerelease
|
|
|
98
115
|
? nextVersionFromChangesets(pkg.version, resolve(CLI_ROOT, '../../.changeset'))
|
|
99
116
|
: pkg.version;
|
|
100
117
|
const runId = process.env.GITHUB_RUN_NUMBER;
|
|
101
|
-
|
|
118
|
+
let existingVersions;
|
|
119
|
+
if (channel.prerelease) {
|
|
120
|
+
existingVersions = fetchPublishedVersions(pkg.name) ?? undefined;
|
|
121
|
+
if (!existingVersions) {
|
|
122
|
+
console.warn('[publish-npm] could not fetch published versions from npm — using run/timestamp counter.');
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
const publishVersion = computePublishVersion(baseVersion, channel, { runId, existingVersions });
|
|
102
126
|
|
|
103
127
|
console.log(`[publish-npm] channel: ${channelName} (dist-tag: ${channel.distTag})`);
|
|
104
128
|
console.log(
|