create-portfoliable 1.2.18 → 1.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/bin/create-portfoliable.mjs +19 -0
- package/cli/portfoliable.mjs +26 -24
- package/package.json +1 -1
- package/scripts/package-updates.mjs +41 -0
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
readProjectUiPreferences,
|
|
17
17
|
writeProjectUiPreferences
|
|
18
18
|
} from '../scripts/terminal-ui.mjs';
|
|
19
|
+
import { findPackageUpdates } from '../scripts/package-updates.mjs';
|
|
19
20
|
|
|
20
21
|
// MARK: DEFAULTS
|
|
21
22
|
// Defines default target folder when no project name is provided.
|
|
@@ -385,6 +386,24 @@ async function run() {
|
|
|
385
386
|
printRailSegment({ dot: true, label: `${color('32', 'Dependencies installed.')}` });
|
|
386
387
|
console.log(color('36', 'Command guide is available after launch via interactive prompt.'));
|
|
387
388
|
|
|
389
|
+
const installedPackages = [
|
|
390
|
+
['create-portfoliable', path.resolve(targetDir, 'node_modules', 'create-portfoliable', 'package.json')],
|
|
391
|
+
['@portfoliablejs/valence', path.resolve(targetDir, 'node_modules', '@portfoliablejs', 'valence', 'package.json')]
|
|
392
|
+
].flatMap(([name, packagePath]) => {
|
|
393
|
+
try {
|
|
394
|
+
return [{ name, currentVersion: JSON.parse(fs.readFileSync(packagePath, 'utf8')).version }];
|
|
395
|
+
} catch {
|
|
396
|
+
return [];
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
const updates = await findPackageUpdates(installedPackages);
|
|
400
|
+
for (const update of updates) {
|
|
401
|
+
const isValence = update.name === '@portfoliablejs/valence';
|
|
402
|
+
const label = isValence ? 'design system' : 'Portfoliable';
|
|
403
|
+
console.log(color('33', `A new ${label} update (${update.latestVersion}) is available.`));
|
|
404
|
+
console.log(`Run: ${color('32', `npm update ${update.name}`)}`);
|
|
405
|
+
}
|
|
406
|
+
|
|
388
407
|
if (options.launch) {
|
|
389
408
|
printRailSegment();
|
|
390
409
|
printRailSegment({ dot: true, label: `${color('36', 'Preparing first build...')}` });
|
package/cli/portfoliable.mjs
CHANGED
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
readProjectUiPreferences
|
|
28
28
|
} from '../scripts/terminal-ui.mjs';
|
|
29
29
|
import { resolveConsumerRuntimeAliases } from '../scripts/consumer-runtime-aliases.mjs';
|
|
30
|
+
import { findPackageUpdates } from '../scripts/package-updates.mjs';
|
|
30
31
|
|
|
31
32
|
function resolveMermaidDevAliases(runtimeAliases) {
|
|
32
33
|
return [
|
|
@@ -83,21 +84,6 @@ function firstNetworkAddress() {
|
|
|
83
84
|
return null;
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
// Fetches latest published create-portfoliable version from npm registry.
|
|
87
|
-
async function fetchLatestVersion() {
|
|
88
|
-
try {
|
|
89
|
-
// Calls npm metadata endpoint for latest dist-tag payload.
|
|
90
|
-
const response = await fetch('https://registry.npmjs.org/create-portfoliable/latest');
|
|
91
|
-
if (!response.ok) return null;
|
|
92
|
-
|
|
93
|
-
// Parses registry response payload.
|
|
94
|
-
const data = await response.json();
|
|
95
|
-
return data.version || null;
|
|
96
|
-
} catch {
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
87
|
// MARK: CLI ARGUMENT PARSING
|
|
102
88
|
// Parses command and flags from argv into normalized runtime options.
|
|
103
89
|
function parseCliArgs(argv) {
|
|
@@ -496,7 +482,7 @@ function createCaseContentAssetPlugin() {
|
|
|
496
482
|
}
|
|
497
483
|
|
|
498
484
|
// Prints startup summary box for dev server sessions.
|
|
499
|
-
function printStartupBox({ localUrl, networkUrl,
|
|
485
|
+
function printStartupBox({ localUrl, networkUrl, updates }) {
|
|
500
486
|
const lines = [
|
|
501
487
|
`${green}${bold}Portfoliable ready!${reset}`,
|
|
502
488
|
`${dim}Dev server is live and ready for editing.${reset}`,
|
|
@@ -507,13 +493,20 @@ function printStartupBox({ localUrl, networkUrl, localVersion, latestVersion })
|
|
|
507
493
|
`${bold}Next:${reset} open the local URL in your browser.`
|
|
508
494
|
];
|
|
509
495
|
|
|
510
|
-
|
|
496
|
+
for (const update of updates) {
|
|
511
497
|
lines.push('');
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
lines.push(
|
|
498
|
+
const isValence = update.name === '@portfoliablejs/valence';
|
|
499
|
+
const packageLabel = isValence ? 'design system' : 'Portfoliable';
|
|
500
|
+
lines.push(`${yellow}A new ${packageLabel} update (${update.latestVersion}) is available!${reset}`);
|
|
501
|
+
lines.push(`Upgrade now: ${green}npm update ${update.name}${reset}`);
|
|
502
|
+
if (!isValence) {
|
|
503
|
+
lines.push(`If it still persists, run: ${green}npm install ${update.name}@latest${reset}`);
|
|
504
|
+
}
|
|
515
505
|
lines.push('Read changelog:');
|
|
516
|
-
|
|
506
|
+
const changelogUrl = isValence
|
|
507
|
+
? 'https://github.com/portfoliablejs/valence/blob/main/CHANGELOG.md'
|
|
508
|
+
: 'https://github.com/portfoliablejs/portfoliable/blob/main/CHANGELOG.md';
|
|
509
|
+
lines.push(`${dim}${changelogUrl}${reset}`);
|
|
517
510
|
}
|
|
518
511
|
|
|
519
512
|
printRailAttachedBox({ width: 96, lines });
|
|
@@ -634,15 +627,24 @@ async function runDevServer(flags, options = {}) {
|
|
|
634
627
|
|
|
635
628
|
// Resolves currently running CLI package version.
|
|
636
629
|
const localVersion = resolvePackageVersion();
|
|
637
|
-
|
|
638
|
-
|
|
630
|
+
const valencePackagePath = path.resolve(process.cwd(), 'node_modules', '@portfoliablejs', 'valence', 'package.json');
|
|
631
|
+
let valenceVersion = null;
|
|
632
|
+
try {
|
|
633
|
+
valenceVersion = JSON.parse(fs.readFileSync(valencePackagePath, 'utf8')).version || null;
|
|
634
|
+
} catch {
|
|
635
|
+
valenceVersion = null;
|
|
636
|
+
}
|
|
637
|
+
const updates = await findPackageUpdates([
|
|
638
|
+
{ name: 'create-portfoliable', currentVersion: localVersion },
|
|
639
|
+
...(valenceVersion ? [{ name: '@portfoliablejs/valence', currentVersion: valenceVersion }] : [])
|
|
640
|
+
]);
|
|
639
641
|
|
|
640
642
|
if (fancyDots) {
|
|
641
643
|
printRailSegment({ dot: true, label: `${cyan}${bold}Starting...${reset}` });
|
|
642
644
|
printRailSpacer();
|
|
643
645
|
}
|
|
644
646
|
|
|
645
|
-
printStartupBox({ localUrl, networkUrl,
|
|
647
|
+
printStartupBox({ localUrl, networkUrl, updates });
|
|
646
648
|
|
|
647
649
|
if (isInteractiveTerminal() && flags.open !== false) {
|
|
648
650
|
let showCommands = false;
|
package/package.json
CHANGED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const PACKAGE_REGISTRY_URL = 'https://registry.npmjs.org';
|
|
2
|
+
|
|
3
|
+
function parseVersion(version) {
|
|
4
|
+
const match = String(version || '').trim().match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
5
|
+
return match ? match.slice(1).map(Number) : null;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function isNewerVersion(latestVersion, currentVersion) {
|
|
9
|
+
const latest = parseVersion(latestVersion);
|
|
10
|
+
const current = parseVersion(currentVersion);
|
|
11
|
+
if (!latest || !current) return false;
|
|
12
|
+
|
|
13
|
+
for (let index = 0; index < latest.length; index += 1) {
|
|
14
|
+
if (latest[index] !== current[index]) return latest[index] > current[index];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export async function fetchLatestPackageVersion(packageName) {
|
|
21
|
+
try {
|
|
22
|
+
const response = await fetch(`${PACKAGE_REGISTRY_URL}/${encodeURIComponent(packageName)}/latest`);
|
|
23
|
+
if (!response.ok) return null;
|
|
24
|
+
|
|
25
|
+
const data = await response.json();
|
|
26
|
+
return data.version || null;
|
|
27
|
+
} catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export async function findPackageUpdates(packages) {
|
|
33
|
+
const updates = await Promise.all(packages.map(async ({ name, currentVersion }) => {
|
|
34
|
+
const latestVersion = await fetchLatestPackageVersion(name);
|
|
35
|
+
if (!latestVersion || !isNewerVersion(latestVersion, currentVersion)) return null;
|
|
36
|
+
|
|
37
|
+
return { name, currentVersion, latestVersion };
|
|
38
|
+
}));
|
|
39
|
+
|
|
40
|
+
return updates.filter(Boolean);
|
|
41
|
+
}
|