mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-10 04:22:27 +10:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 30fd283898 | |||
| 726ea7312b | |||
| f3a7180d4b | |||
| 0173ce32c3 | |||
| d4b6c16bf9 | |||
| c571f201d3 | |||
| e4ecf50ed4 |
@ -2,6 +2,7 @@
|
||||
/app
|
||||
|
||||
# Build Artifacts
|
||||
/schema/dist
|
||||
/server/dist
|
||||
/client/.next
|
||||
|
||||
|
||||
@ -1,12 +1,23 @@
|
||||
{
|
||||
"ignorePatterns": ["/app"],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"extends": ["plugin:@typescript-eslint/recommended"],
|
||||
"plugins": ["@typescript-eslint/eslint-plugin", "simple-import-sort"],
|
||||
"plugins": ["@typescript-eslint/eslint-plugin", "unused-imports", "simple-import-sort"],
|
||||
"rules": {
|
||||
// ESLint
|
||||
"no-unused-vars": "off",
|
||||
|
||||
// Unused Imports
|
||||
"unused-imports/no-unused-imports": "error",
|
||||
"unused-imports/no-unused-vars": [
|
||||
"warn",
|
||||
{
|
||||
"vars": "all",
|
||||
"args": "none",
|
||||
"varsIgnorePattern": "^_",
|
||||
"argsIgnorePattern": "^_"
|
||||
}
|
||||
],
|
||||
|
||||
// Simple Import Sort
|
||||
"simple-import-sort/imports": "error",
|
||||
"simple-import-sort/exports": "error",
|
||||
|
||||
7
.github/workflows/docker-build-push.yml
vendored
7
.github/workflows/docker-build-push.yml
vendored
@ -13,6 +13,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
image: [client, server]
|
||||
arch: [linux/amd64, linux/arm64]
|
||||
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
@ -25,7 +26,7 @@ jobs:
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2.1.0
|
||||
with:
|
||||
platforms: amd64
|
||||
platforms: ${{ matrix.arch }}
|
||||
|
||||
- id: buildx
|
||||
name: Set up Docker Buildx
|
||||
@ -49,8 +50,10 @@ jobs:
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
platforms: linux/amd64
|
||||
platforms: ${{ matrix.arch }}
|
||||
file: ${{ matrix.image }}/Dockerfile
|
||||
build-args: |
|
||||
TURBO_TOKEN=${{ secrets.TURBO_TOKEN }}
|
||||
tags: |
|
||||
amruthpillai/reactive-resume:${{ matrix.image }}-latest
|
||||
amruthpillai/reactive-resume:${{ matrix.image }}-${{ steps.version.outputs.current-version }}
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,6 +1,7 @@
|
||||
# Environment Variables
|
||||
.env
|
||||
.env.*
|
||||
*.env
|
||||
!.env.gitpod
|
||||
!.env.example
|
||||
|
||||
@ -12,3 +13,6 @@ node_modules
|
||||
|
||||
# Intellij
|
||||
.idea
|
||||
|
||||
# Turborepo
|
||||
.turbo
|
||||
@ -21,8 +21,10 @@ COPY --from=dependencies /app/node_modules ./node_modules
|
||||
COPY --from=dependencies /app/schema/node_modules ./schema/node_modules
|
||||
COPY --from=dependencies /app/client/node_modules ./client/node_modules
|
||||
|
||||
RUN pnpm run --filter schema build \
|
||||
&& pnpm run --filter client build
|
||||
ARG TURBO_TOKEN
|
||||
ENV TURBO_TOKEN=$TURBO_TOKEN
|
||||
|
||||
RUN pnpm exec turbo --filter client build
|
||||
|
||||
FROM base as production
|
||||
|
||||
@ -40,7 +42,4 @@ EXPOSE 3000
|
||||
|
||||
ENV PORT 3000
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=20s --retries=3 --start-period=15s \
|
||||
CMD curl -fSs localhost:3000 || exit 1
|
||||
|
||||
CMD [ "pnpm", "run", "start" ]
|
||||
CMD [ "pnpm", "run", "--filter", "client", "start" ]
|
||||
43
client/Dockerfile.standalone
Normal file
43
client/Dockerfile.standalone
Normal file
@ -0,0 +1,43 @@
|
||||
FROM node:18-alpine AS base
|
||||
|
||||
FROM base AS deps
|
||||
RUN apk add --no-cache libc6-compat
|
||||
WORKDIR /app
|
||||
|
||||
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
|
||||
RUN \
|
||||
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
|
||||
elif [ -f package-lock.json ]; then npm ci; \
|
||||
elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i --frozen-lockfile; \
|
||||
else echo "Lockfile not found." && exit 1; \
|
||||
fi
|
||||
|
||||
FROM base AS builder
|
||||
WORKDIR /app
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
|
||||
ENV NEXT_TELEMETRY_DISABLED 1
|
||||
|
||||
RUN yarn global add pnpm && pnpm build
|
||||
|
||||
FROM base AS runner
|
||||
WORKDIR /app
|
||||
|
||||
ENV NODE_ENV production
|
||||
ENV NEXT_TELEMETRY_DISABLED 1
|
||||
|
||||
RUN addgroup --system --gid 1001 nodejs
|
||||
RUN adduser --system --uid 1001 nextjs
|
||||
|
||||
COPY --from=builder /app/public ./public
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||
|
||||
USER nextjs
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
ENV PORT 3000
|
||||
|
||||
CMD ["node", "client/server.js"]
|
||||
@ -20,7 +20,6 @@ import {
|
||||
useMediaQuery,
|
||||
useTheme,
|
||||
} from '@mui/material';
|
||||
import { Resume } from '@reactive-resume/schema';
|
||||
import clsx from 'clsx';
|
||||
import get from 'lodash/get';
|
||||
import { useRouter } from 'next/router';
|
||||
@ -28,6 +27,7 @@ import { useTranslation } from 'next-i18next';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import toast from 'react-hot-toast';
|
||||
import { useMutation } from 'react-query';
|
||||
import { Resume } from 'schema';
|
||||
|
||||
import { RESUMES_QUERY } from '@/constants/index';
|
||||
import { ServerError } from '@/services/axios';
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { CustomCSS, PageConfig, ThemeConfig, Typography } from '@reactive-resume/schema';
|
||||
import clsx from 'clsx';
|
||||
import get from 'lodash/get';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useMemo } from 'react';
|
||||
import { CustomCSS, PageConfig, ThemeConfig, Typography } from 'schema';
|
||||
|
||||
import { useAppSelector } from '@/store/hooks';
|
||||
import templateMap from '@/templates/templateMap';
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { Add, Star } from '@mui/icons-material';
|
||||
import { Button, Divider, IconButton, SwipeableDrawer, Tooltip, useMediaQuery, useTheme } from '@mui/material';
|
||||
import { Section as SectionRecord } from '@reactive-resume/schema';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import get from 'lodash/get';
|
||||
import Link from 'next/link';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import React, { ReactComponentElement, useMemo } from 'react';
|
||||
import { Section as SectionRecord } from 'schema';
|
||||
import { validate } from 'uuid';
|
||||
|
||||
import Logo from '@/components/shared/Logo';
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { Circle, Square, SquareRounded } from '@mui/icons-material';
|
||||
import { Checkbox, Divider, FormControlLabel, Slider, ToggleButton, ToggleButtonGroup } from '@mui/material';
|
||||
import { Photo, PhotoShape } from '@reactive-resume/schema';
|
||||
import get from 'lodash/get';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { Photo, PhotoShape } from 'schema';
|
||||
|
||||
import { useAppDispatch, useAppSelector } from '@/store/hooks';
|
||||
import { setResumeState } from '@/store/resume/resumeSlice';
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { Avatar, IconButton, Skeleton, Tooltip } from '@mui/material';
|
||||
import { Photo, Resume } from '@reactive-resume/schema';
|
||||
import get from 'lodash/get';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import React, { useRef } from 'react';
|
||||
import toast from 'react-hot-toast';
|
||||
import { useMutation } from 'react-query';
|
||||
import { Photo, Resume } from 'schema';
|
||||
|
||||
import { ServerError } from '@/services/axios';
|
||||
import { deletePhoto, DeletePhotoParams, uploadPhoto, UploadPhotoParams } from '@/services/resume';
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { Add } from '@mui/icons-material';
|
||||
import { Button } from '@mui/material';
|
||||
import { ListItem } from '@reactive-resume/schema';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { ListItem } from 'schema';
|
||||
|
||||
import Heading from '@/components/shared/Heading';
|
||||
import List from '@/components/shared/List';
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { Add } from '@mui/icons-material';
|
||||
import { Button } from '@mui/material';
|
||||
import { ListItem, Section as SectionRecord, SectionType } from '@reactive-resume/schema';
|
||||
import clsx from 'clsx';
|
||||
import get from 'lodash/get';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { ListItem, Section as SectionRecord, SectionType } from 'schema';
|
||||
import { validate } from 'uuid';
|
||||
|
||||
import Heading from '@/components/shared/Heading';
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import Editor from '@monaco-editor/react';
|
||||
import { useTheme } from '@mui/material';
|
||||
import { CustomCSS as CustomCSSType } from '@reactive-resume/schema';
|
||||
import clsx from 'clsx';
|
||||
import get from 'lodash/get';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import React from 'react';
|
||||
import { CustomCSS as CustomCSSType } from 'schema';
|
||||
|
||||
import Heading from '@/components/shared/Heading';
|
||||
import { useAppDispatch, useAppSelector } from '@/store/hooks';
|
||||
|
||||
@ -10,13 +10,13 @@ import {
|
||||
Switch,
|
||||
TextField,
|
||||
} from '@mui/material';
|
||||
import { DateConfig, PageConfig, Resume } from '@reactive-resume/schema';
|
||||
import dayjs from 'dayjs';
|
||||
import get from 'lodash/get';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useMutation } from 'react-query';
|
||||
import { DateConfig, PageConfig, Resume } from 'schema';
|
||||
|
||||
import Heading from '@/components/shared/Heading';
|
||||
import ThemeSwitch from '@/components/shared/ThemeSwitch';
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { ThemeConfig } from '@reactive-resume/schema';
|
||||
import get from 'lodash/get';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { ThemeConfig } from 'schema';
|
||||
|
||||
import ColorAvatar from '@/components/shared/ColorAvatar';
|
||||
import ColorPicker from '@/components/shared/ColorPicker';
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { Autocomplete, Skeleton, Slider, TextField } from '@mui/material';
|
||||
import { Font, TypeCategory, TypeProperty, Typography as TypographyType } from '@reactive-resume/schema';
|
||||
import get from 'lodash/get';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useQuery } from 'react-query';
|
||||
import { Font, TypeCategory, TypeProperty, Typography as TypographyType } from 'schema';
|
||||
|
||||
import Heading from '@/components/shared/Heading';
|
||||
import { FONTS_QUERY } from '@/constants/index';
|
||||
|
||||
@ -7,7 +7,6 @@ import {
|
||||
OpenInNew,
|
||||
} from '@mui/icons-material';
|
||||
import { ButtonBase, ListItemIcon, ListItemText, Menu, MenuItem, Tooltip } from '@mui/material';
|
||||
import { Resume } from '@reactive-resume/schema';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
@ -15,6 +14,7 @@ import { useTranslation } from 'next-i18next';
|
||||
import { useState } from 'react';
|
||||
import toast from 'react-hot-toast';
|
||||
import { useMutation } from 'react-query';
|
||||
import { Resume } from 'schema';
|
||||
|
||||
import { RESUMES_QUERY } from '@/constants/index';
|
||||
import { ServerError } from '@/services/axios';
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import { ListItem as ListItemType } from '@reactive-resume/schema';
|
||||
import clsx from 'clsx';
|
||||
import get from 'lodash/get';
|
||||
import isArray from 'lodash/isArray';
|
||||
@ -8,6 +7,7 @@ import { useTranslation } from 'next-i18next';
|
||||
import { useCallback } from 'react';
|
||||
import { DndProvider } from 'react-dnd';
|
||||
import { HTML5Backend } from 'react-dnd-html5-backend';
|
||||
import { ListItem as ListItemType } from 'schema';
|
||||
|
||||
import { useAppDispatch, useAppSelector } from '@/store/hooks';
|
||||
import { deleteItem, setResumeState } from '@/store/resume/resumeSlice';
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { DeleteOutline, DriveFileRenameOutline, FileCopy, MoreVert } from '@mui/icons-material';
|
||||
import { Divider, IconButton, ListItemIcon, ListItemText, Menu, MenuItem, Tooltip } from '@mui/material';
|
||||
import { ListItem as ListItemType } from '@reactive-resume/schema';
|
||||
import clsx from 'clsx';
|
||||
import isFunction from 'lodash/isFunction';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import React, { useRef, useState } from 'react';
|
||||
import { DropTargetMonitor, useDrag, useDrop, XYCoord } from 'react-dnd';
|
||||
import { ListItem as ListItemType } from 'schema';
|
||||
|
||||
import styles from './ListItem.module.scss';
|
||||
|
||||
|
||||
@ -58,12 +58,10 @@ const ResumeInput: React.FC<Props> = ({ type = 'text', label, path, className, m
|
||||
openTo="year"
|
||||
label={label}
|
||||
value={dayjs(value)}
|
||||
views={['year', 'month', 'day']}
|
||||
slots={{
|
||||
textField: (params) => <TextField {...params} error={false} className={className} />,
|
||||
}}
|
||||
slots={{ textField: (params) => <TextField {...params} error={false} className={className} /> }}
|
||||
onChange={(date: dayjs.Dayjs | null) => {
|
||||
date && dayjs(date).isValid() && onChangeValue(dayjs(date).format('YYYY-MM-DD'));
|
||||
if (!date) return onChangeValue('');
|
||||
if (dayjs(date).isValid()) return onChangeValue(dayjs(date).format('YYYY-MM-DD'));
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -23,8 +23,8 @@ import {
|
||||
VolunteerActivism,
|
||||
Work,
|
||||
} from '@mui/icons-material';
|
||||
import { Section as SectionRecord, SectionType } from '@reactive-resume/schema';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import { Section as SectionRecord, SectionType } from 'schema';
|
||||
|
||||
import Basics from '@/components/build/LeftSidebar/sections/Basics';
|
||||
import Location from '@/components/build/LeftSidebar/sections/Location';
|
||||
|
||||
@ -2,7 +2,7 @@ import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import { Button, TextField } from '@mui/material';
|
||||
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
|
||||
import { Award, SectionPath } from '@reactive-resume/schema';
|
||||
import { Award, SectionPath } from 'schema';
|
||||
import dayjs from 'dayjs';
|
||||
import Joi from 'joi';
|
||||
import get from 'lodash/get';
|
||||
|
||||
@ -2,7 +2,7 @@ import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import { Button, TextField } from '@mui/material';
|
||||
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
|
||||
import { Certificate, SectionPath } from '@reactive-resume/schema';
|
||||
import { Certificate, SectionPath } from 'schema';
|
||||
import dayjs from 'dayjs';
|
||||
import Joi from 'joi';
|
||||
import get from 'lodash/get';
|
||||
|
||||
@ -2,7 +2,7 @@ import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import { Button, Slider, TextField } from '@mui/material';
|
||||
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
|
||||
import { Custom } from '@reactive-resume/schema';
|
||||
import { Custom } from 'schema';
|
||||
import dayjs from 'dayjs';
|
||||
import Joi from 'joi';
|
||||
import get from 'lodash/get';
|
||||
|
||||
@ -2,7 +2,7 @@ import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import { Button, TextField } from '@mui/material';
|
||||
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
|
||||
import { Education, SectionPath } from '@reactive-resume/schema';
|
||||
import { Education, SectionPath } from 'schema';
|
||||
import dayjs from 'dayjs';
|
||||
import Joi from 'joi';
|
||||
import get from 'lodash/get';
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import { Button, TextField } from '@mui/material';
|
||||
import { Interest, SectionPath } from '@reactive-resume/schema';
|
||||
import { Interest, SectionPath } from 'schema';
|
||||
import Joi from 'joi';
|
||||
import get from 'lodash/get';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import { Button, Slider, TextField } from '@mui/material';
|
||||
import { Language, SectionPath } from '@reactive-resume/schema';
|
||||
import { Language, SectionPath } from 'schema';
|
||||
import Joi from 'joi';
|
||||
import get from 'lodash/get';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, AlternateEmail, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import { Button, TextField } from '@mui/material';
|
||||
import { Profile } from '@reactive-resume/schema';
|
||||
import { Profile } from 'schema';
|
||||
import Joi from 'joi';
|
||||
import get from 'lodash/get';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
@ -2,7 +2,7 @@ import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import { Button, TextField } from '@mui/material';
|
||||
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
|
||||
import { Project, SectionPath } from '@reactive-resume/schema';
|
||||
import { Project, SectionPath } from 'schema';
|
||||
import dayjs from 'dayjs';
|
||||
import Joi from 'joi';
|
||||
import get from 'lodash/get';
|
||||
|
||||
@ -2,7 +2,7 @@ import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import { Button, TextField } from '@mui/material';
|
||||
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
|
||||
import { Publication, SectionPath } from '@reactive-resume/schema';
|
||||
import { Publication, SectionPath } from 'schema';
|
||||
import dayjs from 'dayjs';
|
||||
import Joi from 'joi';
|
||||
import get from 'lodash/get';
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import { Button, TextField } from '@mui/material';
|
||||
import { Reference, SectionPath } from '@reactive-resume/schema';
|
||||
import { Reference, SectionPath } from 'schema';
|
||||
import Joi from 'joi';
|
||||
import get from 'lodash/get';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import { Button, Slider, TextField } from '@mui/material';
|
||||
import { SectionPath, Skill } from '@reactive-resume/schema';
|
||||
import { SectionPath, Skill } from 'schema';
|
||||
import Joi from 'joi';
|
||||
import get from 'lodash/get';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
@ -2,7 +2,7 @@ import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import { Button, TextField } from '@mui/material';
|
||||
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
|
||||
import { SectionPath, Volunteer } from '@reactive-resume/schema';
|
||||
import { SectionPath, Volunteer } from 'schema';
|
||||
import dayjs from 'dayjs';
|
||||
import Joi from 'joi';
|
||||
import get from 'lodash/get';
|
||||
|
||||
@ -2,7 +2,7 @@ import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add, DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import { Button, TextField } from '@mui/material';
|
||||
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
|
||||
import { WorkExperience } from '@reactive-resume/schema';
|
||||
import { WorkExperience } from 'schema';
|
||||
import dayjs from 'dayjs';
|
||||
import Joi from 'joi';
|
||||
import get from 'lodash/get';
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { Add } from '@mui/icons-material';
|
||||
import { Button, FormControlLabel, FormGroup, Switch, TextField } from '@mui/material';
|
||||
import { Resume } from '@reactive-resume/schema';
|
||||
import { Resume } from 'schema';
|
||||
import Joi from 'joi';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Code, ImportExport, LinkedIn, TrackChanges, UploadFile } from '@mui/icons-material';
|
||||
import { Button, Divider } from '@mui/material';
|
||||
import { Integration, Resume } from '@reactive-resume/schema';
|
||||
import { Integration, Resume } from 'schema';
|
||||
import { Trans, useTranslation } from 'next-i18next';
|
||||
import { useRef } from 'react';
|
||||
import toast from 'react-hot-toast';
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { joiResolver } from '@hookform/resolvers/joi';
|
||||
import { DriveFileRenameOutline } from '@mui/icons-material';
|
||||
import { Button, TextField } from '@mui/material';
|
||||
import { Resume } from '@reactive-resume/schema';
|
||||
import { Resume } from 'schema';
|
||||
import Joi from 'joi';
|
||||
import get from 'lodash/get';
|
||||
import noop from 'lodash/noop';
|
||||
|
||||
@ -2,5 +2,5 @@
|
||||
module.exports = {
|
||||
siteUrl: 'https://rxresu.me',
|
||||
changefreq: 'monthly',
|
||||
generateRobotsTxt: true,
|
||||
generateIndexSitemap: false,
|
||||
};
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "@reactive-resume/client",
|
||||
"name": "client",
|
||||
"scripts": {
|
||||
"dev": "react-env --prefix PUBLIC -- next dev",
|
||||
"lint": "next lint --fix",
|
||||
@ -9,74 +9,74 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@beam-australia/react-env": "^3.1.1",
|
||||
"@emotion/css": "^11.10.6",
|
||||
"@emotion/react": "^11.10.6",
|
||||
"@emotion/styled": "^11.10.6",
|
||||
"@emotion/css": "^11.11.0",
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@hello-pangea/dnd": "^16.2.0",
|
||||
"@hookform/resolvers": "3.1.0",
|
||||
"@monaco-editor/react": "^4.5.0",
|
||||
"@monaco-editor/react": "^4.5.1",
|
||||
"@mui/icons-material": "^5.11.16",
|
||||
"@mui/lab": "^5.0.0-alpha.127",
|
||||
"@mui/material": "^5.12.1",
|
||||
"@mui/system": "^5.12.1",
|
||||
"@mui/x-date-pickers": "6.2.1",
|
||||
"@react-oauth/google": "^0.10.0",
|
||||
"@mui/lab": "^5.0.0-alpha.133",
|
||||
"@mui/material": "^5.13.4",
|
||||
"@mui/system": "^5.13.2",
|
||||
"@mui/x-date-pickers": "6.6.0",
|
||||
"@react-oauth/google": "^0.11.0",
|
||||
"@reduxjs/toolkit": "^1.9.5",
|
||||
"axios": "^1.3.6",
|
||||
"axios": "^1.4.0",
|
||||
"clsx": "^1.2.1",
|
||||
"dayjs": "^1.11.7",
|
||||
"dayjs": "^1.11.8",
|
||||
"downloadjs": "^1.4.7",
|
||||
"joi": "^17.9.1",
|
||||
"joi": "^17.9.2",
|
||||
"lodash": "^4.17.21",
|
||||
"md5-hex": "^4.0.0",
|
||||
"monaco-editor": "^0.37.1",
|
||||
"monaco-editor": "^0.39.0",
|
||||
"nanoid": "3.3.4",
|
||||
"next": "13.3.0",
|
||||
"next-i18next": "^13.2.2",
|
||||
"next": "13.4.4",
|
||||
"next-i18next": "^13.3.0",
|
||||
"react": "^18.2.0",
|
||||
"react-colorful": "^5.6.1",
|
||||
"react-dnd": "16.0.1",
|
||||
"react-dnd-html5-backend": "16.0.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-hook-form": "^7.43.9",
|
||||
"react-hot-toast": "2.4.0",
|
||||
"react-icons": "^4.8.0",
|
||||
"react-hook-form": "^7.44.3",
|
||||
"react-hot-toast": "2.4.1",
|
||||
"react-icons": "^4.9.0",
|
||||
"react-markdown": "^8.0.7",
|
||||
"react-query": "^3.39.3",
|
||||
"react-redux": "^8.0.5",
|
||||
"react-zoom-pan-pinch": "^3.0.7",
|
||||
"react-redux": "^8.0.7",
|
||||
"react-zoom-pan-pinch": "^3.0.8",
|
||||
"redux": "^4.2.1",
|
||||
"redux-persist": "^6.0.0",
|
||||
"redux-saga": "^1.2.3",
|
||||
"redux-undo": "^1.0.1",
|
||||
"rehype-katex": "^6.0.2",
|
||||
"rehype-katex": "^6.0.3",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"remark-math": "^5.1.1",
|
||||
"sharp": "^0.32.0",
|
||||
"sharp": "^0.32.1",
|
||||
"uuid": "^9.0.0",
|
||||
"webfontloader": "^1.6.28"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.21.4",
|
||||
"@reactive-resume/schema": "workspace:*",
|
||||
"@babel/core": "^7.22.1",
|
||||
"schema": "workspace:*",
|
||||
"@tailwindcss/typography": "^0.5.9",
|
||||
"@types/downloadjs": "^1.4.3",
|
||||
"@types/lodash": "^4.14.194",
|
||||
"@types/node": "^18.15.12",
|
||||
"@types/react": "^18.0.37",
|
||||
"@types/react-dom": "^18.0.11",
|
||||
"@types/lodash": "^4.14.195",
|
||||
"@types/node": "^20.2.5",
|
||||
"@types/react": "^18.2.8",
|
||||
"@types/react-dom": "^18.2.4",
|
||||
"@types/react-redux": "^7.1.25",
|
||||
"@types/uuid": "^9.0.1",
|
||||
"@types/webfontloader": "^1.6.35",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"csstype": "^3.1.2",
|
||||
"eslint-config-next": "^13.3.0",
|
||||
"eslint-plugin-tailwindcss": "^3.11.0",
|
||||
"eslint-config-next": "^13.4.4",
|
||||
"eslint-plugin-tailwindcss": "^3.12.1",
|
||||
"eslint-plugin-unused-imports": "^2.0.0",
|
||||
"next-sitemap": "^4.0.7",
|
||||
"postcss": "^8.4.23",
|
||||
"sass": "^1.62.0",
|
||||
"tailwindcss": "^3.3.1",
|
||||
"typescript": "^5.0.4"
|
||||
"next-sitemap": "^4.1.3",
|
||||
"postcss": "^8.4.24",
|
||||
"sass": "^1.62.1",
|
||||
"tailwindcss": "^3.3.2",
|
||||
"typescript": "^5.1.3"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import { Resume } from '@reactive-resume/schema';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import { GetServerSideProps, NextPage } from 'next';
|
||||
import Head from 'next/head';
|
||||
@ -6,6 +5,7 @@ import { useTranslation } from 'next-i18next';
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
||||
import { useEffect } from 'react';
|
||||
import { useQuery } from 'react-query';
|
||||
import { Resume } from 'schema';
|
||||
|
||||
import Center from '@/components/build/Center/Center';
|
||||
import LeftSidebar from '@/components/build/LeftSidebar/LeftSidebar';
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { Download, Downloading } from '@mui/icons-material';
|
||||
import { ButtonBase } from '@mui/material';
|
||||
import { Resume } from '@reactive-resume/schema';
|
||||
import clsx from 'clsx';
|
||||
import dayjs from 'dayjs';
|
||||
import download from 'downloadjs';
|
||||
@ -13,6 +12,7 @@ import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
||||
import { useEffect } from 'react';
|
||||
import toast from 'react-hot-toast';
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
import { Resume } from 'schema';
|
||||
|
||||
import Page from '@/components/build/Center/Page';
|
||||
import { DEFAULT_ERROR_MESSAGE } from '@/constants/index';
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import { Resume } from '@reactive-resume/schema';
|
||||
import clsx from 'clsx';
|
||||
import get from 'lodash/get';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
@ -6,6 +5,7 @@ import { GetServerSideProps, NextPage } from 'next';
|
||||
import { useRouter } from 'next/router';
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
||||
import { useEffect } from 'react';
|
||||
import { Resume } from 'schema';
|
||||
|
||||
import Page from '@/components/build/Center/Page';
|
||||
import { fetchResumeByIdentifier } from '@/services/resume';
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { Download, Downloading } from '@mui/icons-material';
|
||||
import { ButtonBase } from '@mui/material';
|
||||
import { Resume } from '@reactive-resume/schema';
|
||||
import clsx from 'clsx';
|
||||
import dayjs from 'dayjs';
|
||||
import download from 'downloadjs';
|
||||
@ -12,6 +11,7 @@ import { useRouter } from 'next/router';
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
||||
import { useEffect } from 'react';
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
import { Resume } from 'schema';
|
||||
|
||||
import Page from '@/components/build/Center/Page';
|
||||
import { ServerError } from '@/services/axios';
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { User } from '@reactive-resume/schema';
|
||||
import { AxiosResponse } from 'axios';
|
||||
import toast from 'react-hot-toast';
|
||||
import { User } from 'schema';
|
||||
|
||||
import { logout, setAccessToken, setUser } from '@/store/auth/authSlice';
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Font } from '@reactive-resume/schema';
|
||||
import { Font } from 'schema';
|
||||
|
||||
import axios from './axios';
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Integration, Resume } from '@reactive-resume/schema';
|
||||
import { AxiosResponse } from 'axios';
|
||||
import { Integration, Resume } from 'schema';
|
||||
|
||||
import axios from './axios';
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import env from '@beam-australia/react-env';
|
||||
import { Resume } from '@reactive-resume/schema';
|
||||
import { AxiosResponse } from 'axios';
|
||||
import { Resume } from 'schema';
|
||||
|
||||
import isBrowser from '@/utils/isBrowser';
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { User } from '@reactive-resume/schema';
|
||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
||||
import { User } from 'schema';
|
||||
|
||||
type AuthState = {
|
||||
user: User | null;
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import { ListItem, Profile, Resume, Section, SectionType } from '@reactive-resume/schema';
|
||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import get from 'lodash/get';
|
||||
import merge from 'lodash/merge';
|
||||
import pick from 'lodash/pick';
|
||||
import set from 'lodash/set';
|
||||
import { ListItem, Profile, Resume, Section, SectionType } from 'schema';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
import { getSectionsByType } from '@/config/sections';
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Resume } from '@reactive-resume/schema';
|
||||
import debounce from 'lodash/debounce';
|
||||
import { select, takeLatest } from 'redux-saga/effects';
|
||||
import { Resume } from 'schema';
|
||||
|
||||
import { updateResume } from '@/services/resume';
|
||||
import { AppDispatch, RootState } from '@/store/index';
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { ThemeConfig } from '@reactive-resume/schema';
|
||||
import { ThemeConfig } from 'schema';
|
||||
import clsx from 'clsx';
|
||||
import get from 'lodash/get';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { darken } from '@mui/material';
|
||||
import { ThemeConfig } from '@reactive-resume/schema';
|
||||
import { ThemeConfig } from 'schema';
|
||||
import get from 'lodash/get';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { Cake, Email, Phone, Public, Room } from '@mui/icons-material';
|
||||
import { ThemeConfig } from '@reactive-resume/schema';
|
||||
import { ThemeConfig } from 'schema';
|
||||
import clsx from 'clsx';
|
||||
import get from 'lodash/get';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Email, Link, Phone } from '@mui/icons-material';
|
||||
import { ListItem, Section as SectionType } from '@reactive-resume/schema';
|
||||
import { ListItem, Section as SectionType } from 'schema';
|
||||
import clsx from 'clsx';
|
||||
import get from 'lodash/get';
|
||||
import isArray from 'lodash/isArray';
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { alpha } from '@mui/material';
|
||||
import { ThemeConfig } from '@reactive-resume/schema';
|
||||
import { ThemeConfig } from 'schema';
|
||||
import clsx from 'clsx';
|
||||
import get from 'lodash/get';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ThemeConfig } from '@reactive-resume/schema';
|
||||
import { ThemeConfig } from 'schema';
|
||||
import get from 'lodash/get';
|
||||
|
||||
import { useAppSelector } from '@/store/hooks';
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { Cake, Email, Phone, Public, Room } from '@mui/icons-material';
|
||||
import { alpha } from '@mui/material';
|
||||
import { ThemeConfig } from '@reactive-resume/schema';
|
||||
import { ThemeConfig } from 'schema';
|
||||
import clsx from 'clsx';
|
||||
import get from 'lodash/get';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Email, Link, Phone } from '@mui/icons-material';
|
||||
import { ListItem, Section as SectionType } from '@reactive-resume/schema';
|
||||
import { ListItem, Section as SectionType } from 'schema';
|
||||
import get from 'lodash/get';
|
||||
import isArray from 'lodash/isArray';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { alpha } from '@mui/material';
|
||||
import { ThemeConfig } from '@reactive-resume/schema';
|
||||
import { ThemeConfig } from 'schema';
|
||||
import get from 'lodash/get';
|
||||
import isArray from 'lodash/isArray';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ThemeConfig } from '@reactive-resume/schema';
|
||||
import { ThemeConfig } from 'schema';
|
||||
import get from 'lodash/get';
|
||||
|
||||
import { useAppSelector } from '@/store/hooks';
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Email, Link, Phone } from '@mui/icons-material';
|
||||
import { ListItem, Section as SectionType } from '@reactive-resume/schema';
|
||||
import { ListItem, Section as SectionType } from 'schema';
|
||||
import get from 'lodash/get';
|
||||
import isArray from 'lodash/isArray';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ThemeConfig } from '@reactive-resume/schema';
|
||||
import { ThemeConfig } from 'schema';
|
||||
import get from 'lodash/get';
|
||||
import isArray from 'lodash/isArray';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Email, Link, Phone } from '@mui/icons-material';
|
||||
import { ListItem, Section as SectionType } from '@reactive-resume/schema';
|
||||
import { ListItem, Section as SectionType } from 'schema';
|
||||
import get from 'lodash/get';
|
||||
import isArray from 'lodash/isArray';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ThemeConfig } from '@reactive-resume/schema';
|
||||
import { ThemeConfig } from 'schema';
|
||||
import get from 'lodash/get';
|
||||
|
||||
import { useAppSelector } from '@/store/hooks';
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Cake, Email, Phone, Public, Room } from '@mui/icons-material';
|
||||
import { alpha } from '@mui/material';
|
||||
import { ThemeConfig } from '@reactive-resume/schema';
|
||||
import { ThemeConfig } from 'schema';
|
||||
import get from 'lodash/get';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Email, Link, Phone } from '@mui/icons-material';
|
||||
import { ListItem, Section as SectionType } from '@reactive-resume/schema';
|
||||
import { ListItem, Section as SectionType } from 'schema';
|
||||
import get from 'lodash/get';
|
||||
import isArray from 'lodash/isArray';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { ThemeConfig } from '@reactive-resume/schema';
|
||||
import get from 'lodash/get';
|
||||
import { ThemeConfig } from 'schema';
|
||||
|
||||
import { useAppSelector } from '@/store/hooks';
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Email, Link, Phone } from '@mui/icons-material';
|
||||
import { ListItem, Section as SectionType } from '@reactive-resume/schema';
|
||||
import { ListItem, Section as SectionType } from 'schema';
|
||||
import get from 'lodash/get';
|
||||
import isArray from 'lodash/isArray';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ThemeConfig } from '@reactive-resume/schema';
|
||||
import { ThemeConfig } from 'schema';
|
||||
import get from 'lodash/get';
|
||||
|
||||
import { useAppSelector } from '@/store/hooks';
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Cake, Email, Phone, Public, Room } from '@mui/icons-material';
|
||||
import { ThemeConfig } from '@reactive-resume/schema';
|
||||
import { ThemeConfig } from 'schema';
|
||||
import clsx from 'clsx';
|
||||
import get from 'lodash/get';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Email, Link, Phone } from '@mui/icons-material';
|
||||
import { ListItem, Section as SectionType } from '@reactive-resume/schema';
|
||||
import { ListItem, Section as SectionType } from 'schema';
|
||||
import get from 'lodash/get';
|
||||
import isArray from 'lodash/isArray';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { DateRange } from '@reactive-resume/schema';
|
||||
import { DateRange } from 'schema';
|
||||
import dayjs from 'dayjs';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import isString from 'lodash/isString';
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import env from '@beam-australia/react-env';
|
||||
import { Resume } from '@reactive-resume/schema';
|
||||
import { Resume } from 'schema';
|
||||
import get from 'lodash/get';
|
||||
|
||||
type Options = {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ThemeConfig, Typography } from '@reactive-resume/schema';
|
||||
import { ThemeConfig, Typography } from 'schema';
|
||||
import { RgbColor } from 'react-colorful';
|
||||
|
||||
import { hexColorPattern } from '@/config/colors';
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ListItem, Location, PhotoFilters } from '@reactive-resume/schema';
|
||||
import { ListItem, Location, PhotoFilters } from 'schema';
|
||||
import clsx from 'clsx';
|
||||
import get from 'lodash/get';
|
||||
import isArray from 'lodash/isArray';
|
||||
|
||||
@ -8,22 +8,18 @@ services:
|
||||
- 5432:5432
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
||||
start_period: 15s
|
||||
interval: 30s
|
||||
timeout: 30s
|
||||
retries: 3
|
||||
environment:
|
||||
- POSTGRES_DB=postgres
|
||||
- POSTGRES_USER=postgres
|
||||
- POSTGRES_PASSWORD=postgres
|
||||
|
||||
server:
|
||||
image: amruthpillai/reactive-resume:server-latest
|
||||
# build:
|
||||
# context: .
|
||||
# dockerfile: ./server/Dockerfile
|
||||
# image: amruthpillai/reactive-resume:server-latest
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./server/Dockerfile
|
||||
args:
|
||||
- TURBO_TOKEN=
|
||||
restart: always
|
||||
ports:
|
||||
- 3100:3100
|
||||
@ -59,10 +55,12 @@ services:
|
||||
- PDF_DELETION_TIME=
|
||||
|
||||
client:
|
||||
image: amruthpillai/reactive-resume:client-latest
|
||||
# build:
|
||||
# context: .
|
||||
# dockerfile: ./client/Dockerfile
|
||||
# image: amruthpillai/reactive-resume:client-latest
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./client/Dockerfile
|
||||
args:
|
||||
- TURBO_TOKEN=
|
||||
restart: always
|
||||
ports:
|
||||
- 3000:3000
|
||||
|
||||
32
package.json
32
package.json
@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "reactive-resume",
|
||||
"version": "3.7.3",
|
||||
"version": "3.7.4",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "env-cmd --silent cross-var cross-env VERSION=$npm_package_version pnpm run --recursive --parallel --stream dev",
|
||||
"build": "env-cmd --silent cross-var cross-env VERSION=$npm_package_version pnpm run --recursive --parallel build",
|
||||
"start": "env-cmd --silent cross-var cross-env VERSION=$npm_package_version pnpm run --recursive --parallel --stream start",
|
||||
"update": "ncu -x nanoid --deep -u && pnpm install",
|
||||
"generate-env": "ts-node ./scripts/generate-env.ts",
|
||||
"format": "prettier --write .",
|
||||
"lint": "pnpm run --recursive --parallel lint"
|
||||
"dev": "env-cmd --silent cross-var cross-env VERSION=$npm_package_version turbo run dev",
|
||||
"build": "env-cmd --silent cross-var cross-env VERSION=$npm_package_version turbo run build",
|
||||
"start": "env-cmd --silent cross-var cross-env VERSION=$npm_package_version turbo run start",
|
||||
"format": "prettier --write --loglevel silent --cache .",
|
||||
"lint": "turbo run lint",
|
||||
"update-dependencies": "ncu -x nanoid --deep -u && pnpm install",
|
||||
"generate-env": "ts-node ./scripts/generate-env.ts"
|
||||
},
|
||||
"workspaces": [
|
||||
"schema",
|
||||
@ -23,16 +23,18 @@
|
||||
"uuid": "^9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.15.12",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.0",
|
||||
"@typescript-eslint/parser": "^5.59.0",
|
||||
"eslint": "^8.38.0",
|
||||
"@types/node": "^20.2.5",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.9",
|
||||
"@typescript-eslint/parser": "^5.59.9",
|
||||
"eslint": "^8.42.0",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-simple-import-sort": "^10.0.0",
|
||||
"npm-check-updates": "^16.10.8",
|
||||
"prettier": "^2.8.7",
|
||||
"eslint-plugin-unused-imports": "^2.0.0",
|
||||
"npm-check-updates": "^16.10.12",
|
||||
"prettier": "^2.8.8",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^5.0.4"
|
||||
"turbo": "^1.10.2",
|
||||
"typescript": "^5.1.3"
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/react": "17.0.2",
|
||||
|
||||
3166
pnpm-lock.yaml
generated
3166
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "@reactive-resume/schema",
|
||||
"name": "schema",
|
||||
"type": "commonjs",
|
||||
"main": "./dist/index.js",
|
||||
"typings": "./dist/index.d.ts",
|
||||
@ -9,7 +9,7 @@
|
||||
"build": "tsc"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.38.0",
|
||||
"typescript": "^5.0.4"
|
||||
"eslint": "^8.42.0",
|
||||
"typescript": "^5.1.3"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,19 +1,7 @@
|
||||
{
|
||||
"root": true,
|
||||
"extends": "../.eslintrc.json",
|
||||
"plugins": ["unused-imports"],
|
||||
"ignorePatterns": ["dist"],
|
||||
"env": { "node": true },
|
||||
"rules": {
|
||||
// Unused Imports
|
||||
"unused-imports/no-unused-imports": "error",
|
||||
"unused-imports/no-unused-vars": [
|
||||
"warn",
|
||||
{
|
||||
"vars": "all",
|
||||
"args": "none",
|
||||
"varsIgnorePattern": "^_",
|
||||
"argsIgnorePattern": "^_"
|
||||
}
|
||||
]
|
||||
}
|
||||
"rules": {}
|
||||
}
|
||||
|
||||
1
server/.gitignore
vendored
1
server/.gitignore
vendored
@ -13,6 +13,7 @@ lerna-debug.log*
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
.playwright
|
||||
|
||||
# Tests
|
||||
/coverage
|
||||
|
||||
@ -21,8 +21,10 @@ COPY --from=dependencies /app/node_modules ./node_modules
|
||||
COPY --from=dependencies /app/schema/node_modules ./schema/node_modules
|
||||
COPY --from=dependencies /app/server/node_modules ./server/node_modules
|
||||
|
||||
RUN pnpm run --filter schema build \
|
||||
&& pnpm run --filter server build
|
||||
ARG TURBO_TOKEN
|
||||
ENV TURBO_TOKEN=$TURBO_TOKEN
|
||||
|
||||
RUN pnpm exec turbo --filter server build
|
||||
|
||||
FROM mcr.microsoft.com/playwright:v1.34.3-focal as production
|
||||
|
||||
@ -47,7 +49,4 @@ EXPOSE 3100
|
||||
|
||||
ENV PORT 3100
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=20s --retries=3 --start-period=15s \
|
||||
CMD curl -fSs localhost:3100/health || exit 1
|
||||
|
||||
CMD [ "pnpm", "run", "start" ]
|
||||
CMD [ "pnpm", "run", "--filter", "server", "start" ]
|
||||
@ -1,75 +1,74 @@
|
||||
{
|
||||
"name": "@reactive-resume/server",
|
||||
"name": "server",
|
||||
"scripts": {
|
||||
"lint": "eslint --fix src",
|
||||
"dev": "nest start --watch",
|
||||
"build": "rimraf dist && nest build",
|
||||
"debug": "nest start --debug --watch",
|
||||
"start": "node dist/main"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.317.0",
|
||||
"@aws-sdk/client-s3": "^3.347.1",
|
||||
"@nestjs/axios": "^2.0.0",
|
||||
"@nestjs/cache-manager": "^1.0.0",
|
||||
"@nestjs/common": "^9.4.0",
|
||||
"@nestjs/config": "^2.3.1",
|
||||
"@nestjs/core": "^9.4.0",
|
||||
"@nestjs/common": "^9.4.2",
|
||||
"@nestjs/config": "^2.3.2",
|
||||
"@nestjs/core": "^9.4.2",
|
||||
"@nestjs/jwt": "^10.0.3",
|
||||
"@nestjs/mapped-types": "^1.2.2",
|
||||
"@nestjs/passport": "^9.0.3",
|
||||
"@nestjs/platform-express": "^9.4.0",
|
||||
"@nestjs/schedule": "^2.2.1",
|
||||
"@nestjs/platform-express": "^9.4.2",
|
||||
"@nestjs/schedule": "^2.2.2",
|
||||
"@nestjs/serve-static": "^3.0.1",
|
||||
"@nestjs/terminus": "^9.2.2",
|
||||
"@nestjs/typeorm": "^9.0.1",
|
||||
"@types/passport": "^1.0.12",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"cache-manager": "^5.2.0",
|
||||
"cache-manager": "^5.2.2",
|
||||
"class-transformer": "^0.5.1",
|
||||
"class-validator": "^0.14.0",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"csvtojson": "^2.0.10",
|
||||
"dayjs": "^1.11.7",
|
||||
"google-auth-library": "^8.7.0",
|
||||
"joi": "^17.9.1",
|
||||
"dayjs": "^1.11.8",
|
||||
"google-auth-library": "^8.8.0",
|
||||
"joi": "^17.9.2",
|
||||
"lodash": "^4.17.21",
|
||||
"multer": "^1.4.5-lts.1",
|
||||
"nanoid": "3.3.4",
|
||||
"node-stream-zip": "^1.15.0",
|
||||
"nodemailer": "^6.9.1",
|
||||
"nodemailer": "^6.9.3",
|
||||
"passport": "^0.6.0",
|
||||
"passport-jwt": "^4.0.1",
|
||||
"passport-local": "^1.0.0",
|
||||
"pdf-lib": "^1.17.1",
|
||||
"pg": "^8.10.0",
|
||||
"playwright-chromium": "^1.32.3",
|
||||
"pg": "^8.11.0",
|
||||
"playwright-chromium": "^1.34.3",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"rimraf": "^5.0.0",
|
||||
"rxjs": "^7.8.0",
|
||||
"typeorm": "0.3.15",
|
||||
"rxjs": "^7.8.1",
|
||||
"typeorm": "0.3.16",
|
||||
"uuid": "^9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nestjs/cli": "^9.4.0",
|
||||
"@nestjs/schematics": "^9.1.0",
|
||||
"@reactive-resume/schema": "workspace:*",
|
||||
"@nestjs/cli": "^9.5.0",
|
||||
"@nestjs/schematics": "^9.2.0",
|
||||
"schema": "workspace:*",
|
||||
"@types/bcryptjs": "^2.4.2",
|
||||
"@types/cookie-parser": "^1.4.3",
|
||||
"@types/express": "^4.17.17",
|
||||
"@types/lodash": "^4.14.194",
|
||||
"@types/lodash": "^4.14.195",
|
||||
"@types/multer": "^1.4.7",
|
||||
"@types/node": "^18.15.12",
|
||||
"@types/nodemailer": "^6.4.7",
|
||||
"@types/node": "^20.2.5",
|
||||
"@types/nodemailer": "^6.4.8",
|
||||
"@types/passport-jwt": "^3.0.8",
|
||||
"@types/passport-local": "^1.0.35",
|
||||
"@types/uuid": "^9.0.1",
|
||||
"eslint-plugin-unused-imports": "^2.0.0",
|
||||
"prettier": "^2.8.7",
|
||||
"prettier": "^2.8.8",
|
||||
"rimraf": "^5.0.1",
|
||||
"source-map-support": "^0.5.21",
|
||||
"ts-loader": "^9.4.2",
|
||||
"ts-loader": "^9.4.3",
|
||||
"ts-node": "^10.9.1",
|
||||
"tsconfig-paths": "^4.2.0",
|
||||
"typescript": "^5.0.4",
|
||||
"webpack": "^5.80.0"
|
||||
"typescript": "^5.1.3",
|
||||
"webpack": "^5.86.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,9 +7,8 @@ import { join } from 'path';
|
||||
import { AuthModule } from './auth/auth.module';
|
||||
import { ConfigModule } from './config/config.module';
|
||||
import { DatabaseModule } from './database/database.module';
|
||||
import { HttpExceptionFilter } from './filters/http-exception.filter';
|
||||
import { AllExceptionsFilter } from './filters/all-exceptions.filter';
|
||||
import { FontsModule } from './fonts/fonts.module';
|
||||
import { HealthModule } from './health/health.module';
|
||||
import { IntegrationsModule } from './integrations/integrations.module';
|
||||
import { MailModule } from './mail/mail.module';
|
||||
import { PrinterModule } from './printer/printer.module';
|
||||
@ -33,7 +32,6 @@ import { UsersModule } from './users/users.module';
|
||||
FontsModule,
|
||||
IntegrationsModule,
|
||||
PrinterModule,
|
||||
HealthModule,
|
||||
],
|
||||
providers: [
|
||||
{
|
||||
@ -42,7 +40,7 @@ import { UsersModule } from './users/users.module';
|
||||
},
|
||||
{
|
||||
provide: APP_FILTER,
|
||||
useClass: HttpExceptionFilter,
|
||||
useClass: AllExceptionsFilter,
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Body, Controller, Delete, Get, HttpCode, Patch, Post, UseGuards } from '@nestjs/common';
|
||||
import { BadRequestException, Body, Controller, Delete, Get, HttpCode, Patch, Post, UseGuards } from '@nestjs/common';
|
||||
|
||||
import { User } from '@/decorators/user.decorator';
|
||||
import { User as UserEntity } from '@/users/entities/user.entity';
|
||||
@ -23,10 +23,14 @@ export class AuthController {
|
||||
|
||||
@Post('google')
|
||||
async loginWithGoogle(@Body('credential') credential: string) {
|
||||
const user = await this.authService.authenticateWithGoogle(credential);
|
||||
const accessToken = this.authService.getAccessToken(user.id);
|
||||
try {
|
||||
const user = await this.authService.authenticateWithGoogle(credential);
|
||||
const accessToken = this.authService.getAccessToken(user.id);
|
||||
|
||||
return { user, accessToken };
|
||||
return { user, accessToken };
|
||||
} catch (error) {
|
||||
throw new BadRequestException('User with this email might already exist.');
|
||||
}
|
||||
}
|
||||
|
||||
@Post('register')
|
||||
|
||||
23
server/src/filters/all-exceptions.filter.ts
Normal file
23
server/src/filters/all-exceptions.filter.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { ArgumentsHost, Catch, ExceptionFilter, HttpException, HttpStatus } from '@nestjs/common';
|
||||
import { HttpAdapterHost } from '@nestjs/core';
|
||||
|
||||
@Catch()
|
||||
export class AllExceptionsFilter implements ExceptionFilter {
|
||||
constructor(private readonly httpAdapterHost: HttpAdapterHost) {}
|
||||
|
||||
catch(exception: unknown, host: ArgumentsHost) {
|
||||
const { httpAdapter } = this.httpAdapterHost;
|
||||
|
||||
const ctx = host.switchToHttp();
|
||||
|
||||
const httpStatus = exception instanceof HttpException ? exception.getStatus() : HttpStatus.INTERNAL_SERVER_ERROR;
|
||||
|
||||
const responseBody = {
|
||||
statusCode: httpStatus,
|
||||
timestamp: new Date().toISOString(),
|
||||
path: httpAdapter.getRequestUrl(ctx.getRequest()),
|
||||
};
|
||||
|
||||
httpAdapter.reply(ctx.getResponse(), responseBody, httpStatus);
|
||||
}
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
import { ArgumentsHost, Catch, ExceptionFilter, HttpException } from '@nestjs/common';
|
||||
import type { Request, Response } from 'express';
|
||||
import { TypeORMError } from 'typeorm';
|
||||
|
||||
@Catch(HttpException)
|
||||
export class HttpExceptionFilter implements ExceptionFilter {
|
||||
catch(exception: HttpException, host: ArgumentsHost) {
|
||||
const ctx = host.switchToHttp();
|
||||
const response = ctx.getResponse<Response>();
|
||||
const request = ctx.getRequest<Request>();
|
||||
|
||||
const statusCode = exception.getStatus();
|
||||
const message = (exception.getResponse() as TypeORMError).message || exception.message;
|
||||
|
||||
response.status(statusCode).json({
|
||||
statusCode,
|
||||
message,
|
||||
timestamp: new Date().toISOString(),
|
||||
path: request.url,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
import { CacheInterceptor, Controller, Get, UseGuards, UseInterceptors } from '@nestjs/common';
|
||||
import { CacheInterceptor } from '@nestjs/cache-manager';
|
||||
import { Controller, Get, UseGuards, UseInterceptors } from '@nestjs/common';
|
||||
|
||||
import { JwtAuthGuard } from '@/auth/guards/jwt.guard';
|
||||
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { HttpService } from '@nestjs/axios';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { Font } from '@reactive-resume/schema';
|
||||
import get from 'lodash/get';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { Font } from 'schema';
|
||||
|
||||
import cachedResponse from './assets/cachedResponse.json';
|
||||
|
||||
|
||||
@ -1,13 +0,0 @@
|
||||
import { Controller, Get } from '@nestjs/common';
|
||||
import { HealthCheck, HealthCheckService, TypeOrmHealthIndicator } from '@nestjs/terminus';
|
||||
|
||||
@Controller('health')
|
||||
export class HealthController {
|
||||
constructor(private health: HealthCheckService, private db: TypeOrmHealthIndicator) {}
|
||||
|
||||
@Get()
|
||||
@HealthCheck()
|
||||
check() {
|
||||
return this.health.check([() => this.db.pingCheck('database')]);
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
import { HttpModule } from '@nestjs/axios';
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TerminusModule } from '@nestjs/terminus';
|
||||
|
||||
import { HealthController } from './health.controller';
|
||||
|
||||
@Module({
|
||||
imports: [HttpModule, TerminusModule],
|
||||
controllers: [HealthController],
|
||||
})
|
||||
export class HealthModule {}
|
||||
@ -1,4 +1,12 @@
|
||||
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
||||
import csv from 'csvtojson';
|
||||
import dayjs from 'dayjs';
|
||||
import { readFile, unlink } from 'fs/promises';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import get from 'lodash/get';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import merge from 'lodash/merge';
|
||||
import StreamZip from 'node-stream-zip';
|
||||
import {
|
||||
Award,
|
||||
Certificate,
|
||||
@ -12,15 +20,7 @@ import {
|
||||
Skill,
|
||||
Volunteer,
|
||||
WorkExperience,
|
||||
} from '@reactive-resume/schema';
|
||||
import csv from 'csvtojson';
|
||||
import dayjs from 'dayjs';
|
||||
import { readFile, unlink } from 'fs/promises';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import get from 'lodash/get';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import merge from 'lodash/merge';
|
||||
import StreamZip from 'node-stream-zip';
|
||||
} from 'schema';
|
||||
import { DeepPartial } from 'typeorm';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Controller, Get, Param, Query } from '@nestjs/common';
|
||||
import { Controller, GatewayTimeoutException, Get, Param, Query } from '@nestjs/common';
|
||||
|
||||
import { PrinterService } from './printer.service';
|
||||
|
||||
@ -7,11 +7,15 @@ export class PrinterController {
|
||||
constructor(private readonly printerService: PrinterService) {}
|
||||
|
||||
@Get('/:username/:slug')
|
||||
printAsPdf(
|
||||
async printAsPdf(
|
||||
@Param('username') username: string,
|
||||
@Param('slug') slug: string,
|
||||
@Query('lastUpdated') lastUpdated: string
|
||||
): Promise<string> {
|
||||
return this.printerService.printAsPdf(username, slug, lastUpdated);
|
||||
try {
|
||||
return await this.printerService.printAsPdf(username, slug, lastUpdated);
|
||||
} catch (error) {
|
||||
throw new GatewayTimeoutException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,21 +1,61 @@
|
||||
import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { SchedulerRegistry } from '@nestjs/schedule';
|
||||
import { PageConfig } from '@reactive-resume/schema';
|
||||
import { access, mkdir, readdir, unlink, writeFile } from 'fs/promises';
|
||||
import { join } from 'path';
|
||||
import { PDFDocument } from 'pdf-lib';
|
||||
import { Browser, chromium } from 'playwright-chromium';
|
||||
import { BrowserContext, chromium } from 'playwright-chromium';
|
||||
import { PageConfig } from 'schema';
|
||||
|
||||
const minimal_chromium_args = [
|
||||
'--autoplay-policy=user-gesture-required',
|
||||
'--disable-background-networking',
|
||||
'--disable-background-timer-throttling',
|
||||
'--disable-backgrounding-occluded-windows',
|
||||
'--disable-breakpad',
|
||||
'--disable-client-side-phishing-detection',
|
||||
'--disable-component-update',
|
||||
'--disable-default-apps',
|
||||
'--disable-dev-shm-usage',
|
||||
'--disable-domain-reliability',
|
||||
'--disable-extensions',
|
||||
'--disable-features=AudioServiceOutOfProcess',
|
||||
'--disable-hang-monitor',
|
||||
'--disable-ipc-flooding-protection',
|
||||
'--disable-notifications',
|
||||
'--disable-offer-store-unmasked-wallet-cards',
|
||||
'--disable-popup-blocking',
|
||||
'--disable-print-preview',
|
||||
'--disable-prompt-on-repost',
|
||||
'--disable-renderer-backgrounding',
|
||||
'--disable-setuid-sandbox',
|
||||
'--disable-speech-api',
|
||||
'--disable-sync',
|
||||
'--hide-scrollbars',
|
||||
'--ignore-gpu-blacklist',
|
||||
'--metrics-recording-only',
|
||||
'--mute-audio',
|
||||
'--no-default-browser-check',
|
||||
'--no-first-run',
|
||||
'--no-pings',
|
||||
'--no-sandbox',
|
||||
'--no-zygote',
|
||||
'--password-store=basic',
|
||||
'--use-gl=swiftshader',
|
||||
'--use-mock-keychain',
|
||||
];
|
||||
|
||||
@Injectable()
|
||||
export class PrinterService implements OnModuleInit, OnModuleDestroy {
|
||||
private browser: Browser;
|
||||
private browser: BrowserContext;
|
||||
|
||||
constructor(private readonly schedulerRegistry: SchedulerRegistry, private readonly configService: ConfigService) {}
|
||||
|
||||
async onModuleInit() {
|
||||
this.browser = await chromium.launch({
|
||||
args: ['--disable-dev-shm-usage'],
|
||||
this.browser = await chromium.launchPersistentContext('.playwright', {
|
||||
headless: true,
|
||||
forcedColors: 'active',
|
||||
args: minimal_chromium_args,
|
||||
});
|
||||
}
|
||||
|
||||
@ -34,6 +74,7 @@ export class PrinterService implements OnModuleInit, OnModuleDestroy {
|
||||
await access(join(directory, filename));
|
||||
} catch {
|
||||
const activeSchedulerTimeouts = this.schedulerRegistry.getTimeouts();
|
||||
|
||||
await readdir(directory).then(async (files) => {
|
||||
await Promise.all(
|
||||
files.map(async (file) => {
|
||||
@ -53,9 +94,8 @@ export class PrinterService implements OnModuleInit, OnModuleDestroy {
|
||||
|
||||
const page = await this.browser.newPage();
|
||||
|
||||
await page.goto(`${url}${username}/${slug}/printer?secretKey=${secretKey}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForSelector('html.wf-active');
|
||||
await page.goto(`${url}/${username}/${slug}/printer?secretKey=${secretKey}`, { waitUntil: 'networkidle' });
|
||||
await page.waitForSelector('html.wf-active', { state: 'visible' });
|
||||
|
||||
const pageFormat: PageConfig['format'] = await page.$$eval(
|
||||
'[data-page]',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Resume } from '@reactive-resume/schema';
|
||||
import { Resume } from 'schema';
|
||||
|
||||
const defaultCSS = `/* Enter custom CSS here */
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Basics, Metadata, Section } from '@reactive-resume/schema';
|
||||
import { Basics, Metadata, Section } from 'schema';
|
||||
import { Column, CreateDateColumn, Entity, ManyToOne, PrimaryGeneratedColumn, Unique, UpdateDateColumn } from 'typeorm';
|
||||
|
||||
import { User } from '@/users/entities/user.entity';
|
||||
|
||||
@ -2,7 +2,6 @@ import { DeleteObjectCommand, PutObjectCommand, S3, S3Client } from '@aws-sdk/cl
|
||||
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Resume as ResumeSchema } from '@reactive-resume/schema';
|
||||
import fs from 'fs/promises';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import pick from 'lodash/pick';
|
||||
@ -10,6 +9,7 @@ import sample from 'lodash/sample';
|
||||
import set from 'lodash/set';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { extname } from 'path';
|
||||
import { Resume as ResumeSchema } from 'schema';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { PostgresErrorCode } from '@/database/errorCodes.enum';
|
||||
|
||||
17
turbo.json
Normal file
17
turbo.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"$schema": "https://turbo.build/schema.json",
|
||||
"pipeline": {
|
||||
"build": {
|
||||
"dependsOn": ["^build"],
|
||||
"outputs": [".next/**", "!.next/cache/**", "dist/**"]
|
||||
},
|
||||
"lint": {},
|
||||
"format": {
|
||||
"dependsOn": ["^lint"]
|
||||
},
|
||||
"dev": {
|
||||
"cache": false,
|
||||
"persistent": true
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user