diff --git a/.env.template b/.env.template new file mode 100644 index 0000000000..72b87a801e --- /dev/null +++ b/.env.template @@ -0,0 +1 @@ +GITHUB_ACCESS_TOKEN=your_github_access_token \ No newline at end of file diff --git a/.gitignore b/.gitignore index 3039681104..f01e88b317 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ cypress/screenshots !.yarn/releases !.yarn/sdks !.yarn/versions +.env diff --git a/Makefile b/Makefile index 535e6f6fef..3bd01d7cd7 100644 --- a/Makefile +++ b/Makefile @@ -176,3 +176,6 @@ update-sandbox: ## Push the local version of the simple example to the sandbox r check-documentation-videos-format: ## Check the documentation format ./scripts/check-documentation-videos-format.sh + +release: ## Start the release process and publish the packages to npm using lerna + ./scripts/release.sh \ No newline at end of file diff --git a/package.json b/package.json index 499cba7418..75cafb5d02 100644 --- a/package.json +++ b/package.json @@ -21,10 +21,14 @@ "run-crm": "cd examples/crm && yarn dev", "build-crm": "cd examples/crm && yarn build", "storybook": "storybook dev -p 9010", - "build-storybook": "storybook build -c .storybook -o public --quiet" + "build-storybook": "storybook build -c .storybook -o public --quiet", + "update-changelog": "tsx scripts/update-changelog.ts", + "update-milestones": "tsx scripts/update-milestones.ts", + "create-github-release": "tsx scripts/create-github-release.ts" }, "devDependencies": { "@babel/plugin-proposal-private-property-in-object": "^7.21.11", + "@octokit/core": "^6.1.4", "@storybook/addon-actions": "^8.4.4", "@storybook/addon-controls": "^8.4.4", "@storybook/addon-storysource": "^8.4.4", @@ -37,6 +41,8 @@ "@typescript-eslint/eslint-plugin": "^5.60.0", "@typescript-eslint/parser": "^5.60.0", "cross-env": "^5.2.0", + "date-fns": "^3.6.0", + "dotenv": "^16.4.7", "eslint": "^8.19.0", "eslint-config-prettier": "^9.1.0", "eslint-config-react-app": "^7.0.1", @@ -53,6 +59,7 @@ "jest-watch-typeahead": "2.2.2", "lerna": "~7.1.3", "lint-staged": "^13.0.3", + "lodash": "^4.17.21", "lolex": "~2.3.2", "prettier": "~3.2.5", "raf": "~3.4.1", @@ -60,6 +67,7 @@ "react-dom": "^18.3.1", "storybook": "^8.4.4", "ts-jest": "^29.1.0", + "tsx": "^4.19.2", "typescript": "^5.1.3", "whatwg-fetch": "^3.0.0" }, diff --git a/scripts/create-github-release.ts b/scripts/create-github-release.ts new file mode 100644 index 0000000000..05899547b2 --- /dev/null +++ b/scripts/create-github-release.ts @@ -0,0 +1,98 @@ +import 'dotenv/config'; +import { Octokit } from '@octokit/core'; +import fs from 'fs'; +import path from 'path'; +import escapeRegExp from 'lodash/escapeRegExp'; + +const main = async () => { + if (process.env.RELEASE_DRY_RUN) { + console.log('Dry run mode is enabled'); + } + + if (!process.env.GITHUB_ACCESS_TOKEN) { + console.error( + 'Please provide the GITHUB_ACCESS_TOKEN variable in the .env file' + ); + process.exit(1); + } + + const version = process.argv[2]; + + if (!version || !version.match(/^\d{1,2}\.\d{1,2}\.\d{1,2}$/)) { + console.error(`Invalid version provided: ${version}`); + console.error('Usage: yarn run create-github-release '); + process.exit(1); + } + + const tag_name = `v${version}`; + + const octokit = new Octokit({ + auth: process.env.GITHUB_ACCESS_TOKEN, + }); + + console.log(`Fetching latest releases`); + const releases = await octokit.request( + 'GET /repos/{owner}/{repo}/releases', + { + owner: 'marmelab', + repo: 'react-admin', + } + ); + + const alreadyExistingRelease = releases.data.find( + release => release.tag_name === tag_name + ); + + if (alreadyExistingRelease) { + console.log(`Release ${version} already exists.`); + return; + } + + console.log(`Parsing changelog for release ${version}`); + + // Read the changelog file + const changelogFilePath = path.join(__dirname, '../CHANGELOG.md'); + const changelogContent = fs.readFileSync(changelogFilePath, 'utf-8'); + + // Create a regular expression to capture the changelog entries for the specified version + const safeVersion = escapeRegExp(version); + const regex = new RegExp(`## ${safeVersion}\n\n([\\s\\S]*?)\n##`, 'g'); + const match = regex.exec(changelogContent); + + if (!match) { + console.error( + `Could not find changelog entries for version ${version}` + ); + process.exit(1); + } + + const changelogEntries = match[1].trim(); + + console.log(`Creating release ${version} from tag ${tag_name}`); + + if (process.env.RELEASE_DRY_RUN) { + console.log( + 'Would have called GitHub API with', + 'POST /repos/{owner}/{repo}/releases', + { + owner: 'marmelab', + repo: 'react-admin', + tag_name, + name: version, + body: changelogEntries, + } + ); + } else { + await octokit.request('POST /repos/{owner}/{repo}/releases', { + owner: 'marmelab', + repo: 'react-admin', + tag_name, + name: version, + body: changelogEntries, + }); + } + + console.log(`Release ${version} created successfully.`); +}; + +main(); diff --git a/scripts/release.sh b/scripts/release.sh new file mode 100755 index 0000000000..de03085f2f --- /dev/null +++ b/scripts/release.sh @@ -0,0 +1,87 @@ +#!/bin/bash + +set -e + +info() { + echo -e "\033[1;34m$1\033[0m" +} + +step() { + echo "" + info "$1" +} + +if [ ! -z "$RELEASE_DRY_RUN" ]; then + echo "Dry run mode is enabled" +fi + +info "Starting the release process" + +step "make install" +make install + +step "make build" +make build + +step "manual tests: Run the EE tests" +echo "Copy the the packages folder content inside the node_modules of ra-enterprise, then run a full build and run the tests" +echo "Tip: You can use the 'copy-ra-oss-packages-to-ee.sh' script if you have it" +echo "Press Enter when this is done" +read + +step "manual tests: Run the demos" +echo "Test the 3 demos (simple, e-commerce, crm): check console & UI" +echo "Press Enter when this is done" +read + +step "manual task: Update the create-react-admin dependencies" +echo "[Minor version only] Update the dependencies to RA packages in the create-react-admin templates && commit" +echo "Press Enter when this is done" +read + +step "lerna version" +./node_modules/.bin/lerna version --force-publish --no-push + +# Get the version from package.json +npm_package_version=$(jq -r '.version' ./packages/react-admin/package.json) + +step "update-changelog" +yarn run update-changelog ${npm_package_version} +echo "Please review the ./CHANGELOG.md file and update it if needed." +echo "Press Enter when this is done" +read +if [ -z "$RELEASE_DRY_RUN" ]; then + echo "Committing the changelog" + git add CHANGELOG.md + git commit -m "Update changelog for version ${npm_package_version}" +fi + +step "git push" +if [ -z "$RELEASE_DRY_RUN" ]; then + echo "Pushing commits and tags to git" + git push origin HEAD + git push origin --tags +else + echo "dry mode -- skipping git push" +fi + +step "lerna publish" +if [ -z "$RELEASE_DRY_RUN" ]; then + # explicitly publish packages where the latest version is not present in the registry + ./node_modules/.bin/lerna publish from-package +else + echo "dry mode -- skipping lerna publish" +fi + +step "update-milestones" +yarn run update-milestones ${npm_package_version} + +step "create-github-release" +yarn run create-github-release ${npm_package_version} + +step "manual step: Update the documentation" +echo "You can use the 'copy-ra-oss-docs.sh' script if you have it" +echo "Press Enter when this is done" +read + +step "The release is done! 🎉" \ No newline at end of file diff --git a/scripts/update-changelog.ts b/scripts/update-changelog.ts new file mode 100644 index 0000000000..c172c6ef32 --- /dev/null +++ b/scripts/update-changelog.ts @@ -0,0 +1,161 @@ +import 'dotenv/config'; +import fs from 'fs'; +import path from 'path'; +import { Octokit } from '@octokit/core'; +import { OctokitResponse } from '@octokit/types'; +import { components } from '@octokit/openapi-types'; + +const prOrder = [ + 'feature', + 'fix', + '[doc]', + '[typescript]', + '[demo]', + '[website]', + '[storybook]', + '[chore]', + 'bump', +]; + +const getOrderIndex = (title: string) => { + // First pass: check if the title contains a keyword in brackets + for (let i = 0; i < prOrder.length; i++) { + if (!prOrder[i].includes('[')) continue; + if (title.toLowerCase().includes(prOrder[i])) { + return i; + } + } + // Second pass: check for simple word matches + for (let i = 0; i < prOrder.length; i++) { + if (prOrder[i].includes('[')) continue; + // feature is a special case, as we don't really have a keyword for it + // nor words to look for + if (prOrder[i] === 'feature') continue; + if (title.toLowerCase().includes(prOrder[i])) { + return i; + } + } + // if nothing matches, let's assume it's a feature + return prOrder.indexOf('feature'); +}; + +const sortPrEntriesByTitle = (a: string, b: string) => { + const aIndex = getOrderIndex(a); + const bIndex = getOrderIndex(b); + return aIndex - bIndex; +}; + +const sortPrEntries = ( + a: components['schemas']['issue-search-result-item'], + b: components['schemas']['issue-search-result-item'] +) => sortPrEntriesByTitle(a.title, b.title); + +const fetchMilestonePrs = async (milestone_number: string) => { + const octokit = new Octokit({ + auth: process.env.GITHUB_ACCESS_TOKEN, + }); + + let milestone_prs: OctokitResponse< + { + total_count: number; + incomplete_results: boolean; + items: components['schemas']['issue-search-result-item'][]; + }, + 200 + >; + try { + milestone_prs = await octokit.request('GET /search/issues', { + q: `repo:marmelab/react-admin is:pr milestone:${milestone_number}`, + headers: { + 'X-GitHub-Api-Version': '2022-11-28', + }, + }); + } catch (error) { + console.error( + 'Error fetching PRs from GitHub. Make sure your token has the right permissions.' + ); + console.error(error); + process.exit(1); + } + + const items = milestone_prs.data.items; + + if (!items.length) { + console.error( + `Could not find any PR matching milestone ${milestone_number}.` + ); + console.error('Is the milestone correct?'); + process.exit(1); + } + + return items; +}; + +const generateChangelogContent = ( + milestone_number: string, + items: components['schemas']['issue-search-result-item'][] +) => { + const changelog_entries = items.map( + pr => + `* ${pr.title} ([#${pr.number}](${pr.html_url})) ([${pr.user.login}](${pr.user.html_url}))` + ); + + const changelogContent = `\n## ${milestone_number}\n\n${changelog_entries.join('\n')}`; + return changelogContent; +}; + +const writeChangelog = (changelogContent: string) => { + // Read the existing changelog file + const changelogFilePath = path.join(__dirname, '../CHANGELOG.md'); + const existingContent = fs.readFileSync(changelogFilePath, 'utf-8'); + + // Split the content by lines and insert the new entries after the first line + const lines = existingContent.split('\n'); + lines.splice(1, 0, changelogContent); + + // Write the updated content back to the changelog file + fs.writeFileSync(changelogFilePath, lines.join('\n')); +}; + +const main = async () => { + if (process.env.RELEASE_DRY_RUN) { + console.log('Dry run mode is enabled'); + } + + if (!process.env.GITHUB_ACCESS_TOKEN) { + console.error( + 'Please provide the GITHUB_ACCESS_TOKEN variable in the .env file' + ); + process.exit(1); + } + + const milestone_number = process.argv[2]; + + if ( + !milestone_number || + !milestone_number.match(/^\d{1,2}\.\d{1,2}\.\d{1,2}$/) + ) { + console.error(`Invalid milestone provided: ${milestone_number}`); + console.error('Usage: yarn run update-changelog '); + process.exit(1); + } + + console.log(`Generating changelog for version ${milestone_number}...`); + + const items = await fetchMilestonePrs(milestone_number); + + items.sort(sortPrEntries); + + const changelogContent = generateChangelogContent(milestone_number, items); + + if (process.env.RELEASE_DRY_RUN) { + console.log('Would have added the following entries to the changelog'); + console.log(changelogContent); + } else { + writeChangelog(changelogContent); + } + + console.log('Changelog updated successfully.'); +}; + +main(); diff --git a/scripts/update-milestones.ts b/scripts/update-milestones.ts new file mode 100644 index 0000000000..9375544e5d --- /dev/null +++ b/scripts/update-milestones.ts @@ -0,0 +1,161 @@ +import 'dotenv/config'; +import { Octokit } from '@octokit/core'; +import { addWeeks, addMonths, formatISO } from 'date-fns'; + +const main = async () => { + if (process.env.RELEASE_DRY_RUN) { + console.log('Dry run mode is enabled'); + } + + if (!process.env.GITHUB_ACCESS_TOKEN) { + console.error( + 'Please provide the GITHUB_ACCESS_TOKEN variable in the .env file' + ); + process.exit(1); + } + + const current_version = process.argv[2]; + + if ( + !current_version || + !current_version.match(/^\d{1,2}\.\d{1,2}\.\d{1,2}$/) + ) { + console.error(`Invalid version provided: ${current_version}`); + console.error('Usage: yarn run update-milestones '); + process.exit(1); + } + + const current_version_array = current_version.split('.').map(Number); + const next_patch_version = [ + current_version_array[0], + current_version_array[1], + current_version_array[2] + 1, + ].join('.'); + const next_minor_version = [ + current_version_array[0], + current_version_array[1] + 1, + 0, + ].join('.'); + + const octokit = new Octokit({ + auth: process.env.GITHUB_ACCESS_TOKEN, + }); + + console.log(`Fetching currently open milestones`); + const open_milestones = await octokit.request( + 'GET /repos/{owner}/{repo}/milestones', + { + owner: 'marmelab', + repo: 'react-admin', + state: 'open', + } + ); + + const current_milestone = open_milestones.data.find( + milestone => milestone.title === current_version + ); + if (!current_milestone) { + console.log(`No open milestone for current version ${current_version}`); + } else { + console.log(`Closing milestone for current version ${current_version}`); + + if (process.env.RELEASE_DRY_RUN) { + console.log( + 'Would have called GitHub API with', + 'PATCH /repos/{owner}/{repo}/milestones/{milestone_number}', + { + owner: 'marmelab', + repo: 'react-admin', + milestone_number: current_milestone.number, + state: 'closed', + } + ); + } else { + await octokit.request( + 'PATCH /repos/{owner}/{repo}/milestones/{milestone_number}', + { + owner: 'marmelab', + repo: 'react-admin', + milestone_number: current_milestone.number, + state: 'closed', + } + ); + } + } + + const next_patch_milestone = open_milestones.data.find( + milestone => milestone.title === next_patch_version + ); + if (next_patch_milestone) { + console.log( + `Milestone for next patch version ${next_patch_version} already exists` + ); + } else { + console.log( + `Creating milestone for next patch version ${next_patch_version}` + ); + + if (process.env.RELEASE_DRY_RUN) { + console.log( + 'Would have called GitHub API with', + 'POST /repos/{owner}/{repo}/milestones', + { + owner: 'marmelab', + repo: 'react-admin', + title: next_patch_version, + state: 'open', + due_on: formatISO(addWeeks(new Date(), 1)), + description: 'this is a test milestone, do not use', + } + ); + } else { + await octokit.request('POST /repos/{owner}/{repo}/milestones', { + owner: 'marmelab', + repo: 'react-admin', + title: next_patch_version, + state: 'open', + due_on: formatISO(addWeeks(new Date(), 1)), + description: 'this is a test milestone, do not use', + }); + } + } + + const next_minor_milestone = open_milestones.data.find( + milestone => milestone.title === next_minor_version + ); + if (next_minor_milestone) { + console.log( + `Milestone for next minor version ${next_minor_version} already exists` + ); + } else { + console.log( + `Creating milestone for next minor version ${next_minor_version}` + ); + + if (process.env.RELEASE_DRY_RUN) { + console.log( + 'Would have called GitHub API with', + 'POST /repos/{owner}/{repo}/milestones', + { + owner: 'marmelab', + repo: 'react-admin', + title: next_minor_version, + state: 'open', + due_on: formatISO(addMonths(new Date(), 1)), + description: 'this is a test milestone, do not use', + } + ); + } else { + await octokit.request('POST /repos/{owner}/{repo}/milestones', { + owner: 'marmelab', + repo: 'react-admin', + title: next_minor_version, + state: 'open', + due_on: formatISO(addMonths(new Date(), 1)), + description: 'this is a test milestone, do not use', + }); + } + } +}; + +main(); diff --git a/yarn.lock b/yarn.lock index 7df084b0a7..1c0e55c25d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1915,6 +1915,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/aix-ppc64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/aix-ppc64@npm:0.23.1" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/aix-ppc64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/aix-ppc64@npm:0.24.0" @@ -1929,6 +1936,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/android-arm64@npm:0.23.1" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/android-arm64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/android-arm64@npm:0.24.0" @@ -1943,6 +1957,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/android-arm@npm:0.23.1" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@esbuild/android-arm@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/android-arm@npm:0.24.0" @@ -1957,6 +1978,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/android-x64@npm:0.23.1" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + "@esbuild/android-x64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/android-x64@npm:0.24.0" @@ -1971,6 +1999,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/darwin-arm64@npm:0.23.1" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/darwin-arm64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/darwin-arm64@npm:0.24.0" @@ -1985,6 +2020,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/darwin-x64@npm:0.23.1" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@esbuild/darwin-x64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/darwin-x64@npm:0.24.0" @@ -1999,6 +2041,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/freebsd-arm64@npm:0.23.1" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/freebsd-arm64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/freebsd-arm64@npm:0.24.0" @@ -2013,6 +2062,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/freebsd-x64@npm:0.23.1" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/freebsd-x64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/freebsd-x64@npm:0.24.0" @@ -2027,6 +2083,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-arm64@npm:0.23.1" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/linux-arm64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/linux-arm64@npm:0.24.0" @@ -2041,6 +2104,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-arm@npm:0.23.1" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@esbuild/linux-arm@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/linux-arm@npm:0.24.0" @@ -2055,6 +2125,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ia32@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-ia32@npm:0.23.1" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/linux-ia32@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/linux-ia32@npm:0.24.0" @@ -2069,6 +2146,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-loong64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-loong64@npm:0.23.1" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + "@esbuild/linux-loong64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/linux-loong64@npm:0.24.0" @@ -2083,6 +2167,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-mips64el@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-mips64el@npm:0.23.1" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + "@esbuild/linux-mips64el@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/linux-mips64el@npm:0.24.0" @@ -2097,6 +2188,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ppc64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-ppc64@npm:0.23.1" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/linux-ppc64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/linux-ppc64@npm:0.24.0" @@ -2111,6 +2209,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-riscv64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-riscv64@npm:0.23.1" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + "@esbuild/linux-riscv64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/linux-riscv64@npm:0.24.0" @@ -2125,6 +2230,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-s390x@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-s390x@npm:0.23.1" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + "@esbuild/linux-s390x@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/linux-s390x@npm:0.24.0" @@ -2139,6 +2251,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-x64@npm:0.23.1" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + "@esbuild/linux-x64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/linux-x64@npm:0.24.0" @@ -2153,6 +2272,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/netbsd-x64@npm:0.23.1" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/netbsd-x64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/netbsd-x64@npm:0.24.0" @@ -2160,6 +2286,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/openbsd-arm64@npm:0.23.1" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/openbsd-arm64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/openbsd-arm64@npm:0.24.0" @@ -2174,6 +2307,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/openbsd-x64@npm:0.23.1" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/openbsd-x64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/openbsd-x64@npm:0.24.0" @@ -2188,6 +2328,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/sunos-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/sunos-x64@npm:0.23.1" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + "@esbuild/sunos-x64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/sunos-x64@npm:0.24.0" @@ -2202,6 +2349,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/win32-arm64@npm:0.23.1" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/win32-arm64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/win32-arm64@npm:0.24.0" @@ -2216,6 +2370,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-ia32@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/win32-ia32@npm:0.23.1" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/win32-ia32@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/win32-ia32@npm:0.24.0" @@ -2230,6 +2391,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/win32-x64@npm:0.23.1" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@esbuild/win32-x64@npm:0.24.0": version: 0.24.0 resolution: "@esbuild/win32-x64@npm:0.24.0" @@ -3503,6 +3671,13 @@ __metadata: languageName: node linkType: hard +"@octokit/auth-token@npm:^5.0.0": + version: 5.1.2 + resolution: "@octokit/auth-token@npm:5.1.2" + checksum: bd4952571d9c559ede1f6ef8f7756900256d19df0180db04da88886a05484c7e6a4397611422e4804465a82addc8c2daa21d0bb4f450403552ee81041a4046d1 + languageName: node + linkType: hard + "@octokit/core@npm:^4.2.1": version: 4.2.4 resolution: "@octokit/core@npm:4.2.4" @@ -3518,6 +3693,31 @@ __metadata: languageName: node linkType: hard +"@octokit/core@npm:^6.1.4": + version: 6.1.4 + resolution: "@octokit/core@npm:6.1.4" + dependencies: + "@octokit/auth-token": "npm:^5.0.0" + "@octokit/graphql": "npm:^8.1.2" + "@octokit/request": "npm:^9.2.1" + "@octokit/request-error": "npm:^6.1.7" + "@octokit/types": "npm:^13.6.2" + before-after-hook: "npm:^3.0.2" + universal-user-agent: "npm:^7.0.0" + checksum: bcb05e83c54f686ae55bd3793e63a1832f83cbe804586b52c61b0e18942609dcc209af501720de6f2c87dc575047645b074f4cd5822d461e892058ea9654aebc + languageName: node + linkType: hard + +"@octokit/endpoint@npm:^10.1.3": + version: 10.1.3 + resolution: "@octokit/endpoint@npm:10.1.3" + dependencies: + "@octokit/types": "npm:^13.6.2" + universal-user-agent: "npm:^7.0.2" + checksum: 096956534efee1f683b4749673c2d1673c6fbe5362b9cce553f9f4b956feaf59bde816594de72f4352f749b862d0b15bc0e2fa7fb0e198deb1fe637b5f4a8bc7 + languageName: node + linkType: hard + "@octokit/endpoint@npm:^7.0.0": version: 7.0.2 resolution: "@octokit/endpoint@npm:7.0.2" @@ -3540,6 +3740,17 @@ __metadata: languageName: node linkType: hard +"@octokit/graphql@npm:^8.1.2": + version: 8.2.0 + resolution: "@octokit/graphql@npm:8.2.0" + dependencies: + "@octokit/request": "npm:^9.1.4" + "@octokit/types": "npm:^13.8.0" + universal-user-agent: "npm:^7.0.0" + checksum: 10c91490e191554bd611d80ae4678fc3887d3cb0f56258781e04c941d3373ccdb63b518a3e6ba7a08e2777b0cb22c60c62aaa6aa138bd9052624b364c886c1db + languageName: node + linkType: hard + "@octokit/openapi-types@npm:^13.11.0": version: 13.13.1 resolution: "@octokit/openapi-types@npm:13.13.1" @@ -3554,6 +3765,13 @@ __metadata: languageName: node linkType: hard +"@octokit/openapi-types@npm:^23.0.1": + version: 23.0.1 + resolution: "@octokit/openapi-types@npm:23.0.1" + checksum: ab734ceb26343d9f051a59503b8cb5bdc7fec9ca044b60511b227179bec73141dd9144a6b2d68bcd737741881b136c1b7d5392da89ae2e35e39acc489e5eb4c1 + languageName: node + linkType: hard + "@octokit/plugin-enterprise-rest@npm:6.0.1": version: 6.0.1 resolution: "@octokit/plugin-enterprise-rest@npm:6.0.1" @@ -3604,6 +3822,15 @@ __metadata: languageName: node linkType: hard +"@octokit/request-error@npm:^6.1.6, @octokit/request-error@npm:^6.1.7": + version: 6.1.7 + resolution: "@octokit/request-error@npm:6.1.7" + dependencies: + "@octokit/types": "npm:^13.6.2" + checksum: 24bd6f98b1d7b2d4062de34777b4195d3cc4dc40c3187a0321dd588291ec5e13b5760765aacdef3a73796a529d3dec0bfb820780be6ef526a3e774d13566b5b0 + languageName: node + linkType: hard + "@octokit/request@npm:^6.0.0": version: 6.2.1 resolution: "@octokit/request@npm:6.2.1" @@ -3618,6 +3845,19 @@ __metadata: languageName: node linkType: hard +"@octokit/request@npm:^9.1.4, @octokit/request@npm:^9.2.1": + version: 9.2.1 + resolution: "@octokit/request@npm:9.2.1" + dependencies: + "@octokit/endpoint": "npm:^10.1.3" + "@octokit/request-error": "npm:^6.1.6" + "@octokit/types": "npm:^13.6.2" + fast-content-type-parse: "npm:^2.0.0" + universal-user-agent: "npm:^7.0.2" + checksum: 4ec8ae8a9f323ecbe99abde97d21916c200a48a87be7b88407a4f15f2b4fcdc19f48fd5164d3e768a4712ef0702c06e4ff7f65dac562ec7f703eb9a532aebce2 + languageName: node + linkType: hard + "@octokit/rest@npm:19.0.11": version: 19.0.11 resolution: "@octokit/rest@npm:19.0.11" @@ -3646,6 +3886,15 @@ __metadata: languageName: node linkType: hard +"@octokit/types@npm:^13.6.2, @octokit/types@npm:^13.8.0": + version: 13.8.0 + resolution: "@octokit/types@npm:13.8.0" + dependencies: + "@octokit/openapi-types": "npm:^23.0.1" + checksum: e08c2fcf10e374f18e4c9fa12a6ada33a40f112d1209012a39f0ce40ae7aa9dcf0598b6007b467f63cc4a97e7b1388d6eed34ddef61494655e08b5a95afaad97 + languageName: node + linkType: hard + "@octokit/types@npm:^7.0.0": version: 7.5.1 resolution: "@octokit/types@npm:7.5.1" @@ -6671,6 +6920,13 @@ __metadata: languageName: node linkType: hard +"before-after-hook@npm:^3.0.2": + version: 3.0.2 + resolution: "before-after-hook@npm:3.0.2" + checksum: dea640f9e88a1085372c9bcc974b7bf379267490693da92ec102a7d8b515dd1e95f00ef575a146b83ca638104c57406c3427d37bdf082f602dde4b56d05bba14 + languageName: node + linkType: hard + "better-opn@npm:^3.0.2": version: 3.0.2 resolution: "better-opn@npm:3.0.2" @@ -8755,6 +9011,13 @@ __metadata: languageName: node linkType: hard +"dotenv@npm:^16.4.7": + version: 16.4.7 + resolution: "dotenv@npm:16.4.7" + checksum: be9f597e36a8daf834452daa1f4cc30e5375a5968f98f46d89b16b983c567398a330580c88395069a77473943c06b877d1ca25b4afafcdd6d4adb549e8293462 + languageName: node + linkType: hard + "dotenv@npm:~16.3.1": version: 16.3.2 resolution: "dotenv@npm:16.3.2" @@ -9241,6 +9504,89 @@ __metadata: languageName: node linkType: hard +"esbuild@npm:~0.23.0": + version: 0.23.1 + resolution: "esbuild@npm:0.23.1" + dependencies: + "@esbuild/aix-ppc64": "npm:0.23.1" + "@esbuild/android-arm": "npm:0.23.1" + "@esbuild/android-arm64": "npm:0.23.1" + "@esbuild/android-x64": "npm:0.23.1" + "@esbuild/darwin-arm64": "npm:0.23.1" + "@esbuild/darwin-x64": "npm:0.23.1" + "@esbuild/freebsd-arm64": "npm:0.23.1" + "@esbuild/freebsd-x64": "npm:0.23.1" + "@esbuild/linux-arm": "npm:0.23.1" + "@esbuild/linux-arm64": "npm:0.23.1" + "@esbuild/linux-ia32": "npm:0.23.1" + "@esbuild/linux-loong64": "npm:0.23.1" + "@esbuild/linux-mips64el": "npm:0.23.1" + "@esbuild/linux-ppc64": "npm:0.23.1" + "@esbuild/linux-riscv64": "npm:0.23.1" + "@esbuild/linux-s390x": "npm:0.23.1" + "@esbuild/linux-x64": "npm:0.23.1" + "@esbuild/netbsd-x64": "npm:0.23.1" + "@esbuild/openbsd-arm64": "npm:0.23.1" + "@esbuild/openbsd-x64": "npm:0.23.1" + "@esbuild/sunos-x64": "npm:0.23.1" + "@esbuild/win32-arm64": "npm:0.23.1" + "@esbuild/win32-ia32": "npm:0.23.1" + "@esbuild/win32-x64": "npm:0.23.1" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 08c2ed1105cc3c5e3a24a771e35532fe6089dd24a39c10097899072cef4a99f20860e41e9294e000d86380f353b04d8c50af482483d7f69f5208481cce61eec7 + languageName: node + linkType: hard + "escalade@npm:^3.1.1, escalade@npm:^3.1.2": version: 3.2.0 resolution: "escalade@npm:3.2.0" @@ -9994,6 +10340,13 @@ __metadata: languageName: node linkType: hard +"fast-content-type-parse@npm:^2.0.0": + version: 2.0.1 + resolution: "fast-content-type-parse@npm:2.0.1" + checksum: e5ff87d75a35ae4cf377df1dca46ec49e7abbdc8513689676ecdef548b94900b50e66e516e64470035d79b9f7010ef15d98c24d8ae803a881363cc59e0715e19 + languageName: node + linkType: hard + "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" @@ -10727,6 +11080,15 @@ __metadata: languageName: node linkType: hard +"get-tsconfig@npm:^4.7.5": + version: 4.10.0 + resolution: "get-tsconfig@npm:4.10.0" + dependencies: + resolve-pkg-maps: "npm:^1.0.0" + checksum: c9b5572c5118923c491c04285c73bd55b19e214992af957c502a3be0fc0043bb421386ffd45ca3433c0a7fba81221ca300479e8393960acf15d0ed4563f38a86 + languageName: node + linkType: hard + "getos@npm:^3.2.1": version: 3.2.1 resolution: "getos@npm:3.2.1" @@ -16495,6 +16857,7 @@ __metadata: resolution: "react-admin-lerna@workspace:." dependencies: "@babel/plugin-proposal-private-property-in-object": "npm:^7.21.11" + "@octokit/core": "npm:^6.1.4" "@storybook/addon-actions": "npm:^8.4.4" "@storybook/addon-controls": "npm:^8.4.4" "@storybook/addon-storysource": "npm:^8.4.4" @@ -16507,6 +16870,8 @@ __metadata: "@typescript-eslint/eslint-plugin": "npm:^5.60.0" "@typescript-eslint/parser": "npm:^5.60.0" cross-env: "npm:^5.2.0" + date-fns: "npm:^3.6.0" + dotenv: "npm:^16.4.7" eslint: "npm:^8.19.0" eslint-config-prettier: "npm:^9.1.0" eslint-config-react-app: "npm:^7.0.1" @@ -16523,6 +16888,7 @@ __metadata: jest-watch-typeahead: "npm:2.2.2" lerna: "npm:~7.1.3" lint-staged: "npm:^13.0.3" + lodash: "npm:^4.17.21" lolex: "npm:~2.3.2" prettier: "npm:~3.2.5" raf: "npm:~3.4.1" @@ -16530,6 +16896,7 @@ __metadata: react-dom: "npm:^18.3.1" storybook: "npm:^8.4.4" ts-jest: "npm:^29.1.0" + tsx: "npm:^4.19.2" typescript: "npm:^5.1.3" whatwg-fetch: "npm:^3.0.0" dependenciesMeta: @@ -17345,6 +17712,13 @@ __metadata: languageName: node linkType: hard +"resolve-pkg-maps@npm:^1.0.0": + version: 1.0.0 + resolution: "resolve-pkg-maps@npm:1.0.0" + checksum: fb8f7bbe2ca281a73b7ef423a1cbc786fb244bd7a95cbe5c3fba25b27d327150beca8ba02f622baea65919a57e061eb5005204daa5f93ed590d9b77463a567ab + languageName: node + linkType: hard + "resolve.exports@npm:^2.0.0": version: 2.0.2 resolution: "resolve.exports@npm:2.0.2" @@ -18999,6 +19373,22 @@ __metadata: languageName: node linkType: hard +"tsx@npm:^4.19.2": + version: 4.19.2 + resolution: "tsx@npm:4.19.2" + dependencies: + esbuild: "npm:~0.23.0" + fsevents: "npm:~2.3.3" + get-tsconfig: "npm:^4.7.5" + dependenciesMeta: + fsevents: + optional: true + bin: + tsx: dist/cli.mjs + checksum: 63164b889b1d170403e4d8753a6755dec371f220f5ce29a8e88f1f4d6085a784a12d8dc2ee669116611f2c72757ac9beaa3eea5c452796f541bdd2dc11753721 + languageName: node + linkType: hard + "tuf-js@npm:^1.1.3": version: 1.1.7 resolution: "tuf-js@npm:1.1.7" @@ -19292,6 +19682,13 @@ __metadata: languageName: node linkType: hard +"universal-user-agent@npm:^7.0.0, universal-user-agent@npm:^7.0.2": + version: 7.0.2 + resolution: "universal-user-agent@npm:7.0.2" + checksum: e60517ee929813e6b3ac0ceb3c66deccafadc71341edca160279ff046319c684fd7090a60d63aa61cd34a06c2d2acebeb8c2f8d364244ae7bf8ab788e20cd8c8 + languageName: node + linkType: hard + "universalify@npm:^0.2.0": version: 0.2.0 resolution: "universalify@npm:0.2.0"