mirror of
https://github.com/withastro/astro.git
synced 2024-12-30 22:03:56 -05:00
Adds create-astro
fallback values for package versions (#10255)
* fix(create-astro): add fallback when registry fails to return the current package version * feat(create-astro): inline most current package versions as fallback * test(create-astro): update typescript tests to check for undefined * test(create-astro): properly reset fixtures * refactor: read dependencies from workspace root * refactor: error on missing values
This commit is contained in:
parent
bad9b583a2
commit
2aec2cdc21
9 changed files with 69 additions and 17 deletions
5
.changeset/empty-bees-help.md
Normal file
5
.changeset/empty-bees-help.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
"create-astro": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fixes an issue where TypeScript and `@astrojs/check` versions would occassionally print as `undefined`.
|
|
@ -93,7 +93,7 @@ export async function getContext(argv: string[]): Promise<Context> {
|
||||||
prompt,
|
prompt,
|
||||||
packageManager,
|
packageManager,
|
||||||
username: getName(),
|
username: getName(),
|
||||||
version: getVersion(packageManager, 'astro'),
|
version: getVersion(packageManager, 'astro', process.env.ASTRO_VERSION),
|
||||||
skipHouston,
|
skipHouston,
|
||||||
fancy,
|
fancy,
|
||||||
dryRun,
|
dryRun,
|
||||||
|
|
|
@ -101,8 +101,8 @@ const FILES_TO_UPDATE = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const [astroCheckVersion, typescriptVersion] = await Promise.all([
|
const [astroCheckVersion, typescriptVersion] = await Promise.all([
|
||||||
getVersion(options.ctx.packageManager, '@astrojs/check'),
|
getVersion(options.ctx.packageManager, '@astrojs/check', process.env.ASTRO_CHECK_VERSION),
|
||||||
getVersion(options.ctx.packageManager, 'typescript'),
|
getVersion(options.ctx.packageManager, 'typescript', process.env.TYPESCRIPT_VERSION),
|
||||||
]);
|
]);
|
||||||
parsedPackageJson.dependencies ??= {};
|
parsedPackageJson.dependencies ??= {};
|
||||||
parsedPackageJson.dependencies['@astrojs/check'] = `^${astroCheckVersion}`;
|
parsedPackageJson.dependencies['@astrojs/check'] = `^${astroCheckVersion}`;
|
||||||
|
|
|
@ -65,10 +65,9 @@ export const getVersion = (packageManager: string, packageName: string, fallback
|
||||||
let registry = await getRegistry(packageManager);
|
let registry = await getRegistry(packageManager);
|
||||||
const { version } = await fetch(`${registry}/${packageName}/latest`, {
|
const { version } = await fetch(`${registry}/${packageName}/latest`, {
|
||||||
redirect: 'follow',
|
redirect: 'follow',
|
||||||
}).then(
|
})
|
||||||
(res) => res.json(),
|
.then((res) => res.json())
|
||||||
() => ({ version: fallback })
|
.catch(() => ({ version: fallback }))
|
||||||
);
|
|
||||||
return resolve(version);
|
return resolve(version);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "astro dev",
|
"dev": "astro dev",
|
||||||
"build": "astro check && astro build",
|
"build": "astro build",
|
||||||
"preview": "astro preview"
|
"preview": "astro preview"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1 @@
|
||||||
{
|
{}
|
||||||
"extends": "astro/tsconfigs/strictest"
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
import assert from 'node:assert/strict';
|
import assert from 'node:assert/strict';
|
||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import { beforeEach, describe, it } from 'node:test';
|
import { after, beforeEach, describe, it } from 'node:test';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
||||||
import { setupTypeScript, typescript } from '../dist/index.js';
|
import { setupTypeScript, typescript } from '../dist/index.js';
|
||||||
|
@ -81,6 +81,7 @@ describe('typescript', async () => {
|
||||||
|
|
||||||
describe('typescript: setup tsconfig', async () => {
|
describe('typescript: setup tsconfig', async () => {
|
||||||
beforeEach(() => resetFixtures());
|
beforeEach(() => resetFixtures());
|
||||||
|
after(() => resetFixtures());
|
||||||
|
|
||||||
it('none', async () => {
|
it('none', async () => {
|
||||||
const root = new URL('./fixtures/empty/', import.meta.url);
|
const root = new URL('./fixtures/empty/', import.meta.url);
|
||||||
|
@ -104,6 +105,7 @@ describe('typescript: setup tsconfig', async () => {
|
||||||
|
|
||||||
describe('typescript: setup package', async () => {
|
describe('typescript: setup package', async () => {
|
||||||
beforeEach(() => resetFixtures());
|
beforeEach(() => resetFixtures());
|
||||||
|
after(() => resetFixtures());
|
||||||
|
|
||||||
it('none', async () => {
|
it('none', async () => {
|
||||||
const root = new URL('./fixtures/empty/', import.meta.url);
|
const root = new URL('./fixtures/empty/', import.meta.url);
|
||||||
|
@ -122,7 +124,7 @@ describe('typescript: setup package', async () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
await setupTypeScript('strictest', { cwd: fileURLToPath(root), install: false });
|
await setupTypeScript('strictest', { cwd: fileURLToPath(root), install: false });
|
||||||
const { scripts } = JSON.parse(fs.readFileSync(packageJson, { encoding: 'utf-8' }));
|
const { scripts, dependencies } = JSON.parse(fs.readFileSync(packageJson, { encoding: 'utf-8' }));
|
||||||
|
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
Object.keys(scripts),
|
Object.keys(scripts),
|
||||||
|
@ -130,6 +132,10 @@ describe('typescript: setup package', async () => {
|
||||||
'does not override existing scripts'
|
'does not override existing scripts'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
for (const value of Object.values(dependencies)) {
|
||||||
|
assert.doesNotMatch(value, /undefined$/, 'does not include undefined values')
|
||||||
|
}
|
||||||
|
|
||||||
assert.equal(scripts.build, 'astro check && astro build', 'prepends astro check command');
|
assert.equal(scripts.build, 'astro check && astro build', 'prepends astro check command');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -48,6 +48,7 @@ const resetNotEmptyFixture = async () => {
|
||||||
build: 'astro build',
|
build: 'astro build',
|
||||||
preview: 'astro preview',
|
preview: 'astro preview',
|
||||||
},
|
},
|
||||||
|
dependencies: undefined
|
||||||
});
|
});
|
||||||
|
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
|
|
|
@ -55,11 +55,13 @@ export default async function build(...args) {
|
||||||
|
|
||||||
const {
|
const {
|
||||||
type = 'module',
|
type = 'module',
|
||||||
version,
|
|
||||||
dependencies = {},
|
dependencies = {},
|
||||||
} = await fs.readFile('./package.json').then((res) => JSON.parse(res.toString()));
|
} = await readPackageJSON('./package.json');
|
||||||
// expose PACKAGE_VERSION on process.env for CLI utils
|
|
||||||
config.define = { 'process.env.PACKAGE_VERSION': JSON.stringify(version) };
|
config.define = {};
|
||||||
|
for (const [key, value] of await getDefinedEntries()) {
|
||||||
|
config.define[`process.env.${key}`] = JSON.stringify(value);
|
||||||
|
}
|
||||||
const format = type === 'module' && !forceCJS ? 'esm' : 'cjs';
|
const format = type === 'module' && !forceCJS ? 'esm' : 'cjs';
|
||||||
|
|
||||||
const outdir = 'dist';
|
const outdir = 'dist';
|
||||||
|
@ -138,3 +140,44 @@ async function clean(outdir) {
|
||||||
onlyFiles: true,
|
onlyFiles: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contextual `define` values to statically replace in the built JS output.
|
||||||
|
* Available to all packages, but mostly useful for CLIs like `create-astro`.
|
||||||
|
*/
|
||||||
|
async function getDefinedEntries() {
|
||||||
|
const define = {
|
||||||
|
/** The current version (at the time of building) for the current package, such as `astro` or `@astrojs/sitemap` */
|
||||||
|
PACKAGE_VERSION: await getInternalPackageVersion('./package.json'),
|
||||||
|
/** The current version (at the time of building) for `astro` */
|
||||||
|
ASTRO_VERSION: await getInternalPackageVersion(new URL('../../packages/astro/package.json', import.meta.url)),
|
||||||
|
/** The current version (at the time of building) for `@astrojs/check` */
|
||||||
|
ASTRO_CHECK_VERSION: await getWorkspacePackageVersion('@astrojs/check'),
|
||||||
|
/** The current version (at the time of building) for `typescript` */
|
||||||
|
TYPESCRIPT_VERSION: await getWorkspacePackageVersion('typescript'),
|
||||||
|
}
|
||||||
|
for (const [key, value] of Object.entries(define)) {
|
||||||
|
if (value === undefined) {
|
||||||
|
delete define[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Object.entries(define);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function readPackageJSON(path) {
|
||||||
|
return await fs.readFile(path, { encoding: 'utf8' }).then((res) => JSON.parse(res));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getInternalPackageVersion(path) {
|
||||||
|
return readPackageJSON(path).then(res => res.version);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getWorkspacePackageVersion(packageName) {
|
||||||
|
const { dependencies, devDependencies } = await readPackageJSON(new URL('../../package.json', import.meta.url));
|
||||||
|
const deps = { ...dependencies, ...devDependencies };
|
||||||
|
const version = deps[packageName];
|
||||||
|
if (!version) {
|
||||||
|
throw new Error(`Unable to resolve "${packageName}". Is it a depdendency of the workspace root?`)
|
||||||
|
}
|
||||||
|
return version.replace(/^\D+/, '');
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue