- bumped version to 2.3.3

- fixed text alignment issues
- updated dependencies
- added ukranian language
This commit is contained in:
Amruth Pillai
2020-12-09 10:40:27 +05:30
parent 88a3fe5148
commit df71b86028
32 changed files with 942 additions and 1021 deletions

View File

@ -1,19 +1,17 @@
{
"hosting": [{
"site": "rxresume",
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}],
"hosting": [
{
"site": "rxresume",
"public": "public",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
],
"emulators": {
"functions": {
"port": 5001

View File

@ -17,94 +17,99 @@ async function asyncForEach(array, callback) {
}
}
exports.deleteUser = functions.https.onCall((_, { auth }) => {
if (!auth) {
throw new functions.https.HttpsError(
'failed-precondition',
'The function must be called while authenticated.',
);
}
return new Promise((resolve) => {
const resumesRef = admin.database().ref('resumes');
resumesRef.once('value', async (snapshot) => {
const data = snapshot.val();
const resumes = Object.keys(data).filter(
(x) => data[x].user === auth.uid,
exports.deleteUser = functions
.runWith({ memory: '256MB' })
.https.onCall((_, { auth }) => {
if (!auth) {
throw new functions.https.HttpsError(
'failed-precondition',
'The function must be called while authenticated.',
);
}
await asyncForEach(resumes, async (id) => {
await admin.database().ref(`resumes/${id}`).remove();
return new Promise((resolve) => {
const resumesRef = admin.database().ref('resumes');
resumesRef.once('value', async (snapshot) => {
const data = snapshot.val();
const resumes = Object.keys(data).filter(
(x) => data[x].user === auth.uid,
);
await asyncForEach(resumes, async (id) => {
await admin.database().ref(`resumes/${id}`).remove();
});
resolve();
});
resolve();
});
});
});
exports.printResume = functions.https.onCall(async ({ id, type }, { auth }) => {
if (!id) {
throw new functions.https.HttpsError(
'invalid-argument',
'The function must be called with argument "id" containing the resume ID.',
);
}
if (!type) {
throw new functions.https.HttpsError(
'invalid-argument',
'The function must be called with argument "type" containing the type of resume.',
);
}
if (!auth) {
throw new functions.https.HttpsError(
'failed-precondition',
'The function must be called while authenticated.',
);
}
const browser = await puppeteer.launch({
headless: true,
});
const page = await browser.newPage();
await page.goto(BASE_URL + id, {
waitUntil: 'networkidle0',
});
await timeout(6000);
await page.emulateMediaType('print');
let pdf;
if (type === 'single') {
const height = await page.evaluate(() => {
const { body } = document;
const html = document.documentElement;
const maxHeight = Math.max(
body.scrollHeight,
body.offsetHeight,
html.clientHeight,
html.scrollHeight,
html.offsetHeight,
exports.printResume = functions
.runWith({ memory: '1GB' })
.https.onCall(async ({ id, type }, { auth }) => {
if (!id) {
throw new functions.https.HttpsError(
'invalid-argument',
'The function must be called with argument "id" containing the resume ID.',
);
}
return maxHeight;
});
pdf = await page.pdf({
printBackground: true,
width: `21cm`,
height: `${height}px`,
pageRanges: '1',
});
} else {
pdf = await page.pdf({
format: 'A4',
printBackground: true,
});
}
if (!type) {
throw new functions.https.HttpsError(
'invalid-argument',
'The function must be called with argument "type" containing the type of resume.',
);
}
await browser.close();
return Buffer.from(pdf).toString('base64');
});
if (!auth) {
throw new functions.https.HttpsError(
'failed-precondition',
'The function must be called while authenticated.',
);
}
const browser = await puppeteer.launch({
headless: true,
args: ['--no-sandbox'],
});
const page = await browser.newPage();
await page.goto(BASE_URL + id, {
waitUntil: 'networkidle0',
});
await timeout(6000);
await page.emulateMediaType('print');
let pdf;
if (type === 'single') {
const height = await page.evaluate(() => {
const { body } = document;
const html = document.documentElement;
const maxHeight = Math.max(
body.scrollHeight,
body.offsetHeight,
html.clientHeight,
html.scrollHeight,
html.offsetHeight,
);
return maxHeight;
});
pdf = await page.pdf({
printBackground: true,
width: `21cm`,
height: `${height}px`,
pageRanges: '1',
});
} else {
pdf = await page.pdf({
format: 'A4',
printBackground: true,
});
}
await browser.close();
return Buffer.from(pdf).toString('base64');
});

View File

@ -58,9 +58,9 @@
}
},
"@google-cloud/common": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.4.0.tgz",
"integrity": "sha512-bVMQlK4aZEeopo2oJwDUJiBhPVjRRQHfFCCv9JowmKS3L//PBHNDJzC/LxJixGZEU3fh3YXkUwm67JZ5TBCCNQ==",
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.5.0.tgz",
"integrity": "sha512-10d7ZAvKhq47L271AqvHEd8KzJqGU45TY+rwM2Z3JHuB070FeTi7oJJd7elfrnKaEvaktw3hH2wKnRWxk/3oWQ==",
"optional": true,
"requires": {
"@google-cloud/projectify": "^2.0.0",
@ -69,20 +69,20 @@
"duplexify": "^4.1.1",
"ent": "^2.2.0",
"extend": "^3.0.2",
"google-auth-library": "^6.0.0",
"google-auth-library": "^6.1.1",
"retry-request": "^4.1.1",
"teeny-request": "^7.0.0"
}
},
"@google-cloud/firestore": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-4.4.0.tgz",
"integrity": "sha512-nixsumd4C7eL+hHEgyihspzhBBNe3agsvNFRX0xfqO3uR/6ro4CUj9XdcCvdnSSd3yTyqKfdBSRK2fEj1jIbYg==",
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-4.8.0.tgz",
"integrity": "sha512-cBPo7QQG+aUhS7AIr6fDlA9KIX0/U26rKZyL2K/L68LArDQzgBk1/xOiMoflHRNDQARwCQ0PAZmw8V8CXg7vTg==",
"optional": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"functional-red-black-tree": "^1.0.1",
"google-gax": "^2.2.0"
"google-gax": "^2.9.2"
}
},
"@google-cloud/paginator": {
@ -108,22 +108,22 @@
"optional": true
},
"@google-cloud/storage": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.3.0.tgz",
"integrity": "sha512-3t5UF3SZ14Bw2kcBHubCai6EIugU2GnQOstYWVSFuoO8IJ94RAaIOPq/dtexvQbUTpBTAGpd5smVR9WPL1mJVw==",
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.6.0.tgz",
"integrity": "sha512-nLcym8IuCzy1O7tNTXNFuMHfX900sTM3kSTqbKe7oFSoKUiaIM+FHuuuDimMMlieY6StA1xYNPRFFHz57Nv8YQ==",
"optional": true,
"requires": {
"@google-cloud/common": "^3.3.0",
"@google-cloud/common": "^3.5.0",
"@google-cloud/paginator": "^3.0.0",
"@google-cloud/promisify": "^2.0.0",
"arrify": "^2.0.0",
"compressible": "^2.0.12",
"concat-stream": "^2.0.0",
"date-and-time": "^0.14.0",
"duplexify": "^3.5.0",
"duplexify": "^4.0.0",
"extend": "^3.0.2",
"gaxios": "^3.0.0",
"gaxios": "^4.0.0",
"gcs-resumable-upload": "^3.1.0",
"get-stream": "^6.0.0",
"hash-stream-validation": "^0.2.2",
"mime": "^2.2.0",
"mime-types": "^2.0.8",
@ -135,63 +135,21 @@
"xdg-basedir": "^4.0.0"
},
"dependencies": {
"duplexify": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
"integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
"optional": true,
"requires": {
"end-of-stream": "^1.0.0",
"inherits": "^2.0.1",
"readable-stream": "^2.0.0",
"stream-shift": "^1.0.0"
}
},
"p-limit": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz",
"integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
"optional": true,
"requires": {
"p-try": "^2.0.0"
}
},
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"optional": true,
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"optional": true
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"optional": true,
"requires": {
"safe-buffer": "~5.1.0"
"yocto-queue": "^0.1.0"
}
}
}
},
"@grpc/grpc-js": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.1.7.tgz",
"integrity": "sha512-EuxMstI0u778dp0nk6Fe3gHXYPeV6FYsWOe0/QFwxv1NQ6bc5Wl/0Yxa4xl9uBlKElL6AIxuASmSfu7KEJhqiw==",
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.1.8.tgz",
"integrity": "sha512-64hg5rmEm6F/NvlWERhHmmgxbWU8nD2TMWE+9TvG7/WcOrFT3fzg/Uu631pXRFwmJ4aWO/kp9vVSlr8FUjBDLA==",
"optional": true,
"requires": {
"@grpc/proto-loader": "^0.6.0-pre14",
@ -214,9 +172,9 @@
}
},
"@types/node": {
"version": "12.12.62",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.62.tgz",
"integrity": "sha512-qAfo81CsD7yQIM9mVyh6B/U47li5g7cfpVQEDMfQeF8pSZVwzbhwU3crc0qG4DmpsebpJPR49AKOExQyJ05Cpg==",
"version": "12.19.8",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.8.tgz",
"integrity": "sha512-D4k2kNi0URNBxIRCb1khTnkWNHv8KSL1owPmS/K5e5t8B2GzMReY7AsJIY1BnP5KdlgC4rj9jk2IkDMasIE7xg==",
"optional": true
}
}
@ -310,16 +268,10 @@
"@types/node": "*"
}
},
"@types/color-name": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
"optional": true
},
"@types/connect": {
"version": "3.4.33",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.33.tgz",
"integrity": "sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A==",
"version": "3.4.34",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz",
"integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==",
"requires": {
"@types/node": "*"
}
@ -335,9 +287,9 @@
}
},
"@types/express-serve-static-core": {
"version": "4.17.13",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.13.tgz",
"integrity": "sha512-RgDi5a4nuzam073lRGKTUIaL3eF2+H7LJvJ8eUnCI0wA6SNjXc44DCmWNiTLs/AZ7QlsFWZiw/gTG3nSQGL0fA==",
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.15.tgz",
"integrity": "sha512-pb71P0BrBAx7cQE+/7QnA1HTQUkdBKMlkPY7lHUMn0YvPJkL2UA+KW3BdWQ309IT+i9En/qm45ZxpjIcpgEhNQ==",
"requires": {
"@types/node": "*",
"@types/qs": "*",
@ -345,9 +297,9 @@
}
},
"@types/lodash": {
"version": "4.14.161",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.161.tgz",
"integrity": "sha512-EP6O3Jkr7bXvZZSZYlsgt5DIjiGr0dXP1/jVEwVLTFgg0d+3lWVQkRavYVQszV7dYUwvg0B8R0MBDpcmXg7XIA==",
"version": "4.14.165",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.165.tgz",
"integrity": "sha512-tjSSOTHhI5mCHTy/OOXYIhi2Wt1qcbHmuXD1Ha7q70CgI/I71afO4XtLb/cVexki1oVYchpul/TOuu3Arcdxrg==",
"dev": true
},
"@types/long": {
@ -362,9 +314,9 @@
"integrity": "sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q=="
},
"@types/node": {
"version": "10.17.35",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.35.tgz",
"integrity": "sha512-gXx7jAWpMddu0f7a+L+txMplp3FnHl53OhQIF9puXKq3hDGY/GjH+MF04oWnV/adPSCrbtHumDCFwzq2VhltWA=="
"version": "10.17.48",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.48.tgz",
"integrity": "sha512-Agl6xbYP6FOMDeAsr3QVZ+g7Yzg0uhPHWx0j5g4LFdUBHVtqtU+gH660k/lCEe506jJLOGbEzsnqPDTZGJQLag=="
},
"@types/qs": {
"version": "6.9.5",
@ -377,12 +329,12 @@
"integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA=="
},
"@types/serve-static": {
"version": "1.13.5",
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.5.tgz",
"integrity": "sha512-6M64P58N+OXjU432WoLLBQxbA0LRGBCRm7aAGQJ+SMC1IMl0dgRVi9EFfoDcS2a7Xogygk/eGN94CfwU9UF7UQ==",
"version": "1.13.8",
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.8.tgz",
"integrity": "sha512-MoJhSQreaVoL+/hurAZzIm8wafFR6ajiTM1m4A0kv6AGeVBl4r4pOV8bGFrjjq1sGxDTnCoF8i22o0/aE5XCyA==",
"requires": {
"@types/express-serve-static-core": "*",
"@types/mime": "*"
"@types/mime": "*",
"@types/node": "*"
}
},
"@types/yauzl": {
@ -413,9 +365,9 @@
}
},
"agent-base": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.1.tgz",
"integrity": "sha512-01q25QQDwLSsyfhrKbn8yuur+JNw0H+0Y4JiGIKd3z9aYk/w/2kxD/Upc+t2ZBBSUNff50VjPsSW2YxM8QYKVg==",
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"optional": true,
"requires": {
"debug": "4"
@ -428,12 +380,11 @@
"optional": true
},
"ansi-styles": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"optional": true,
"requires": {
"@types/color-name": "^1.1.1",
"color-convert": "^2.0.1"
}
},
@ -454,9 +405,9 @@
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
"base64-js": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
},
"bignumber.js": {
"version": "9.0.1",
@ -516,12 +467,12 @@
}
},
"buffer": {
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
"integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"requires": {
"base64-js": "^1.0.2",
"ieee754": "^1.1.4"
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
}
},
"buffer-crc32": {
@ -534,12 +485,6 @@
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
"integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
},
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
"optional": true
},
"bytes": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
@ -596,18 +541,6 @@
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"concat-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz",
"integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==",
"optional": true,
"requires": {
"buffer-from": "^1.0.0",
"inherits": "^2.0.3",
"readable-stream": "^3.0.2",
"typedarray": "^0.0.6"
}
},
"configstore": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz",
@ -652,12 +585,6 @@
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
},
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
"optional": true
},
"cors": {
"version": "2.8.5",
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
@ -680,9 +607,9 @@
"optional": true
},
"debug": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz",
"integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==",
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
"requires": {
"ms": "2.1.2"
}
@ -704,9 +631,9 @@
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
},
"devtools-protocol": {
"version": "0.0.799653",
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.799653.tgz",
"integrity": "sha512-t1CcaZbvm8pOlikqrsIM9GOa7Ipp07+4h/q9u0JXBWjPCjHdBl9KkddX87Vv9vBHoBGtwV79sYQNGnQM6iS5gg=="
"version": "0.0.818844",
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.818844.tgz",
"integrity": "sha512-AD1hi7iVJ8OD0aMLQU5VK0XH9LDlA1+BcPIgrAxPfaibx2DbWucuyOhc4oyQCbnvDDO68nN6/LcKfqTP343Jjg=="
},
"dicer": {
"version": "0.3.0",
@ -863,6 +790,16 @@
"debug": "^4.1.1",
"get-stream": "^5.1.0",
"yauzl": "^2.10.0"
},
"dependencies": {
"get-stream": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
"requires": {
"pump": "^3.0.0"
}
}
}
},
"fast-deep-equal": {
@ -932,13 +869,13 @@
}
},
"firebase-admin": {
"version": "9.2.0",
"resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.2.0.tgz",
"integrity": "sha512-LhnMYl71B4gP1FlTLfwaYlOWhBCAcNF+byb2CPTfaW/T4hkp4qlXOgo2bws/zbAv5X9GTFqGir3KexMslVGsIA==",
"version": "9.4.1",
"resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.4.1.tgz",
"integrity": "sha512-y9r2Mz2x1WTr60YrCDqz8Lw70DlwIvRIieVltP+UdRogkVpfnvyd+bi4D0KPlujW3teqcFPmxuzsXB+DP5vGfQ==",
"requires": {
"@firebase/database": "^0.6.10",
"@firebase/database-types": "^0.5.2",
"@google-cloud/firestore": "^4.0.0",
"@google-cloud/firestore": "^4.5.0",
"@google-cloud/storage": "^5.3.0",
"@types/node": "^10.10.0",
"dicer": "^0.3.0",
@ -947,9 +884,9 @@
}
},
"firebase-functions": {
"version": "3.11.0",
"resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.11.0.tgz",
"integrity": "sha512-i1uMhZ/M6i5SCI3ulKo7EWX0/LD+I5o6N+sk0HbOWfzyWfOl0iJTvQkR3BVDcjrlhPVC4xG1bDTLxd+DTkLqaw==",
"version": "3.13.0",
"resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.13.0.tgz",
"integrity": "sha512-tnltJL5KlGtbeBD9scsVjoKTSTMeo6EAy1gsdOfRlrwAu6idgLRKYVdmw0YymS8N7SwJ3CXo+3fuvSSihKhXbA==",
"requires": {
"@types/express": "4.17.3",
"cors": "^2.8.5",
@ -958,9 +895,9 @@
}
},
"firebase-functions-test": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/firebase-functions-test/-/firebase-functions-test-0.2.2.tgz",
"integrity": "sha512-SlHLnpKRn5nMsg4Y0CUTGs/R8NatghJCYZGw3fHzaS/5xDqwWPWuxmdHHc+MSuxrSrUROEwOrDTwrbjmRaSNjw==",
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/firebase-functions-test/-/firebase-functions-test-0.2.3.tgz",
"integrity": "sha512-zYX0QTm53wCazuej7O0xqbHl90r/v1PTXt/hwa0jo1YF8nDM+iBKnLDlkIoW66MDd0R6aGg4BvKzTTdJpvigUA==",
"dev": true,
"requires": {
"@types/lodash": "^4.14.104",
@ -994,9 +931,9 @@
"optional": true
},
"gaxios": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-3.2.0.tgz",
"integrity": "sha512-+6WPeVzPvOshftpxJwRi2Ozez80tn/hdtOUag7+gajDHRJvAblKxTFSSMPtr2hmnLy7p0mvYz0rMXLBl8pSO7Q==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.1.0.tgz",
"integrity": "sha512-vb0to8xzGnA2qcgywAjtshOKKVDf2eQhJoiL6fHhgW5tVN7wNk7egnYIO9zotfn3lQ3De1VPdf7V5/BWfCtCmg==",
"optional": true,
"requires": {
"abort-controller": "^3.0.0",
@ -1007,12 +944,12 @@
}
},
"gcp-metadata": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.2.0.tgz",
"integrity": "sha512-vQZD57cQkqIA6YPGXM/zc+PIZfNRFdukWGsGZ5+LcJzesi5xp6Gn7a02wRJi4eXPyArNMIYpPET4QMxGqtlk6Q==",
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.2.1.tgz",
"integrity": "sha512-tSk+REe5iq/N+K+SK1XjZJUrFPuDqGZVzCy2vocIHIGmPlTGsa8owXMJwGkrXr73NO0AzhPW4MF2DEHz7P2AVw==",
"optional": true,
"requires": {
"gaxios": "^3.0.0",
"gaxios": "^4.0.0",
"json-bigint": "^1.0.0"
}
},
@ -1029,6 +966,21 @@
"google-auth-library": "^6.0.0",
"pumpify": "^2.0.0",
"stream-events": "^1.0.4"
},
"dependencies": {
"gaxios": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-3.2.0.tgz",
"integrity": "sha512-+6WPeVzPvOshftpxJwRi2Ozez80tn/hdtOUag7+gajDHRJvAblKxTFSSMPtr2hmnLy7p0mvYz0rMXLBl8pSO7Q==",
"optional": true,
"requires": {
"abort-controller": "^3.0.0",
"extend": "^3.0.2",
"https-proxy-agent": "^5.0.0",
"is-stream": "^2.0.0",
"node-fetch": "^2.3.0"
}
}
}
},
"get-caller-file": {
@ -1038,12 +990,10 @@
"optional": true
},
"get-stream": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
"requires": {
"pump": "^3.0.0"
}
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz",
"integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==",
"optional": true
},
"glob": {
"version": "7.1.6",
@ -1059,26 +1009,26 @@
}
},
"google-auth-library": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.0.tgz",
"integrity": "sha512-GbalszIADE1YPWhUyfFMrkLhFHnlAgoRcqGVW+MsLDPsuaOB5MRPk7NNafPDv9SherNE4EKzcYuxMJjaxzXMOw==",
"version": "6.1.3",
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.3.tgz",
"integrity": "sha512-m9mwvY3GWbr7ZYEbl61isWmk+fvTmOt0YNUfPOUY2VH8K5pZlAIWJjxEi0PqR3OjMretyiQLI6GURMrPSwHQ2g==",
"optional": true,
"requires": {
"arrify": "^2.0.0",
"base64-js": "^1.3.0",
"ecdsa-sig-formatter": "^1.0.11",
"fast-text-encoding": "^1.0.0",
"gaxios": "^3.0.0",
"gcp-metadata": "^4.1.0",
"gtoken": "^5.0.0",
"gaxios": "^4.0.0",
"gcp-metadata": "^4.2.0",
"gtoken": "^5.0.4",
"jws": "^4.0.0",
"lru-cache": "^6.0.0"
}
},
"google-gax": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.9.0.tgz",
"integrity": "sha512-MFMwA7Fb8PEwjnYwfGXjZMidCNyMl3gSnvS/+kS8TQioJZQDpzK+W3dmwyNyig/U13+kbABqDnbkkAXJ5NiUkw==",
"version": "2.9.2",
"resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.9.2.tgz",
"integrity": "sha512-Pve4osEzNKpBZqFXMfGKBbKCtgnHpUe5IQMh5Ou+Xtg8nLcba94L3gF0xgM5phMdGRRqJn0SMjcuEVmOYu7EBg==",
"optional": true,
"requires": {
"@grpc/grpc-js": "~1.1.1",
@ -1086,7 +1036,7 @@
"@types/long": "^4.0.0",
"abort-controller": "^3.0.0",
"duplexify": "^4.0.0",
"google-auth-library": "^6.0.0",
"google-auth-library": "^6.1.3",
"is-stream-ended": "^0.1.4",
"node-fetch": "^2.6.1",
"protobufjs": "^6.9.0",
@ -1109,13 +1059,13 @@
"optional": true
},
"gtoken": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.0.3.tgz",
"integrity": "sha512-Nyd1wZCMRc2dj/mAD0LlfQLcAO06uKdpKJXvK85SGrF5+5+Bpfil9u/2aw35ltvEHjvl0h5FMKN5knEU+9JrOg==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.1.0.tgz",
"integrity": "sha512-4d8N6Lk8TEAHl9vVoRVMh9BNOKWVgl2DdNtr3428O75r3QFrF/a5MMu851VmK0AA8+iSvbwRv69k5XnMLURGhg==",
"optional": true,
"requires": {
"gaxios": "^3.0.0",
"google-p12-pem": "^3.0.0",
"gaxios": "^4.0.0",
"google-p12-pem": "^3.0.3",
"jws": "^4.0.0",
"mime": "^2.2.0"
}
@ -1180,9 +1130,9 @@
}
},
"ieee754": {
"version": "1.1.13",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
"integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
},
"imurmurhash": {
"version": "0.1.4",
@ -1239,12 +1189,6 @@
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
"optional": true
},
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
"optional": true
},
"json-bigint": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
@ -1470,8 +1414,7 @@
"node-fetch": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
"optional": true
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
},
"node-forge": {
"version": "0.10.0",
@ -1562,21 +1505,15 @@
"find-up": "^4.0.0"
}
},
"process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"optional": true
},
"progress": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
},
"protobufjs": {
"version": "6.10.1",
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.1.tgz",
"integrity": "sha512-pb8kTchL+1Ceg4lFd5XUpK8PdWacbvV5SK2ULH2ebrYtl4GjJmS24m6CKME67jzV53tbJxHlnNOSqQHbTsR9JQ==",
"version": "6.10.2",
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.2.tgz",
"integrity": "sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==",
"optional": true,
"requires": {
"@protobufjs/aspromise": "^1.1.2",
@ -1595,9 +1532,9 @@
},
"dependencies": {
"@types/node": {
"version": "13.13.21",
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.21.tgz",
"integrity": "sha512-tlFWakSzBITITJSxHV4hg4KvrhR/7h3xbJdSFbYJBVzKubrASbnnIFuSgolUh7qKGo/ZeJPKUfbZ0WS6Jp14DQ==",
"version": "13.13.35",
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.35.tgz",
"integrity": "sha512-q9aeOGwv+RRou/ca4aJVUM/jD5u7LBexu+rq9PkA/NhHNn8JifcMo94soKm0b6JGSfw/PSNdqtc428OscMvEYA==",
"optional": true
}
}
@ -1637,14 +1574,15 @@
}
},
"puppeteer": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-5.3.1.tgz",
"integrity": "sha512-YTM1RaBeYrj6n7IlRXRYLqJHF+GM7tasbvrNFx6w1S16G76NrPq7oYFKLDO+BQsXNtS8kW2GxWCXjIMPvfDyaQ==",
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-5.5.0.tgz",
"integrity": "sha512-OM8ZvTXAhfgFA7wBIIGlPQzvyEETzDjeRa4mZRCRHxYL+GNH5WAuYUQdja3rpWZvkX/JKqmuVgbsxDNsDFjMEg==",
"requires": {
"debug": "^4.1.0",
"devtools-protocol": "0.0.799653",
"devtools-protocol": "0.0.818844",
"extract-zip": "^2.0.0",
"https-proxy-agent": "^4.0.0",
"node-fetch": "^2.6.1",
"pkg-dir": "^4.2.0",
"progress": "^2.0.1",
"proxy-from-env": "^1.0.0",
@ -1887,14 +1825,14 @@
"optional": true
},
"tar-fs": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.0.tgz",
"integrity": "sha512-9uW5iDvrIMCVpvasdFHW0wJPez0K4JnMZtsuIeDI7HyMGJNxmDZDOCQROr7lXyS+iL/QMpj07qcjGYTSdRFXUg==",
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
"integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
"requires": {
"chownr": "^1.1.1",
"mkdirp-classic": "^0.5.2",
"pump": "^3.0.0",
"tar-stream": "^2.0.0"
"tar-stream": "^2.1.4"
}
},
"tar-stream": {
@ -1933,9 +1871,9 @@
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
},
"tslib": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
"integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q=="
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
},
"type-is": {
"version": "1.6.18",
@ -1946,12 +1884,6 @@
"mime-types": "~2.1.24"
}
},
"typedarray": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
"optional": true
},
"typedarray-to-buffer": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
@ -1995,9 +1927,9 @@
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
},
"uuid": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz",
"integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==",
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"optional": true
},
"vary": {
@ -2055,9 +1987,9 @@
}
},
"ws": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz",
"integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA=="
"version": "7.4.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.1.tgz",
"integrity": "sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ=="
},
"xdg-basedir": {
"version": "4.0.0",
@ -2066,9 +1998,9 @@
"optional": true
},
"y18n": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz",
"integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==",
"optional": true
},
"yallist": {
@ -2114,6 +2046,12 @@
"buffer-crc32": "~0.2.3",
"fd-slicer": "~1.1.0"
}
},
"yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
"optional": true
}
}
}

