refactor: bundle shared so each consumer can require/import without hassle (#64167)

This commit is contained in:
Oliver Eyton-Williams
2026-01-19 10:45:40 +01:00
committed by GitHub
parent ddfd598eb4
commit f03ad05e84
190 changed files with 1059 additions and 437 deletions
+1 -1
View File
@@ -155,7 +155,7 @@ jobs:
- name: Install and Build
run: |
pnpm install
pnpm compile:ts
pnpm turbo compile
pnpm run build:curriculum
- name: Start apps
+1 -1
View File
@@ -138,7 +138,7 @@ jobs:
- name: Install and Build
run: |
pnpm install
pnpm compile:ts
pnpm turbo compile
pnpm run build:curriculum
- name: Start apps
-5
View File
@@ -151,10 +151,6 @@ jspm_packages/
### Netlify ###
.netlify
### Generated config files ###
shared/tsconfig.tsbuildinfo
curriculum/tsconfig.tsbuildinfo
### Old Generated files ###
# These files are no longer generated by the client, but can
# exist on older branches. Continuing to ignore them ensures they
@@ -197,7 +193,6 @@ curriculum/curricula.json
curriculum/dist
curriculum/build
curriculum/src/test/blocks-generated
shared-dist
### Playwright ###
+1 -1
View File
@@ -52,7 +52,7 @@ tasks:
cp sample.env .env &&
pnpm install &&
gp sync-done pnpm-install &&
pnpm compile:ts &&
pnpm turbo compile &&
pnpm run build:curriculum &&
gp ports await 27017
command: >
+1 -2
View File
@@ -9,15 +9,14 @@ client/public
curriculum/challenges/_meta/*/*
curriculum/challenges/**/*
curriculum/i18n-curriculum
curriculum/generated
docs/**/*.md
/playwright
pnpm-lock.yaml
shared/config/*.js
shared/config/curriculum.json
shared/utils/get-lines.js
shared/utils/get-lines.test.js
shared/utils/is-audited.js
shared/utils/validate.js
shared/utils/validate.test.js
shared-dist
dist
+2
View File
@@ -12,6 +12,7 @@
"@fastify/swagger": "9.6.1",
"@fastify/swagger-ui": "5.2.4",
"@fastify/type-provider-typebox": "6.1.0",
"@freecodecamp/shared": "workspace:*",
"@growthbook/growthbook": "1.6.2",
"@prisma/client": "6.19.1",
"@sentry/node": "9.47.1",
@@ -41,6 +42,7 @@
"description": "The freeCodeCamp.org open-source codebase and curriculum",
"devDependencies": {
"@freecodecamp/eslint-config": "workspace:*",
"@freecodecamp/shared": "workspace:*",
"@total-typescript/ts-reset": "0.6.1",
"@types/jsonwebtoken": "9.0.5",
"@types/lodash-es": "^4.17.12",
+1 -1
View File
@@ -3,7 +3,7 @@ import {
certSlugTypeMap,
certToIdMap,
Certification
} from '../../../../shared/config/certification-settings.js';
} from '@freecodecamp/shared/config/certification-settings';
import { normalizeDate } from '../../utils/normalize.js';
const fullStackCertificateIds = [
+1 -1
View File
@@ -1,6 +1,6 @@
import { isProfane } from 'no-profanity';
import { blocklistedUsernames } from '../../../../shared/config/constants.js';
import { blocklistedUsernames } from '@freecodecamp/shared/config/constants';
/**
* Checks if a username is restricted (i.e. It's profane or reserved).
+1 -1
View File
@@ -8,7 +8,7 @@ import {
vi
} from 'vitest';
import { Certification } from '../../../../shared/config/certification-settings.js';
import { Certification } from '@freecodecamp/shared/config/certification-settings';
import {
defaultUserEmail,
defaultUserId,
+1 -1
View File
@@ -13,7 +13,7 @@ import {
legacyCertifications,
legacyFullStackCertification,
upcomingCertifications
} from '../../../../shared/config/certification-settings.js';
} from '@freecodecamp/shared/config/certification-settings';
import * as schemas from '../../schemas.js';
import { normalizeChallenges, removeNulls } from '../../utils/normalize.js';
+1 -1
View File
@@ -28,7 +28,7 @@ import { Static } from '@fastify/type-provider-typebox';
import { DailyCodingChallengeLanguage } from '@prisma/client';
import request from 'supertest';
import { challengeTypes } from '../../../../shared/config/challenge-types.js';
import { challengeTypes } from '@freecodecamp/shared/config/challenge-types';
import {
defaultUserId,
devLogin,
+1 -1
View File
@@ -6,7 +6,7 @@ import { uniqBy, matches } from 'lodash-es';
import validator from 'validator';
import { challengeTypes } from '../../../../shared/config/challenge-types.js';
import { challengeTypes } from '@freecodecamp/shared/config/challenge-types';
import * as schemas from '../../schemas.js';
import {
jsCertProjectIds,
+1 -1
View File
@@ -2,7 +2,7 @@ import { type FastifyPluginCallbackTypebox } from '@fastify/type-provider-typebo
import Stripe from 'stripe';
import * as schemas from '../../schemas.js';
import { donationSubscriptionConfig } from '../../../../shared/config/donation-settings.js';
import { donationSubscriptionConfig } from '@freecodecamp/shared/config/donation-settings';
import { STRIPE_SECRET_KEY, HOME_LOCATION } from '../../utils/env.js';
/**
+1 -1
View File
@@ -3,7 +3,7 @@ import type { FastifyError, FastifyInstance } from 'fastify';
import { differenceInMinutes } from 'date-fns';
import validator from 'validator';
import { isValidUsername } from '../../../../shared/utils/validate.js';
import { isValidUsername } from '@freecodecamp/shared/utils/validate';
import * as schemas from '../../schemas.js';
import { createAuthToken, isExpired } from '../../utils/tokens.js';
import { API_LOCATION } from '../../utils/env.js';
+1 -1
View File
@@ -8,7 +8,7 @@ import {
certToIdMap,
completionHours,
oldDataVizId
} from '../../../../shared/config/certification-settings.js';
} from '@freecodecamp/shared/config/certification-settings';
import {
getFallbackFullStackDate,
isKnownCertSlug
+1 -1
View File
@@ -5,7 +5,7 @@ import { STRIPE_SECRET_KEY } from '../../utils/env.js';
import {
donationSubscriptionConfig,
allStripeProductIdsArray
} from '../../../../shared/config/donation-settings.js';
} from '@freecodecamp/shared/config/donation-settings';
import * as schemas from '../../schemas.js';
import { inLastFiveMinutes } from '../../utils/validate-donation.js';
import { findOrCreateUser } from '../helpers/auth-helpers.js';
+1 -1
View File
@@ -21,7 +21,7 @@ import {
getPoints,
ProgressTimestamp
} from '../../utils/progress.js';
import { challengeTypes } from '../../../../shared/config/challenge-types.js';
import { challengeTypes } from '@freecodecamp/shared/config/challenge-types';
type ProfileUI = Partial<{
isLocked: boolean;
+1 -1
View File
@@ -1,5 +1,5 @@
import { Type } from '@fastify/type-provider-typebox';
import { Certification } from '../../../../shared/config/certification-settings.js';
import { Certification } from '@freecodecamp/shared/config/certification-settings';
import { genericError } from '../types.js';
export const certSlug = {
+1 -1
View File
@@ -1,7 +1,7 @@
import type { ExamResults, user, Prisma } from '@prisma/client';
import { FastifyInstance } from 'fastify';
import { omit, pick } from 'lodash-es';
import { challengeTypes } from '../../../shared/config/challenge-types.js';
import { challengeTypes } from '@freecodecamp/shared/config/challenge-types';
import { challenges, savableChallenges } from './get-challenges.js';
import { normalizeDate } from './normalize.js';
+1 -1
View File
@@ -1,5 +1,5 @@
import { Exam, Question } from '@prisma/client';
import { shuffleArray } from './../../../shared/utils/shuffle-array.js';
import { shuffleArray } from '@freecodecamp/shared/utils/shuffle-array';
import { UserExam, GeneratedExam } from './exam-types.js';
/**
+1 -1
View File
@@ -7,7 +7,7 @@ import { readFileSync } from 'fs';
import { fileURLToPath } from 'node:url';
import { join, dirname } from 'path';
const CURRICULUM_PATH = '../../../shared-dist/config/curriculum.json';
const CURRICULUM_PATH = '../../../curriculum/generated/curriculum.json';
const __dirname = dirname(fileURLToPath(import.meta.url));
// Curriculum is read using fs, because it is too large for VSCode's LSP to handle type inference which causes annoying behavior.
const curriculum = JSON.parse(
+1 -1
View File
@@ -1,6 +1,6 @@
import jwt from 'jsonwebtoken';
import { availableLangs } from '../../../shared/config/i18n.js';
import { availableLangs } from '@freecodecamp/shared/config/i18n';
import { allowedOrigins } from './allowed-origins.js';
// process.env.HOME_LOCATION is being used as a fallback here. If the one
+2 -1
View File
@@ -3,7 +3,8 @@ import {
legacyCertifications,
upcomingCertifications,
currentCertifications
} from '../../shared-dist/config/certification-settings';
} from '@freecodecamp/shared/config/certification-settings';
import config from '../config/env.json';
const { showUpcomingChanges } = config;
+1 -1
View File
@@ -5,7 +5,7 @@ const uniq = require('lodash/uniq');
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
const webpack = require('webpack');
const { SuperBlocks } = require('../shared-dist/config/curriculum');
const { SuperBlocks } = require('@freecodecamp/shared/config/curriculum');
const env = require('./config/env.json');
const {
createChallengePages,
+1 -1
View File
@@ -4,7 +4,7 @@ import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
const envData = require('../config/env.json');
const { i18nextCodes } = require('../../shared-dist/config/i18n');
const { i18nextCodes } = require('@freecodecamp/shared/config/i18n');
const { clientLocale } = envData;
+2 -2
View File
@@ -8,11 +8,11 @@ import {
availableLangs,
LangNames,
LangCodes
} from '../../shared-dist/config/i18n';
} from '@freecodecamp/shared/config/i18n';
import {
catalogSuperBlocks,
SuperBlocks
} from '../../shared-dist/config/curriculum';
} from '@freecodecamp/shared/config/curriculum';
import intro from './locales/english/intro.json';
interface Intro {
+1 -1
View File
@@ -1,6 +1,6 @@
import path from 'path';
import { readFile } from 'fs/promises';
import { availableLangs } from '../../shared-dist/config/i18n';
import { availableLangs } from '@freecodecamp/shared/config/i18n';
import introSchema from './locales/english/intro.json';
import linksSchema from './locales/english/links.json';
import metaTagsSchema from './locales/english/meta-tags.json';
+2 -1
View File
@@ -24,7 +24,7 @@
"build:scripts": "pnpm run -F=browser-scripts build",
"build:external-curriculum": "tsx ./tools/external-curriculum/build",
"clean": "gatsby clean",
"common-setup": "pnpm -w run compile:ts && pnpm run create:env && pnpm run create:trending && pnpm run create:search-placeholder",
"common-setup": "pnpm -w turbo compile && pnpm run create:env && pnpm run create:trending && pnpm run create:search-placeholder",
"create:env": "DEBUG=fcc:* tsx ./tools/create-env.ts",
"create:trending": "tsx ./tools/download-trending.ts",
"create:search-placeholder": "tsx ./tools/generate-search-placeholder",
@@ -139,6 +139,7 @@
"devDependencies": {
"@babel/plugin-syntax-dynamic-import": "7.8.3",
"@freecodecamp/eslint-config": "workspace:*",
"@freecodecamp/shared": "workspace:*",
"@testing-library/jest-dom": "^6.8.0",
"@testing-library/react": "12.1.5",
"@testing-library/react-hooks": "^8.0.1",
+1 -1
View File
@@ -1,7 +1,7 @@
import {
DonationAmount,
DonationDuration
} from '../../../shared-dist/config/donation-settings';
} from '@freecodecamp/shared/config/donation-settings';
import { ChallengeFiles } from '../redux/prop-types';
import TagManager from '.';
+1 -1
View File
@@ -3,7 +3,7 @@ import {
A1SpanishChapters,
FsdChapters,
A1ChineseChapters
} from '../../../shared-dist/config/chapters';
} from '@freecodecamp/shared/config/chapters';
import DatabaseIcon from './icons/database';
import JavaScriptIcon from './icons/javascript';
import ReactIcon from './icons/react';
+1 -1
View File
@@ -1,5 +1,5 @@
import React from 'react';
import { SuperBlocks } from '../../../shared-dist/config/curriculum';
import { SuperBlocks } from '@freecodecamp/shared/config/curriculum';
import APIIcon from './icons/api';
import D3Icon from './icons/d3';
import DatabaseIcon from './icons/database';
@@ -8,7 +8,7 @@ import { createSelector } from 'reselect';
import { Container, Col, Row, Image, Button, Spacer } from '@freecodecamp/ui';
import envData from '../../config/env.json';
import { getLangCode } from '../../../shared-dist/config/i18n';
import { getLangCode } from '@freecodecamp/shared/config/i18n';
import FreeCodeCampLogo from '../assets/icons/freecodecamp-logo';
import MicrosoftLogo from '../assets/icons/microsoft-logo';
import { createFlashMessage } from '../components/Flash/redux';
@@ -33,13 +33,13 @@ import {
standardErrorMessage
} from '../utils/error-messages';
import { PaymentContext } from '../../../shared-dist/config/donation-settings';
import { PaymentContext } from '@freecodecamp/shared/config/donation-settings';
import ribbon from '../assets/images/ribbon.svg';
import {
Certification,
CertSlug,
linkedInCredentialIds
} from '../../../shared-dist/config/certification-settings';
} from '@freecodecamp/shared/config/certification-settings';
import MultiTierDonationForm from '../components/Donation/multi-tier-donation-form';
import callGA from '../analytics/call-ga';
import ShowProjectLinks from './show-project-links';
@@ -19,9 +19,9 @@ import ExamResultsModal from '../components/SolutionViewer/exam-results-modal';
import { openModal } from '../templates/Challenges/redux/actions';
import { regenerateMissingProperties } from '../../../shared-dist/utils/polyvinyl';
import { regenerateMissingProperties } from '@freecodecamp/shared/utils/polyvinyl';
import '../components/layouts/project-links.css';
import { Certification } from '../../../shared-dist/config/certification-settings';
import { Certification } from '@freecodecamp/shared/config/certification-settings';
interface ShowProjectLinksProps {
certSlug: Certification;
name: string;
@@ -12,7 +12,7 @@ import {
defaultDonation,
DonationAmount,
type DonationConfig
} from '../../../../shared-dist/config/donation-settings';
} from '@freecodecamp/shared/config/donation-settings';
import { defaultDonationFormState } from '../../redux';
import { updateDonationFormState, postCharge } from '../../redux/actions';
import {
@@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next';
import { useFeature } from '@growthbook/growthbook-react';
import { Col, Row, Modal, Spacer } from '@freecodecamp/ui';
import { closeDonationModal } from '../../redux/actions';
import { PaymentContext } from '../../../../shared-dist/config/donation-settings';
import { PaymentContext } from '@freecodecamp/shared/config/donation-settings';
import donationAnimation from '../../assets/images/donation-bear-animation.svg';
import donationAnimationB from '../../assets/images/new-bear-animation.svg';
import supporterBearBlock from '../../assets/images/supporter-bear-block.svg';
@@ -18,7 +18,7 @@ import {
defaultTierAmount,
defaultTierAmountB,
type DonationAmount
} from '../../../../shared-dist/config/donation-settings'; // You can further extract these into separate components and import them
} from '@freecodecamp/shared/config/donation-settings'; // You can further extract these into separate components and import them
import callGA from '../../analytics/call-ga';
import { LocalStorageThemes } from '../../redux/types';
import { formattedAmountLabel, convertToTimeContributed } from './utils';
@@ -3,7 +3,7 @@ import {
DonationAmount,
donationUrls,
PaymentProvider
} from '../../../../shared-dist/config/donation-settings';
} from '@freecodecamp/shared/config/donation-settings';
import envData from '../../../config/env.json';
import PatreonLogo from '../../assets/images/components/patreon-logo';
import { PostPayment } from './types';
@@ -9,7 +9,7 @@ import {
PaymentProvider,
type DonationDuration,
type DonationAmount
} from '../../../../shared-dist/config/donation-settings';
} from '@freecodecamp/shared/config/donation-settings';
import envData from '../../../config/env.json';
import { userSelector, signInLoadingSelector } from '../../redux/selectors';
import { LocalStorageThemes } from '../../redux/types';
@@ -10,7 +10,7 @@ import type {
} from '@stripe/stripe-js';
import React, { useState } from 'react';
import { PaymentProvider } from '../../../../shared-dist/config/donation-settings';
import { PaymentProvider } from '@freecodecamp/shared/config/donation-settings';
import { LocalStorageThemes } from '../../redux/types';
import { DonationApprovalData, PostPayment } from './types';
+1 -1
View File
@@ -1,5 +1,5 @@
import type { PaymentIntentResult } from '@stripe/stripe-js';
import { SuperBlocks } from '../../../../shared-dist/config/curriculum';
import { SuperBlocks } from '@freecodecamp/shared/config/curriculum';
export type PaymentContext = 'modal' | 'donate page' | 'certificate';
export type PaymentProvider = 'patreon' | 'paypal' | 'stripe' | 'stripe card';
@@ -10,7 +10,7 @@ import { LocalStorageThemes } from '../../redux/types';
import {
PaymentProvider,
DonationDuration
} from '../../../../shared-dist/config/donation-settings';
} from '@freecodecamp/shared/config/donation-settings';
import { createStripePaymentIntent } from '../../utils/ajax';
import { DonationApprovalData, PostPayment } from './types';
@@ -8,7 +8,7 @@ import {
LangNames,
LangCodes,
hiddenLangs
} from '../../../../../shared-dist/config/i18n';
} from '@freecodecamp/shared/config/i18n';
import { hardGoTo as navigate } from '../../../redux/actions';
import createLanguageRedirect from '../../create-language-redirect';
import LanguageGlobe from '../../../assets/icons/language-globe';
+1 -1
View File
@@ -9,7 +9,7 @@ import {
getStageOrder,
superBlockStages,
archivedSuperBlocks
} from '../../../../shared-dist/config/curriculum';
} from '@freecodecamp/shared/config/curriculum';
import { SuperBlockIcon } from '../../assets/superblock-icon';
import LinkButton from '../../assets/icons/link-button';
import { ButtonLink, Link } from '../helpers';
+1 -1
View File
@@ -22,7 +22,7 @@ import {
updateSuperBlockStructures,
superBlockStructuresSelector
} from '../../templates/Introduction/redux';
import { getIsDailyCodingChallenge } from '../../../../shared-dist/config/challenge-types';
import { getIsDailyCodingChallenge } from '@freecodecamp/shared/config/challenge-types';
import {
isValidDateString,
formatDisplayDate
@@ -4,7 +4,7 @@ import { I18nextProvider } from 'react-i18next';
import { Provider } from 'react-redux';
import { describe, vi, test, expect } from 'vitest';
import { i18nextCodes } from '../../../shared-dist/config/i18n';
import { i18nextCodes } from '@freecodecamp/shared/config/i18n';
import i18nTestConfig from '../../i18n/config-for-tests';
import { createStore } from '../redux/create-store';
import AppMountNotifier from './app-mount-notifier';
@@ -4,7 +4,7 @@ import React from 'react';
import { useFeature } from '@growthbook/growthbook-react';
import { useTranslation } from 'react-i18next';
import { Button } from '@freecodecamp/ui';
import { challengeTypes } from '../../../../shared-dist/config/challenge-types';
import { challengeTypes } from '@freecodecamp/shared/config/challenge-types';
interface CodeAllyButtonProps {
challengeType: number;
@@ -2,7 +2,7 @@ import React from 'react';
import { useTranslation } from 'react-i18next';
import { Callout } from '@freecodecamp/ui';
import { useFeatureValue } from '@growthbook/growthbook-react';
import { SuperBlocks } from '../../../../shared-dist/config/curriculum';
import { SuperBlocks } from '@freecodecamp/shared/config/curriculum';
import { Link } from '../helpers';
type OnaNoteProps = {
@@ -11,7 +11,7 @@ import { render, screen } from '@testing-library/react';
import React from 'react';
import envData from '../../../../config/env.json';
import { getLangCode } from '../../../../../shared-dist/config/i18n';
import { getLangCode } from '@freecodecamp/shared/config/i18n';
import HeatMap from './heat-map';
const { clientLocale } = envData;
@@ -13,7 +13,7 @@ import 'react-calendar-heatmap/dist/styles.css';
import './heatmap.css';
import envData from '../../../../config/env.json';
import { getLangCode } from '../../../../../shared-dist/config/i18n';
import { getLangCode } from '@freecodecamp/shared/config/i18n';
import { User } from '../../../redux/prop-types';
import FullWidthRow from '../../helpers/full-width-row';
@@ -8,9 +8,9 @@ import { connect } from 'react-redux';
import { Table, Button, Modal, Spacer } from '@freecodecamp/ui';
import envData from '../../../../config/env.json';
import { getLangCode } from '../../../../../shared-dist/config/i18n';
import { getLangCode } from '@freecodecamp/shared/config/i18n';
import { getCertIds, getPathFromID } from '../../../../utils';
import { regenerateMissingProperties } from '../../../../../shared-dist/utils/polyvinyl';
import { regenerateMissingProperties } from '@freecodecamp/shared/utils/polyvinyl';
import CertificationIcon from '../../../assets/icons/certification';
import type {
ChallengeData,
@@ -21,7 +21,7 @@ import ExamResultsModal from '../../SolutionViewer/exam-results-modal';
import { openModal } from '../../../templates/Challenges/redux/actions';
import { Link, FullWidthRow } from '../../helpers';
import { SolutionDisplayWidget } from '../../solution-display-widget';
import { SuperBlocks } from '../../../../../shared-dist/config/curriculum';
import { SuperBlocks } from '@freecodecamp/shared/config/curriculum';
import TimelinePagination from './timeline-pagination';
const SolutionViewer = Loadable(
@@ -8,7 +8,7 @@ import { bindActionCreators } from 'redux';
import type { Dispatch } from 'redux';
import { createSelector } from 'reselect';
import { isValidUsername } from '../../../../../shared-dist/utils/validate';
import { isValidUsername } from '@freecodecamp/shared/utils/validate';
import { usernameValidationSelector } from '../../../redux/settings/selectors';
import {
validateUsername,
@@ -1,4 +1,4 @@
import { Certification } from '../../../../../../shared-dist/config/certification-settings';
import { Certification } from '@freecodecamp/shared/config/certification-settings';
import { User } from '../../../../redux/prop-types';
export const getCertifications = (user: User) => {
@@ -1,5 +1,5 @@
import type { TFunction } from 'i18next';
import { getLangCode } from '../../../../../../shared-dist/config/i18n';
import { getLangCode } from '@freecodecamp/shared/config/i18n';
import envData from '../../../../../config/env.json';
const { clientLocale } = envData;
+1 -1
View File
@@ -2,7 +2,7 @@ import { useStaticQuery, graphql } from 'gatsby';
import React from 'react';
import Helmet from 'react-helmet';
import { useTranslation } from 'react-i18next';
import { SuperBlocks } from '../../../../shared-dist/config/curriculum';
import { SuperBlocks } from '@freecodecamp/shared/config/curriculum';
interface SEOProps {
title?: string;
@@ -6,7 +6,7 @@ import { Element } from 'react-scroll';
import { connect } from 'react-redux';
import { Table, Button, Spacer } from '@freecodecamp/ui';
import { regenerateMissingProperties } from '../../../../shared-dist/utils/polyvinyl';
import { regenerateMissingProperties } from '@freecodecamp/shared/utils/polyvinyl';
import ProjectPreviewModal from '../../templates/Challenges/components/project-preview-modal';
import ExamResultsModal from '../SolutionViewer/exam-results-modal';
import { openModal } from '../../templates/Challenges/redux/actions';
@@ -22,7 +22,7 @@ import {
legacyCertifications,
upcomingCertifications,
type CertificationFlags
} from '../../../../shared-dist/config/certification-settings';
} from '@freecodecamp/shared/config/certification-settings';
import env from '../../../config/env.json';
import type {
@@ -6,7 +6,7 @@ import {
legacyCertifications,
legacyFullStackCertification,
upcomingCertifications
} from '../../../../shared-dist/config/certification-settings';
} from '@freecodecamp/shared/config/certification-settings';
import env from '../../../config/env.json';
type SettingsSidebarNavProps = {
+1 -1
View File
@@ -1,6 +1,6 @@
import React from 'react';
import { clientLocale } from '../config/env.json';
import { rtlLangs } from '../../shared-dist/config/i18n';
import { rtlLangs } from '@freecodecamp/shared/config/i18n';
interface HTMLProps {
body: string;
+1 -1
View File
@@ -2,7 +2,7 @@ import React from 'react';
import { useTranslation } from 'react-i18next';
import { Col, Spacer } from '@freecodecamp/ui';
import { ButtonLink } from '../components/helpers';
import { catalog } from '../../../shared-dist/config/catalog';
import { catalog } from '@freecodecamp/shared/config/catalog';
import { showUpcomingChanges } from '../../config/env.json';
import FourOhFour from '../components/FourOhFour';
+1 -1
View File
@@ -22,7 +22,7 @@ import {
userSelector,
donationFormStateSelector
} from '../redux/selectors';
import { PaymentContext } from '../../../shared-dist/config/donation-settings';
import { PaymentContext } from '@freecodecamp/shared/config/donation-settings';
import { DonateFormState } from '../redux/types';
import callGA from '../analytics/call-ga';
import type { User } from '../redux/prop-types';
+1 -1
View File
@@ -17,7 +17,7 @@ import {
} from '../utils/ajax';
import { stringifyDonationEvents } from '../utils/analytics-strings';
import { stripe } from '../utils/stripe';
import { PaymentProvider } from '../../../shared-dist/config/donation-settings';
import { PaymentProvider } from '@freecodecamp/shared/config/donation-settings';
import {
getSessionChallengeData,
saveCurrentCount
+1 -1
View File
@@ -11,7 +11,7 @@ import {
import store from 'store';
import { v4 as uuid } from 'uuid';
import { challengeTypes } from '../../../shared-dist/config/challenge-types';
import { challengeTypes } from '@freecodecamp/shared/config/challenge-types';
import { isGoodXHRStatus } from '../templates/Challenges/utils';
import postUpdate$ from '../templates/Challenges/utils/post-update';
import { actionTypes } from './action-types';
+1 -1
View File
@@ -6,7 +6,7 @@ import {
actionTypes as challengeTypes,
CURRENT_CHALLENGE_KEY
} from '../templates/Challenges/redux/action-types';
import { getIsDailyCodingChallenge } from '../../../shared-dist/config/challenge-types';
import { getIsDailyCodingChallenge } from '@freecodecamp/shared/config/challenge-types';
import { actionTypes, ns as MainApp } from './action-types';
import { createAppMountSaga } from './app-mount-saga';
import { createDonationSaga } from './donation-saga';
+5 -5
View File
@@ -2,11 +2,11 @@ import { HandlerProps } from 'react-reflex';
import type {
ChallengeLang,
SuperBlocks
} from '../../../shared-dist/config/curriculum';
import type { CertificationFlags } from '../../../shared-dist/config/certification-settings';
import type { Chapter } from '../../../shared-dist/config/chapters';
import { BlockLayouts, BlockLabel } from '../../../shared-dist/config/blocks';
import type { ChallengeFile, Ext } from '../../../shared-dist/utils/polyvinyl';
} from '@freecodecamp/shared/config/curriculum';
import type { CertificationFlags } from '@freecodecamp/shared/config/certification-settings';
import type { Chapter } from '@freecodecamp/shared/config/chapters';
import { BlockLayouts, BlockLabel } from '@freecodecamp/shared/config/blocks';
import type { ChallengeFile, Ext } from '@freecodecamp/shared/utils/polyvinyl';
import { type CertTitle } from '../../config/cert-and-project-map';
import { UserThemes } from './types';
+1 -1
View File
@@ -3,7 +3,7 @@ import { liveCerts } from '../../config/cert-and-project-map';
import {
certSlugTypeMap,
certToTitleMap
} from '../../../shared-dist/config/certification-settings.js';
} from '@freecodecamp/shared/config/certification-settings';
import { randomBetween } from '../utils/random-between';
import { getSessionChallengeData } from '../utils/session-storage';
+1 -1
View File
@@ -10,7 +10,7 @@ import {
import store from 'store';
import { navigate } from 'gatsby';
import { Certification } from '../../../../shared-dist/config/certification-settings';
import { Certification } from '@freecodecamp/shared/config/certification-settings';
import { createFlashMessage } from '../../components/Flash/redux';
import { liveCerts } from '../../../config/cert-and-project-map';
import {
@@ -4,7 +4,7 @@ import React from 'react';
import { useTranslation } from 'react-i18next';
import store from 'store';
import { DailyCodingChallengeLanguages } from '../../../redux/prop-types';
import { challengeTypes } from '../../../../../shared-dist/config/challenge-types';
import { challengeTypes } from '@freecodecamp/shared/config/challenge-types';
import EditorTabs from './editor-tabs';
interface ClassicLayoutProps {
@@ -4,7 +4,7 @@ import { ReflexContainer, ReflexSplitter, ReflexElement } from 'react-reflex';
import { createSelector } from 'reselect';
import { connect } from 'react-redux';
import store from 'store';
import { challengeTypes } from '../../../../../shared-dist/config/challenge-types';
import { challengeTypes } from '@freecodecamp/shared/config/challenge-types';
import {
ChallengeFiles,
DailyCodingChallengeLanguages,
@@ -34,7 +34,7 @@ import type {
} from '../../../redux/prop-types';
import { editorToneOptions } from '../../../utils/tone/editor-config';
import { editorNotes } from '../../../utils/tone/editor-notes';
import { challengeTypes } from '../../../../../shared-dist/config/challenge-types';
import { challengeTypes } from '@freecodecamp/shared/config/challenge-types';
import {
executeChallenge,
saveEditorContent,
@@ -11,7 +11,7 @@ import { editor } from 'monaco-editor';
import type { FitAddon } from 'xterm-addon-fit';
import { useFeature } from '@growthbook/growthbook-react';
import { challengeTypes } from '../../../../../shared-dist/config/challenge-types';
import { challengeTypes } from '@freecodecamp/shared/config/challenge-types';
import LearnLayout from '../../../components/layouts/learn';
import { MAX_MOBILE_WIDTH } from '../../../../config/misc';
@@ -15,7 +15,7 @@ import { useFeature } from '@growthbook/growthbook-react';
import LearnLayout from '../../../components/layouts/learn';
import ChallengeTitle from '../components/challenge-title';
import PrismFormatted from '../components/prism-formatted';
import { challengeTypes } from '../../../../../shared-dist/config/challenge-types';
import { challengeTypes } from '@freecodecamp/shared/config/challenge-types';
import CompletionModal from '../components/completion-modal';
import HelpModal from '../components/help-modal';
import Hotkeys from '../components/hotkeys';
@@ -45,7 +45,7 @@ import ProjectToolPanel from '../projects/tool-panel';
import { getChallengePaths } from '../utils/challenge-paths';
import SolutionForm from '../projects/solution-form';
import { FlashMessages } from '../../../components/Flash/redux/flash-messages';
import { SuperBlocks } from '../../../../../shared-dist/config/curriculum';
import { SuperBlocks } from '@freecodecamp/shared/config/curriculum';
import { CodeAllyDown } from '../../../components/growth-book/codeally-down';
import { postUserToken } from '../../../utils/ajax';
import RdbStep1Instructions from './rdb-step-1-instructions';
@@ -7,7 +7,7 @@ import { faMicrophone } from '@fortawesome/free-solid-svg-icons';
import { Button, Spacer } from '@freecodecamp/ui';
import { Question } from '../../../redux/prop-types';
import { openModal } from '../redux/actions';
import { SuperBlocks } from '../../../../../shared/config/curriculum';
import { SuperBlocks } from '@freecodecamp/shared/config/curriculum';
import SpeakingModal from './speaking-modal';
import ChallengeHeading from './challenge-heading';
import PrismFormatted from './prism-formatted';
@@ -17,7 +17,7 @@ import { isSpeakingModalOpenSelector } from '../redux/selectors';
import {
SuperBlocks,
superBlockToSpeechLang
} from '../../../../../shared-dist/config/curriculum';
} from '@freecodecamp/shared/config/curriculum';
import {
compareTexts,
type ComparisonResult,
@@ -10,9 +10,11 @@ import { bindActionCreators } from 'redux';
import type { Dispatch } from 'redux';
import { createSelector } from 'reselect';
import { Container, Col, Row, Button, Spacer } from '@freecodecamp/ui';
import ShortcutsModal from '../components/shortcuts-modal';
import { ChallengeLang } from '@freecodecamp/shared/config/curriculum';
// Local Utilities
import ShortcutsModal from '../components/shortcuts-modal';
import LearnLayout from '../../../components/layouts/learn';
import { ChallengeNode, ChallengeMeta, Test } from '../../../redux/prop-types';
import Hotkeys from '../components/hotkeys';
@@ -38,7 +40,6 @@ import { replaceAppleQuotes } from '../../../utils/replace-apple-quotes';
import { parseHanziPinyinPairs } from './parse-blanks';
import './show.css';
import { ChallengeLang } from '../../../../../shared-dist/config/curriculum';
// Redux Setup
const mapStateToProps = createSelector(
@@ -13,7 +13,7 @@ import {
Spacer
} from '@freecodecamp/ui';
import { isMicrosoftTranscriptLink } from '../../../../../shared-dist/utils/validate';
import { isMicrosoftTranscriptLink } from '@freecodecamp/shared/utils/validate';
import {
linkMsUsername,
unlinkMsUsername,
@@ -2,7 +2,7 @@ import React, { Component } from 'react';
import { withTranslation } from 'react-i18next';
import type { WithTranslation } from 'react-i18next';
import { challengeTypes } from '../../../../../shared-dist/config/challenge-types';
import { challengeTypes } from '@freecodecamp/shared/config/challenge-types';
import {
StrictSolutionForm,
ValidatedValues
@@ -19,7 +19,7 @@ import {
} from '@freecodecamp/ui';
// Local Utilities
import { shuffleArray } from '../../../../../shared-dist/utils/shuffle-array';
import { shuffleArray } from '@freecodecamp/shared/utils/shuffle-array';
import LearnLayout from '../../../components/layouts/learn';
import { ChallengeNode, ChallengeMeta, Test } from '../../../redux/prop-types';
import ChallengeDescription from '../components/challenge-description';
@@ -15,7 +15,7 @@ import {
transformHeadTailAndContents,
compileHeadTail,
createSource
} from '../../../../../shared-dist/utils/polyvinyl';
} from '@freecodecamp/shared/utils/polyvinyl';
import { WorkerExecutor } from '../utils/worker-executor';
import {
compileTypeScriptCode,
@@ -3,7 +3,7 @@ import { of } from 'rxjs';
import { filter, ignoreElements, map, switchMap, tap } from 'rxjs/operators';
import store from 'store';
import { isPoly, setContent } from '../../../../../shared-dist/utils/polyvinyl';
import { isPoly, setContent } from '@freecodecamp/shared/utils/polyvinyl';
import { createFlashMessage } from '../../../components/Flash/redux';
import { FlashMessages } from '../../../components/Flash/redux/flash-messages';
import { savedChallengesSelector } from '../../../redux/selectors';
@@ -11,7 +11,7 @@ import { actionTypes as appTypes } from '../../../redux/action-types';
import {
getIsDailyCodingChallenge,
getDailyCodingChallengeLanguage
} from '../../../../../shared-dist/config/challenge-types';
} from '@freecodecamp/shared/config/challenge-types';
import { actionTypes } from './action-types';
import { noStoredCodeFound, updateFile } from './actions';
import { challengeFilesSelector, challengeMetaSelector } from './selectors';
@@ -20,7 +20,7 @@ import {
getIsDailyCodingChallenge,
getDailyCodingChallengeLanguage,
submitTypes
} from '../../../../../shared-dist/config/challenge-types';
} from '@freecodecamp/shared/config/challenge-types';
import { actionTypes as submitActionTypes } from '../../../redux/action-types';
import {
allowSectionDonationRequests,
@@ -34,7 +34,7 @@ import { isSignedInSelector, userSelector } from '../../../redux/selectors';
import { mapFilesToChallengeFiles } from '../../../utils/ajax';
import { standardizeRequestBody } from '../../../utils/challenge-request-helpers';
import postUpdate$ from '../utils/post-update';
import { chapterBasedSuperBlocks } from '../../../../../shared-dist/config/curriculum';
import { chapterBasedSuperBlocks } from '@freecodecamp/shared/config/curriculum';
import { actionTypes } from './action-types';
import {
closeModal,
@@ -4,7 +4,7 @@ import { mapTo, tap } from 'rxjs/operators';
import envData from '../../../../config/env.json';
import { transformEditorLink } from '../utils';
import { challengeTypes } from '../../../../../shared-dist/config/challenge-types';
import { challengeTypes } from '@freecodecamp/shared/config/challenge-types';
import { actionTypes } from './action-types';
import { closeModal } from './actions';
import {
@@ -14,7 +14,7 @@ import {
takeLatest
} from 'redux-saga/effects';
import { challengeTypes } from '../../../../../shared-dist/config/challenge-types';
import { challengeTypes } from '@freecodecamp/shared/config/challenge-types';
import { createFlashMessage } from '../../../components/Flash/redux';
import { FlashMessages } from '../../../components/Flash/redux/flash-messages';
import {
@@ -1,7 +1,7 @@
import { isEmpty } from 'lodash-es';
import { handleActions } from 'redux-actions';
import { getLines } from '../../../../../shared-dist/utils/get-lines';
import { getLines } from '@freecodecamp/shared/utils/get-lines';
import { getTargetEditor } from '../utils/get-target-editor';
import { actionTypes, ns } from './action-types';
import codeStorageEpic from './code-storage-epic';
@@ -1,5 +1,5 @@
import { createSelector } from 'reselect';
import { challengeTypes } from '../../../../../shared-dist/config/challenge-types';
import { challengeTypes } from '@freecodecamp/shared/config/challenge-types';
import {
completedChallengesSelector,
allChallengesInfoSelector,
@@ -1,4 +1,4 @@
import { challengeTypes } from '../../../../../shared-dist/config/challenge-types';
import { challengeTypes } from '@freecodecamp/shared/config/challenge-types';
import type { ChallengeFile } from '../../../redux/prop-types';
import { concatHtml } from '../rechallenge/builders';
@@ -3,7 +3,7 @@ import { isEmpty } from 'lodash';
import { Button } from '@freecodecamp/ui';
import { Link } from '../../../components/helpers';
import type { BlockLabel as BlockLabelType } from '../../../../../shared-dist/config/blocks';
import type { BlockLabel as BlockLabelType } from '@freecodecamp/shared/config/blocks';
import { ProgressBar } from '../../../components/Progress/progress-bar';
import DropDown from '../../../assets/icons/dropdown';
import CheckMark from './check-mark';
@@ -1,6 +1,6 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { BlockLabel as BlockLabelType } from '../../../../../shared-dist/config/blocks';
import { BlockLabel as BlockLabelType } from '@freecodecamp/shared/config/blocks';
interface BlockLabelProps {
blockLabel: BlockLabelType;
@@ -2,7 +2,7 @@ import React from 'react';
import { render, screen } from '@testing-library/react';
import { describe, it, expect, afterEach, vi, Mock } from 'vitest';
import type { TFunction } from 'i18next';
import { SuperBlocks } from '../../../../../shared-dist/config/curriculum';
import { SuperBlocks } from '@freecodecamp/shared/config/curriculum';
import {
ChallengeFiles,
PrerequisiteChallenge,
@@ -12,14 +12,11 @@ import {
FileKeyChallenge,
BilibiliIds
} from '../../../redux/prop-types';
import { isAuditedSuperBlock } from '../../../../../shared-dist/utils/is-audited';
import {
BlockLayouts,
BlockLabel
} from '../../../../../shared-dist/config/blocks';
import { isAuditedSuperBlock } from '@freecodecamp/shared/utils/is-audited';
import { BlockLayouts, BlockLabel } from '@freecodecamp/shared/config/blocks';
import { Block } from './block';
vi.mock('../../../../../shared-dist/utils/is-audited', () => ({
vi.mock('@freecodecamp/shared/utils/is-audited', () => ({
isAuditedSuperBlock: vi.fn().mockReturnValueOnce(true)
}));
@@ -7,13 +7,13 @@ import { bindActionCreators, Dispatch } from 'redux';
import { createSelector } from 'reselect';
import { Spacer } from '@freecodecamp/ui';
import { challengeTypes } from '../../../../../shared-dist/config/challenge-types';
import { challengeTypes } from '@freecodecamp/shared/config/challenge-types';
import {
chapterBasedSuperBlocks,
SuperBlocks
} from '../../../../../shared-dist/config/curriculum';
} from '@freecodecamp/shared/config/curriculum';
import envData from '../../../../config/env.json';
import { isAuditedSuperBlock } from '../../../../../shared-dist/utils/is-audited';
import { isAuditedSuperBlock } from '@freecodecamp/shared/utils/is-audited';
import Caret from '../../../assets/icons/caret';
import { Link } from '../../../components/helpers';
import { completedChallengesSelector } from '../../../redux/selectors';
@@ -23,7 +23,7 @@ import { isProjectBased } from '../../../utils/curriculum-layout';
import {
BlockLayouts,
BlockLabel as BlockLabelType
} from '../../../../../shared-dist/config/blocks';
} from '@freecodecamp/shared/config/blocks';
import CheckMark from './check-mark';
import {
GridMapChallenges,
@@ -7,8 +7,8 @@ import { Button } from '@freecodecamp/ui';
import {
type Certification,
superBlockToCertMap
} from '../../../../../shared-dist/config/certification-settings';
import { SuperBlocks } from '../../../../../shared-dist/config/curriculum';
} from '@freecodecamp/shared/config/certification-settings';
import { SuperBlocks } from '@freecodecamp/shared/config/curriculum';
import {
isSignedInSelector,
@@ -3,8 +3,8 @@ import { useTranslation } from 'react-i18next';
import GreenNotCompleted from '../../../assets/icons/green-not-completed';
import GreenPass from '../../../assets/icons/green-pass';
import { SuperBlocks } from '../../../../../shared-dist/config/curriculum';
import { challengeTypes } from '../../../../../shared-dist/config/challenge-types';
import { SuperBlocks } from '@freecodecamp/shared/config/curriculum';
import { challengeTypes } from '@freecodecamp/shared/config/challenge-types';
import { Link } from '../../../components/helpers';
import { ButtonLink } from '../../../components/helpers/button-link';
@@ -1,8 +1,8 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Spacer } from '@freecodecamp/ui';
import { SuperBlocks } from '../../../../../shared-dist/config/curriculum';
import { isAuditedSuperBlock } from '../../../../../shared-dist/utils/is-audited';
import { SuperBlocks } from '@freecodecamp/shared/config/curriculum';
import { isAuditedSuperBlock } from '@freecodecamp/shared/utils/is-audited';
import { Link } from '../../../components/helpers';
import envData from '../../../../config/env.json';
@@ -1,7 +1,7 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Callout } from '@freecodecamp/ui';
import { SuperBlocks } from '../../../../../shared-dist/config/curriculum';
import { SuperBlocks } from '@freecodecamp/shared/config/curriculum';
import { isRelationalDbCert, isExamCert } from '../../../utils/is-a-cert';
import { CodeAllyDown } from '../../../components/growth-book/codeally-down';
@@ -1,12 +1,9 @@
import React from 'react';
import { render, screen, within } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import { SuperBlocks } from '../../../../../shared-dist/config/curriculum';
import { SuperBlocks } from '@freecodecamp/shared/config/curriculum';
import { SuperBlockAccordion } from './super-block-accordion';
import {
BlockLabel,
BlockLayouts
} from '../../../../../shared-dist/config/blocks';
import { BlockLabel, BlockLayouts } from '@freecodecamp/shared/config/blocks';
const mockStructure = {
superBlock: SuperBlocks.RespWebDesign,
@@ -3,18 +3,15 @@ import { useTranslation } from 'react-i18next';
// TODO: Add this component to freecodecamp/ui and remove this dependency
import { Disclosure } from '@headlessui/react';
import { SuperBlocks } from '../../../../../shared-dist/config/curriculum';
import { SuperBlocks } from '@freecodecamp/shared/config/curriculum';
import DropDown from '../../../assets/icons/dropdown';
import type { ChapterBasedSuperBlockStructure } from '../../../redux/prop-types';
import { ChapterIcon } from '../../../assets/chapter-icon';
import { type Chapter } from '../../../../../shared-dist/config/chapters';
import { type Chapter } from '@freecodecamp/shared/config/chapters';
import { Link } from '../../../components/helpers';
import {
BlockLayouts,
BlockLabel
} from '../../../../../shared-dist/config/blocks';
import { FsdChapters } from '../../../../../shared-dist/config/chapters';
import { type Module } from '../../../../../shared-dist/config/modules';
import { BlockLayouts, BlockLabel } from '@freecodecamp/shared/config/blocks';
import { FsdChapters } from '@freecodecamp/shared/config/chapters';
import { type Module } from '@freecodecamp/shared/config/modules';
import envData from '../../../../config/env.json';
import Block from './block';
import CheckMark from './check-mark';
@@ -4,7 +4,7 @@ import { Callout, Spacer, Container, Row, Col } from '@freecodecamp/ui';
import {
archivedSuperBlocks,
SuperBlocks
} from '../../../../../shared-dist/config/curriculum';
} from '@freecodecamp/shared/config/curriculum';
import { SuperBlockIcon } from '../../../assets/superblock-icon';
import { Link } from '../../../components/helpers';
import CapIcon from '../../../assets/icons/cap';
@@ -6,7 +6,7 @@ import {
certificationCollectionSuperBlocks,
chapterBasedSuperBlocks,
SuperBlocks
} from '../../../../../shared-dist/config/curriculum';
} from '@freecodecamp/shared/config/curriculum';
import type { CertTitle } from '../../../../config/cert-and-project-map';
import type {
ChapterBasedSuperBlockStructure,
@@ -15,14 +15,14 @@ import type {
import type {
BlockLabel,
BlockLayouts
} from '../../../../../shared-dist/config/blocks';
} from '@freecodecamp/shared/config/blocks';
import { SuperBlockIcon } from '../../../assets/superblock-icon';
import { Link } from '../../../components/helpers';
import {
certSlugTypeMap,
certificationRequirements,
superBlockToCertMap
} from '../../../../../shared-dist/config/certification-settings';
} from '@freecodecamp/shared/config/certification-settings';
import CheckMark from './check-mark';
import Block from './block';
@@ -144,11 +144,8 @@ vi.mock('../../components/helpers', () => ({
)
}));
import {
BlockLabel,
BlockLayouts
} from '../../../../shared-dist/config/blocks';
import { SuperBlocks } from '../../../../shared-dist/config/curriculum';
import { BlockLabel, BlockLayouts } from '@freecodecamp/shared/config/blocks';
import { SuperBlocks } from '@freecodecamp/shared/config/curriculum';
import SuperBlockIntroductionPage from './super-block-intro';
type ChallengeNode = {
@@ -15,7 +15,7 @@ import { useFeatureValue } from '@growthbook/growthbook-react';
import {
SuperBlocks,
certificationCollectionSuperBlocks
} from '../../../../shared-dist/config/curriculum';
} from '@freecodecamp/shared/config/curriculum';
import DonateModal from '../../components/Donation/donation-modal';
import Login from '../../components/Header/components/login';
import Map from '../../components/Map';
@@ -34,11 +34,8 @@ import type {
ChapterBasedSuperBlockStructure
} from '../../redux/prop-types';
import { CertTitle, liveCerts } from '../../../config/cert-and-project-map';
import { superBlockToCertMap } from '../../../../shared-dist/config/certification-settings';
import {
BlockLayouts,
BlockLabel
} from '../../../../shared-dist/config/blocks';
import { superBlockToCertMap } from '@freecodecamp/shared/config/certification-settings';
import { BlockLayouts, BlockLabel } from '@freecodecamp/shared/config/blocks';
import LegacyLinks from './components/legacy-links';
import HelpTranslate from './components/help-translate';
import SuperBlockIntro from './components/super-block-intro';
@@ -1,5 +1,5 @@
import { challengeFiles } from '../../../utils/__fixtures__/challenges';
import { challengeTypes } from '../../../../shared-dist/config/challenge-types';
import { challengeTypes } from '@freecodecamp/shared/config/challenge-types';
const baseChallenge = {
id: '1',
+1 -1
View File
@@ -13,7 +13,7 @@ import type {
SurveyResults,
User
} from '../redux/prop-types';
import { DonationDuration } from '../../../shared-dist/config/donation-settings';
import { DonationDuration } from '@freecodecamp/shared/config/donation-settings';
const { apiLocation } = envData;

Some files were not shown because too many files have changed in this diff Show More