diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 25f463c..38abcdf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,16 +54,16 @@ jobs: - 'package-lock.json' - '.github/workflows/ci.yml' aliases: [*shared, 'aliases/**'] - core: [*shared, 'core/**', 'parsefiles/**', 'fixtures/**'] + core: [*shared, 'core/**', 'fetchindex/**', 'parsefiles/**', 'fixtures/**'] fetchindex: [*shared, 'fetchindex/**'] fixtures: [*shared, 'fixtures/**'] - newest: [*shared, 'newest/**', 'core/**', 'parsefiles/**', 'fixtures/**'] - oldest: [*shared, 'oldest/**', 'core/**', 'parsefiles/**', 'fixtures/**'] + newest: [*shared, 'newest/**', 'core/**', 'fetchindex/**', 'parsefiles/**', 'fixtures/**'] + oldest: [*shared, 'oldest/**', 'core/**', 'fetchindex/**', 'parsefiles/**', 'fixtures/**'] opt: [*shared, 'opt/**'] parsefiles: [*shared, 'parsefiles/**', 'fixtures/**'] - ranges: [*shared, 'ranges/**', 'core/**', 'aliases/**', 'parsefiles/**', 'fixtures/**'] - static: [*shared, 'static/**', 'core/**', 'parsefiles/**', 'fixtures/**'] - translate: [*shared, 'translate/**', 'ranges/**', 'core/**', 'aliases/**', 'parsefiles/**', 'fixtures/**'] + ranges: [*shared, 'ranges/**', 'core/**', 'aliases/**', 'fetchindex/**', 'parsefiles/**', 'fixtures/**'] + static: [*shared, 'static/**', 'core/**', 'fetchindex/**', 'parsefiles/**', 'fixtures/**'] + translate: [*shared, 'translate/**', 'ranges/**', 'core/**', 'aliases/**', 'fetchindex/**', 'parsefiles/**', 'fixtures/**'] # the site shows core's version, which every release bumps docs: [*shared, 'docs/**', 'doc-kit.config.mjs', 'core/package.json', '.github/workflows/docs.yml'] workflows: ['.github/**'] diff --git a/core/index.js b/core/index.js index 2f8eba9..2871e82 100644 --- a/core/index.js +++ b/core/index.js @@ -2,7 +2,7 @@ const { DateTime } = require('luxon'); const semver = require('semver'); const parsefiles = require('@nodevu/parsefiles'); const optionsParser = require('./util/prod/optionsParser'); -const versionFetcher = require('./util/prod/versions'); +const versionFetcher = require('@nodevu/fetchindex'); const scheduleFetcher = require('./util/prod/schedule'); /** diff --git a/core/package.json b/core/package.json index 95301b9..54ef532 100644 --- a/core/package.json +++ b/core/package.json @@ -18,6 +18,7 @@ "/types" ], "dependencies": { + "@nodevu/fetchindex": "^1.1.0", "@nodevu/parsefiles": "^1.1.0", "@types/luxon": "^3.7.6", "luxon": "^3.5.0", diff --git a/core/test/versions.js b/core/test/versions.js deleted file mode 100644 index cbe167d..0000000 --- a/core/test/versions.js +++ /dev/null @@ -1,105 +0,0 @@ -const { deepStrictEqual, match, ok, rejects } = require('node:assert'); -const { describe, it } = require('node:test'); -const undici = require('undici'); -const versions = require('../util/prod/versions'); -const optionsParser = require('../util/prod/optionsParser'); - -// undici's types only take its own Request class, so they don't match the -// global fetch's type even though it works as one -const undiciFetch = /** @type {typeof fetch} */ ( - /** @type {unknown} */ (undici.fetch) -); - -/** @typedef {import('../util/prod/optionsParser').ParsedOptions} ParsedOptions */ - -// checks that verify the result of data returned -/** @param {import('../util/prod/versions').IndexRelease[]} data */ -function check(data) { - // the newest release can be a prerelease, like v27.0.0-alpha.0.0.0 - match(data[0].version, /^v\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$/); - match(data[0].date, /^\d{4}-\d{2}-\d{2}$/); - deepStrictEqual(Array.isArray(data[0].files), true); - ok( - data[0].npm && - data[0].v8 && - data[0].uv && - data[0].zlib && - data[0].openssl && - data[0].modules, - ); - match(data[0].npm, /^\d+\.\d+\.\d+/); - match(data[0].v8, /^\d+\.\d+\.\d+/); - match(data[0].uv, /^\d+\.\d+\.\d+/); - match(data[0].zlib, /^\d+\.\d+/); - match(data[0].openssl, /^\d+\.\d+\.\d+/); - match(data[0].modules, /^\d+$/); - // index.json has false for non-LTS releases and the line's codename for LTS - // ones - deepStrictEqual( - data[0].lts === false || /^[A-Z][a-z]+$/.test(data[0].lts), - true, - ); - deepStrictEqual([true, false].includes(data[0].security), true); -} - -// set up options object that would normally be passed to the module. the -// module only reads fetch and its own URL -const options = /** @type {ParsedOptions} */ ({ - fetch: globalThis.fetch, - urls: { - index: 'https://nodejs.org/dist/index.json', - }, -}); - -describe('under normal condiditons, versions should work', async () => { - it('should work with default options', async () => { - const data = await versions(options); - check(data); - }); - - it('should work with Undici fetch', async () => { - options.fetch = undiciFetch; - const data = await versions(options); - check(data); - }); -}); - -describe('versions should work with optionsParser', async () => { - it('should work with the default output of optionsParser', async () => { - const parsedOptions = optionsParser({}); - const data = await versions(parsedOptions); - check(data); - }); - - it('should work with a different fetch passed to optionsParser', async () => { - const parsedOptions = optionsParser({ - fetch: undiciFetch, - }); - - const data = await versions(parsedOptions); - check(data); - }); -}); - -describe('versions', async () => { - it('should reject naming the URL and status when the response is not ok', async () => { - // Arrange - const url = 'https://nodejs.org/dist/index.json'; - - // Act - const result = versions( - /** @type {ParsedOptions} */ ({ fetch: notFound, urls: { index: url } }), - ); - - // Assert - await rejects(result, { - message: `Fetching ${url} failed: 404 Not Found`, - }); - }); -}); - -// Helpers - -/** @type {typeof fetch} */ -const notFound = async () => - new Response('Not Found', { status: 404, statusText: 'Not Found' }); diff --git a/core/tsconfig.json b/core/tsconfig.json index 78be28d..dd1dcf9 100644 --- a/core/tsconfig.json +++ b/core/tsconfig.json @@ -1,5 +1,5 @@ { "extends": "../tsconfig.base.json", "include": ["index.js", "util/prod/*.js"], - "references": [{ "path": "../parsefiles" }] + "references": [{ "path": "../fetchindex" }, { "path": "../parsefiles" }] } diff --git a/core/types/util/prod/versions.d.ts b/core/types/util/prod/versions.d.ts deleted file mode 100644 index dd81f75..0000000 --- a/core/types/util/prod/versions.d.ts +++ /dev/null @@ -1,41 +0,0 @@ -/** - * A release as the Node.js release index lists it. - * - * @typedef {object} IndexRelease - * @property {string} version Such as `'v17.6.0'`. - * @property {string} date - * @property {string[]} files - * @property {string} [npm] - * @property {string} [v8] - * @property {string} [uv] - * @property {string} [zlib] - * @property {string} [openssl] - * @property {string} [modules] - * @property {string | false} lts The LTS codename, or `false`. - * @property {boolean} security - */ -export = versions; -export type IndexRelease = { - /** - * Such as `'v17.6.0'`. - */ - version: string; - date: string; - files: string[]; - npm?: string; - v8?: string; - uv?: string; - zlib?: string; - openssl?: string; - modules?: string; - /** - * The LTS codename, or `false`. - */ - lts: string | false; - security: boolean; -}; -/** - * @param {import('./optionsParser').ParsedOptions} options - * @returns {Promise} - */ -declare function versions(options: import('./optionsParser').ParsedOptions): Promise; diff --git a/core/util/prod/versions.js b/core/util/prod/versions.js deleted file mode 100644 index f6bce85..0000000 --- a/core/util/prod/versions.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * A release as the Node.js release index lists it. - * - * @typedef {object} IndexRelease - * @property {string} version Such as `'v17.6.0'`. - * @property {string} date - * @property {string[]} files - * @property {string} [npm] - * @property {string} [v8] - * @property {string} [uv] - * @property {string} [zlib] - * @property {string} [openssl] - * @property {string} [modules] - * @property {string | false} lts The LTS codename, or `false`. - * @property {boolean} security - */ - -/** - * @param {import('./optionsParser').ParsedOptions} options - * @returns {Promise} - */ -async function versions(options) { - // parse our options and set up fetch if a custom fetch is passed - const fetch = options.fetch; - const url = options.urls.index; - - // fetch the url, get the json from the fetched URL that we're going to use - const raw = await fetch(url); - - if (!raw.ok) { - throw new Error(`Fetching ${url} failed: ${raw.status} ${raw.statusText}`); - } - - const versions = await raw.json(); - - return versions; -} - -module.exports = versions; diff --git a/package-lock.json b/package-lock.json index 392344e..3f916df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -56,6 +56,7 @@ "version": "1.1.0", "license": "MIT", "dependencies": { + "@nodevu/fetchindex": "^1.1.0", "@nodevu/parsefiles": "^1.1.0", "@types/luxon": "^3.7.6", "luxon": "^3.5.0",