View File

@ -9,15 +9,15 @@
"logs": "firebase functions:log"
},
"engines": {
"node": "10"
"node": "12"
},
"dependencies": {
"firebase-admin": "^9.2.0",
"firebase-functions": "^3.11.0",
"puppeteer": "5.3.1"
"firebase-admin": "^9.4.1",
"firebase-functions": "^3.13.0",
"puppeteer": "5.5.0"
},
"devDependencies": {
"firebase-functions-test": "^0.2.2"
"firebase-functions-test": "^0.2.3"
},
"private": true
}

View File

@ -5,7 +5,7 @@ module.exports = {
title: 'Reactive Resume',
siteUrl: 'https://rxresu.me',
description: 'A free and open source resume builder.',
version: '2.3',
version: '2.3.3',
},
plugins: [
'gatsby-plugin-react-helmet',

907
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -20,14 +20,14 @@
"@reach/router": "^1.3.4",
"animate.css": "^4.1.1",
"array-move": "^3.0.1",
"autoprefixer": "^10.0.4",
"autoprefixer": "^10.1.0",
"classnames": "^2.2.6",
"dayjs": "^1.9.6",
"dayjs": "^1.9.7",
"dotenv": "^8.2.0",
"downloadjs": "^1.4.7",
"firebase": "^8.1.2",
"formik": "^2.2.5",
"gatsby": "^2.28.0",
"gatsby": "^2.28.1",
"gatsby-image": "^2.7.0",
"gatsby-plugin-create-client-paths": "^2.6.0",
"gatsby-plugin-firebase": "^0.2.0-beta.4",
@ -36,7 +36,7 @@
"gatsby-plugin-offline": "^3.6.0",
"gatsby-plugin-postcss": "^3.3.0",
"gatsby-plugin-react-helmet": "^3.6.0",
"gatsby-plugin-sharp": "^2.10.0",
"gatsby-plugin-sharp": "^2.10.1",
"gatsby-plugin-sitemap": "^2.8.0",
"gatsby-plugin-webfonts": "^1.1.3",
"gatsby-source-filesystem": "^2.7.0",
@ -46,24 +46,24 @@
"i18next": "^19.8.4",
"lodash": "^4.17.20",
"nanoevents": "^5.1.10",
"postcss": "^8.1.14",
"postcss": "^8.2.0",
"react": "^17.0.1",
"react-beautiful-dnd": "^13.0.0",
"react-dom": "^17.0.1",
"react-helmet": "^6.1.0",
"react-i18next": "^11.7.4",
"react-i18next": "^11.8.1",
"react-icons": "^4.1.0",
"react-markdown": "^5.0.3",
"react-scroll": "^1.8.1",
"react-toastify": "^6.1.0",
"react-toastify": "^6.2.0",
"short-unique-id": "^3.2.0",
"uuid": "^8.3.1",
"yup": "^0.32.1"
"uuid": "^8.3.2",
"yup": "^0.32.6"
},
"devDependencies": {
"eslint": "^7.15.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-config-prettier": "^6.15.0",
"eslint-config-prettier": "^7.0.0",
"eslint-loader": "^4.0.2",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-prettier": "^3.2.0",

View File

@ -60,16 +60,14 @@ const SidebarSection = ({ id, event }) => {
);
};
const LeftSidebar = () => {
return (
<div className="flex">
<LeftNavbar />
const LeftSidebar = () => (
<div className="flex">
<LeftNavbar />
<div id="LeftSidebar" className={styles.container}>
{sections.map(SidebarSection)}
</div>
<div id="LeftSidebar" className={styles.container}>
{sections.map(SidebarSection)}
</div>
);
};
</div>
);
export default memo(LeftSidebar);

View File

@ -4,25 +4,23 @@ import SectionIcon from '../../shared/SectionIcon';
import styles from './RightNavbar.module.css';
import SyncIndicator from './SyncIndicator';
const RightNavbar = () => {
return (
<div className={styles.container}>
<div className="grid grid-cols-1 gap-4 text-primary-500">
{sections.map((x) => (
<SectionIcon
key={x.id}
section={x}
containerId="RightSidebar"
tooltipPlacement="left"
/>
))}
</div>
<hr className="mt-auto my-6" />
<SyncIndicator />
const RightNavbar = () => (
<div className={styles.container}>
<div className="grid grid-cols-1 gap-4 text-primary-500">
{sections.map((x) => (
<SectionIcon
key={x.id}
section={x}
containerId="RightSidebar"
tooltipPlacement="left"
/>
))}
</div>
);
};
<hr className="mt-auto my-6" />
<SyncIndicator />
</div>
);
export default memo(RightNavbar);

View File

@ -45,16 +45,14 @@ const SidebarSection = ({ id, event }) => {
);
};
const RightSidebar = () => {
return (
<div className="flex">
<div id="RightSidebar" className={styles.container}>
{sections.map(SidebarSection)}
</div>
<RightNavbar />
const RightSidebar = () => (
<div className="flex">
<div id="RightSidebar" className={styles.container}>
{sections.map(SidebarSection)}
</div>
);
};
<RightNavbar />
</div>
);
export default memo(RightSidebar);

View File

@ -4,18 +4,16 @@ import Avatar from '../shared/Avatar';
import Logo from '../shared/Logo';
import styles from './TopNavbar.module.css';
const TopNavbar = () => {
return (
<div className={styles.navbar}>
<div className="container">
<Link to="/">
<Logo size="40px" />
</Link>
const TopNavbar = () => (
<div className={styles.navbar}>
<div className="container">
<Link to="/">
<Logo size="40px" />
</Link>
<Avatar className="ml-8" />
</div>
<Avatar className="ml-8" />
</div>
);
};
</div>
);
export default memo(TopNavbar);

View File

@ -3,19 +3,17 @@ import React, { memo } from 'react';
import { getRandomTip } from '../../data/tips';
import Logo from '../shared/Logo';
const LoadingScreen = () => {
return (
<Modal open hideBackdrop>
<Fade in>
<div className="w-screen h-screen flex justify-center items-center outline-none">
<div className="flex flex-col items-center">
<Logo size="48px" className="mb-4" />
<span className="font-medium opacity-75">{getRandomTip()}</span>
</div>
const LoadingScreen = () => (
<Modal open hideBackdrop>
<Fade in>
<div className="w-screen h-screen flex justify-center items-center outline-none">
<div className="flex flex-col items-center">
<Logo size="48px" className="mb-4" />
<span className="font-medium opacity-75">{getRandomTip()}</span>
</div>
</Fade>
</Modal>
);
};
</div>
</Fade>
</Modal>
);
export default memo(LoadingScreen);

View File

@ -8,13 +8,9 @@ const defaultState = { events: ModalEvents, emitter };
const ModalContext = createContext(defaultState);
const ModalProvider = ({ children }) => {
return (
<ModalContext.Provider value={defaultState}>
{children}
</ModalContext.Provider>
);
};
const ModalProvider = ({ children }) => (
<ModalContext.Provider value={defaultState}>{children}</ModalContext.Provider>
);
export default ModalContext;

View File

@ -83,6 +83,10 @@ const languages = [
code: 'tr',
name: 'Turkish (Türkçe)',
},
{
code: 'uk',
name: 'Ukrainian (Українська)',
},
];
i18n.use(initReactI18next).init({

View File

@ -17,6 +17,7 @@ import ptPt from './pt-pt.json';
import ru from './ru.json';
import sv from './sv.json';
import tr from './tr.json';
import uk from './uk.json';
import zh from './zh.json';
export default {
@ -39,5 +40,6 @@ export default {
ru: { translation: ru },
sv: { translation: sv },
tr: { translation: tr },
uk: { translation: uk },
zh: { translation: zh },
};

View File

@ -14,25 +14,23 @@ import SkillModal from './sections/SkillModal';
import SocialModal from './sections/SocialModal';
import WorkModal from './sections/WorkModal';
const ModalRegistrar = () => {
return (
<>
<AuthModal />
<ResumeModal />
<SocialModal />
<WorkModal />
<EducationModal />
<ProjectModal />
<AwardModal />
<CertificateModal />
<SkillModal />
<HobbyModal />
<LanguageModal />
<ReferenceModal />
<ImportModal />
<ExportModal />
</>
);
};
const ModalRegistrar = () => (
<>
<AuthModal />
<ResumeModal />
<SocialModal />
<WorkModal />
<EducationModal />
<ProjectModal />
<AwardModal />
<CertificateModal />
<SkillModal />
<HobbyModal />
<LanguageModal />
<ReferenceModal />
<ImportModal />
<ExportModal />
</>
);
export default memo(ModalRegistrar);

View File

@ -4,112 +4,110 @@ import { Helmet } from 'react-helmet';
import { MdKeyboardArrowLeft } from 'react-icons/md';
import Wrapper from '../components/shared/Wrapper';
const FrequentlyAskedQuestions = () => {
return (
<Wrapper>
<Helmet>
<title>Frequently Asked Questions | Reactive Resume</title>
<link rel="canonical" href="https://rxresu.me/app/dashboard" />
</Helmet>
const FrequentlyAskedQuestions = () => (
<Wrapper>
<Helmet>
<title>Frequently Asked Questions | Reactive Resume</title>
<link rel="canonical" href="https://rxresu.me/app/dashboard" />
</Helmet>
<div className="md:w-1/2 container px-8 md:px-0 py-16 grid gap-12">
<div className="flex items-center">
<Link to="/">
<MdKeyboardArrowLeft size="32px" />
</Link>
<h1 className="ml-6 text-4xl font-semibold">
Frequently Asked Questions
</h1>
</div>
<div>
<p className="leading-loose">
This is aimed to be the world&apos;s simplest privacy policy. This
document should explain to you why the app collects some
information, what happens when your account is deleted and some
other frequently asked questions answered regarding your privacy.
</p>
<p className="mt-6 leading-loose">
If you have any more questions, please raise an issue regarding the
same on GitHub and I&apos;ll answer as honest and quickly as
possible :)
</p>
</div>
<hr />
<div>
<h4 className="text-xl font-medium mb-4">
What identifiable information is stored about me?
</h4>
<p className="leading-loose">
Your name and your email address is stored along with your user
information, if you signed in with Google, and of course, all the
information you input in your resume is also stored in the database.
You won&apos;t even get any marketing emails, feature updates,
newsletters, notification emails, nothing.
</p>
</div>
<hr />
<div>
<h4 className="text-xl font-medium mb-4">
Why are you using a database, why not keep everything local like in
the first version of Reactive Resume?
</h4>
<p className="leading-loose">
Not having a centralized database cause a lot more problems than I
could solve, mainly having a large chunk of the users of the app
having an outdated schema as the app evolved. This was a problem I
could not solve without having at least some control.
</p>
<p className="mt-6 leading-loose">
Also, a lot of users were having trouble printing their resumes on
their browsers, so with the help of Cloud Functions from Firebase,
you can now print your resumes remotely. None of the resumes are
stored, and they are sent to you immediately after generation, which
can be verified by looking through the source code.
</p>
</div>
<hr />
<div>
<h4 className="text-xl font-medium mb-4">
How is this all free? There must be a catch!
</h4>
<p className="leading-loose">
<strong>Absolutely no catch to this freebie.</strong> This project
is just my way of giving back to the community that I&apos;ve
learned so much from. If you&apos;d like to show your appreciation
however, you can follow me on my social media and let me know how
much it helped you, or donate to help pay the cloud bills, or if you
are a fellow developer, you can head to GitHub and contribute to the
code and raising a PR.
</p>
</div>
<hr />
<div>
<h4 className="text-xl font-medium mb-4">
Is there a mobile app for Reactive Resume?
</h4>
<p className="leading-loose">
<strong>Not yet. But soon, maybe?</strong> One of the main
motivations for me to shift to a centralized database approach was
that I could one day build a mobile app as well that could let users
jump from editing on their desktops to editing on their phones. It
requires a lot of time, so I would not expect it any time soon, but
it&apos;s definitely in the pipeline.
</p>
</div>
<div className="md:w-1/2 container px-8 md:px-0 py-16 grid gap-12">
<div className="flex items-center">
<Link to="/">
<MdKeyboardArrowLeft size="32px" />
</Link>
<h1 className="ml-6 text-4xl font-semibold">
Frequently Asked Questions
</h1>
</div>
</Wrapper>
);
};
<div>
<p className="leading-loose">
This is aimed to be the world&apos;s simplest privacy policy. This
document should explain to you why the app collects some information,
what happens when your account is deleted and some other frequently
asked questions answered regarding your privacy.
</p>
<p className="mt-6 leading-loose">
If you have any more questions, please raise an issue regarding the
same on GitHub and I&apos;ll answer as honest and quickly as possible
:)
</p>
</div>
<hr />
<div>
<h4 className="text-xl font-medium mb-4">
What identifiable information is stored about me?
</h4>
<p className="leading-loose">
Your name and your email address is stored along with your user
information, if you signed in with Google, and of course, all the
information you input in your resume is also stored in the database.
You won&apos;t even get any marketing emails, feature updates,
newsletters, notification emails, nothing.
</p>
</div>
<hr />
<div>
<h4 className="text-xl font-medium mb-4">
Why are you using a database, why not keep everything local like in
the first version of Reactive Resume?
</h4>
<p className="leading-loose">
Not having a centralized database cause a lot more problems than I
could solve, mainly having a large chunk of the users of the app
having an outdated schema as the app evolved. This was a problem I
could not solve without having at least some control.
</p>
<p className="mt-6 leading-loose">
Also, a lot of users were having trouble printing their resumes on
their browsers, so with the help of Cloud Functions from Firebase, you
can now print your resumes remotely. None of the resumes are stored,
and they are sent to you immediately after generation, which can be
verified by looking through the source code.
</p>
</div>
<hr />
<div>
<h4 className="text-xl font-medium mb-4">
How is this all free? There must be a catch!
</h4>
<p className="leading-loose">
<strong>Absolutely no catch to this freebie.</strong> This project is
just my way of giving back to the community that I&apos;ve learned so
much from. If you&apos;d like to show your appreciation however, you
can follow me on my social media and let me know how much it helped
you, or donate to help pay the cloud bills, or if you are a fellow
developer, you can head to GitHub and contribute to the code and
raising a PR.
</p>
</div>
<hr />
<div>
<h4 className="text-xl font-medium mb-4">
Is there a mobile app for Reactive Resume?
</h4>
<p className="leading-loose">
<strong>Not yet. But soon, maybe?</strong> One of the main motivations
for me to shift to a centralized database approach was that I could
one day build a mobile app as well that could let users jump from
editing on their desktops to editing on their phones. It requires a
lot of time, so I would not expect it any time soon, but it&apos;s
definitely in the pipeline.
</p>
</div>
</div>
</Wrapper>
);
export default FrequentlyAskedQuestions;

View File

@ -127,16 +127,14 @@ const Home = () => {
);
};
const Feature = ({ icon: Icon, title, children }) => {
return (
<div className="mt-16">
<div className="flex items-center">
<Icon size="18px" className="text-primary-900 mr-4" />
<div className="text-3xl">{title}</div>
</div>
<p className="mt-6 text-lg leading-loose">{children}</p>
const Feature = ({ icon: Icon, title, children }) => (
<div className="mt-16">
<div className="flex items-center">
<Icon size="18px" className="text-primary-900 mr-4" />
<div className="text-3xl">{title}</div>
</div>
);
};
<p className="mt-6 text-lg leading-loose">{children}</p>
</div>
);
export default memo(Home);

View File

@ -52,7 +52,6 @@ const ResumeViewer = ({ id }) => {
</Helmet>
<div
id="page"
className={styles.page}
style={{ backgroundColor: resume.metadata.colors.background }}
>

View File

@ -76,6 +76,7 @@ section {
#page {
width: 21cm;
position: absolute;
text-align: start;
top: 0;
left: 0;
right: 0;

View File

@ -55,6 +55,7 @@ const Castform = ({ data }) => {
return (
<PageContext.Provider value={{ data, heading: HeadingD }}>
<div
id="page"
className="rounded"
style={{
fontFamily: data.metadata.font,

View File

@ -86,6 +86,7 @@ const Celebi = ({ data }) => {
return (
<PageContext.Provider value={{ data, heading: HeadingE }}>
<div
id="page"
className="relative rounded"
style={{
fontFamily: data.metadata.font,

View File

@ -59,6 +59,7 @@ const Gengar = ({ data }) => {
return (
<PageContext.Provider value={{ data, heading: HeadingC }}>
<div
id="page"
className="rounded"
style={{
fontFamily: data.metadata.font,

View File

@ -54,6 +54,7 @@ const Glalie = ({ data }) => {
return (
<PageContext.Provider value={{ data, heading: HeadingB }}>
<div
id="page"
className="rounded"
style={{
fontFamily: data.metadata.font,

View File

@ -33,6 +33,7 @@ const Onyx = ({ data }) => {
return (
<PageContext.Provider value={{ data, heading: HeadingA }}>
<div
id="page"
className="p-8 rounded"
style={{
fontFamily: data.metadata.font,

View File

@ -32,6 +32,7 @@ const Pikachu = ({ data }) => {
return (
<PageContext.Provider value={{ data, heading: HeadingB }}>
<div
id="page"
className="p-8 rounded"
style={{
fontFamily: data.metadata.font,

View File

@ -3,8 +3,8 @@ import { useTranslation } from 'react-i18next';
import PageContext from '../../../contexts/PageContext';
import { safetyCheck } from '../../../utils';
const ContactItem = ({ value, label, link }) => {
return value ? (
const ContactItem = ({ value, label, link }) =>
value ? (
<div className="flex flex-col">
<h6 className="capitalize font-semibold">{label}</h6>
{link ? (
@ -16,7 +16,6 @@ const ContactItem = ({ value, label, link }) => {
)}
</div>
) : null;
};
const ContactC = () => {
const { t } = useTranslation();

View File

@ -4,8 +4,8 @@ import { MdFlare } from 'react-icons/md';
import PageContext from '../../../contexts/PageContext';
import { safetyCheck } from '../../../utils';
const ContactItem = ({ value, label, link }) => {
return value ? (
const ContactItem = ({ value, label, link }) =>
value ? (
<div className="flex flex-col">
<h6 className="capitalize font-semibold">{label}</h6>
{link ? (
@ -17,7 +17,6 @@ const ContactItem = ({ value, label, link }) => {
)}
</div>
) : null;
};
const ContactD = () => {
const { t } = useTranslation();

View File

@ -1,11 +1,7 @@
import React, { memo } from 'react';
const HeadingC = ({ children }) => {
return (
<h6 className="font-bold text-xs uppercase tracking-wide mb-1">
{children}
</h6>
);
};
const HeadingC = ({ children }) => (
<h6 className="font-bold text-xs uppercase tracking-wide mb-1">{children}</h6>
);
export default memo(HeadingC);

View File

@ -1,11 +1,9 @@
import React, { memo } from 'react';
const HeadingC = ({ children }) => {
return (
<h6 className="my-2 text-md uppercase font-semibold tracking-wider pb-1 border-b-2 border-gray-800">
{children}
</h6>
);
};
const HeadingC = ({ children }) => (
<h6 className="my-2 text-md uppercase font-semibold tracking-wider pb-1 border-b-2 border-gray-800">
{children}
</h6>
);
export default memo(HeadingC);

View File

@ -15,6 +15,7 @@ import 'dayjs/locale/nl';
import 'dayjs/locale/pl';
import 'dayjs/locale/pt';
import 'dayjs/locale/tr';
import 'dayjs/locale/uk';
import relativeTime from 'dayjs/plugin/relativeTime';
dayjs.extend(relativeTime);

View File

@ -1,15 +1,13 @@
import dayjs from 'dayjs';
import { get, isEmpty } from 'lodash';
export const getModalText = (isEditMode, type, t) => {
return isEditMode
export const getModalText = (isEditMode, type, t) =>
isEditMode
? `${t('shared.buttons.edit')} ${type}`
: `${t('shared.buttons.add')} ${type}`;
};
export const safetyCheck = (section, path = 'items') => {
return !!(section && section.visible === true && !isEmpty(section[path]));
};
export const safetyCheck = (section, path = 'items') =>
!!(section && section.visible === true && !isEmpty(section[path]));
export const handleKeyUp = (event, action) => {
(event.which === 13 || event.which === 32) && action();