toi bi ngu

This commit is contained in:
2024-11-17 20:27:33 +07:00
parent bb0eed1851
commit 3430971449
14 changed files with 675 additions and 82 deletions

View File

@@ -1,7 +1,14 @@
{ {
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
"vcs": { "enabled": false, "clientKind": "git", "useIgnoreFile": false }, "vcs": {
"files": { "ignoreUnknown": false, "ignore": ["dist"] }, "enabled": false,
"clientKind": "git",
"useIgnoreFile": false
},
"files": {
"ignoreUnknown": false,
"ignore": ["dist"]
},
"formatter": { "formatter": {
"enabled": true, "enabled": true,
"useEditorconfig": true, "useEditorconfig": true,
@@ -9,11 +16,13 @@
"indentStyle": "space", "indentStyle": "space",
"indentWidth": 2, "indentWidth": 2,
"lineEnding": "lf", "lineEnding": "lf",
"lineWidth": 80, "lineWidth": 240,
"attributePosition": "auto", "attributePosition": "auto",
"bracketSpacing": true "bracketSpacing": true
}, },
"organizeImports": { "enabled": true }, "organizeImports": {
"enabled": true
},
"linter": { "linter": {
"enabled": true, "enabled": true,
"rules": { "rules": {

564
package-lock.json generated
View File

@@ -42,6 +42,7 @@
"@prisma/client": "^5.21.1", "@prisma/client": "^5.21.1",
"@smatch-corp/nestjs-pothos": "^0.3.0", "@smatch-corp/nestjs-pothos": "^0.3.0",
"@smatch-corp/nestjs-pothos-apollo-driver": "^0.1.0", "@smatch-corp/nestjs-pothos-apollo-driver": "^0.1.0",
"@turbodocx/html-to-docx": "^1.10.0",
"apollo-server-express": "^3.13.0", "apollo-server-express": "^3.13.0",
"axios": "^1.7.7", "axios": "^1.7.7",
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",
@@ -4123,7 +4124,6 @@
"version": "0.3.6", "version": "0.3.6",
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
"integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/gen-mapping": "^0.3.5",
@@ -5097,6 +5097,93 @@
"license": "MIT", "license": "MIT",
"optional": true "optional": true
}, },
"node_modules/@oozcitak/dom": {
"version": "1.15.6",
"resolved": "https://registry.npmjs.org/@oozcitak/dom/-/dom-1.15.6.tgz",
"integrity": "sha512-k4uEIa6DI3FCrFJMGq/05U/59WnS9DjME0kaPqBRCJAqBTkmopbYV1Xs4qFKbDJ/9wOg8W97p+1E0heng/LH7g==",
"license": "MIT",
"dependencies": {
"@oozcitak/infra": "1.0.5",
"@oozcitak/url": "1.0.0",
"@oozcitak/util": "8.3.4"
},
"engines": {
"node": ">=8.0"
}
},
"node_modules/@oozcitak/infra": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@oozcitak/infra/-/infra-1.0.5.tgz",
"integrity": "sha512-o+zZH7M6l5e3FaAWy3ojaPIVN5eusaYPrKm6MZQt0DKNdgXa2wDYExjpP0t/zx+GoQgQKzLu7cfD8rHCLt8JrQ==",
"license": "MIT",
"dependencies": {
"@oozcitak/util": "8.0.0"
},
"engines": {
"node": ">=6.0"
}
},
"node_modules/@oozcitak/infra/node_modules/@oozcitak/util": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-8.0.0.tgz",
"integrity": "sha512-+9Hq6yuoq/3TRV/n/xcpydGBq2qN2/DEDMqNTG7rm95K6ZE2/YY/sPyx62+1n8QsE9O26e5M1URlXsk+AnN9Jw==",
"license": "MIT",
"engines": {
"node": ">=6.0"
}
},
"node_modules/@oozcitak/url": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@oozcitak/url/-/url-1.0.0.tgz",
"integrity": "sha512-LGrMeSxeLzsdaitxq3ZmBRVOrlRRQIgNNci6L0VRnOKlJFuRIkNm4B+BObXPCJA6JT5bEJtrrwjn30jueHJYZQ==",
"license": "MIT",
"dependencies": {
"@oozcitak/infra": "1.0.3",
"@oozcitak/util": "1.0.2"
},
"engines": {
"node": ">=8.0"
}
},
"node_modules/@oozcitak/url/node_modules/@oozcitak/infra": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@oozcitak/infra/-/infra-1.0.3.tgz",
"integrity": "sha512-9O2wxXGnRzy76O1XUxESxDGsXT5kzETJPvYbreO4mv6bqe1+YSuux2cZTagjJ/T4UfEwFJz5ixanOqB0QgYAag==",
"license": "MIT",
"dependencies": {
"@oozcitak/util": "1.0.1"
},
"engines": {
"node": ">=6.0"
}
},
"node_modules/@oozcitak/url/node_modules/@oozcitak/infra/node_modules/@oozcitak/util": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-1.0.1.tgz",
"integrity": "sha512-dFwFqcKrQnJ2SapOmRD1nQWEZUtbtIy9Y6TyJquzsalWNJsKIPxmTI0KG6Ypyl8j7v89L2wixH9fQDNrF78hKg==",
"license": "MIT",
"engines": {
"node": ">=6.0"
}
},
"node_modules/@oozcitak/url/node_modules/@oozcitak/util": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-1.0.2.tgz",
"integrity": "sha512-4n8B1cWlJleSOSba5gxsMcN4tO8KkkcvXhNWW+ADqvq9Xj+Lrl9uCa90GRpjekqQJyt84aUX015DG81LFpZYXA==",
"license": "MIT",
"engines": {
"node": ">=6.0"
}
},
"node_modules/@oozcitak/util": {
"version": "8.3.4",
"resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-8.3.4.tgz",
"integrity": "sha512-6gH/bLQJSJEg7OEpkH4wGQdA8KXHRbzL1YkGyUO12YNAgV3jxKy4K9kvfXj4+9T0OLug5k58cnPCKSSIKzp7pg==",
"license": "MIT",
"engines": {
"node": ">=8.0"
}
},
"node_modules/@payos/node": { "node_modules/@payos/node": {
"version": "1.0.10", "version": "1.0.10",
"resolved": "https://registry.npmjs.org/@payos/node/-/node-1.0.10.tgz", "resolved": "https://registry.npmjs.org/@payos/node/-/node-1.0.10.tgz",
@@ -5514,6 +5601,28 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@turbodocx/html-to-docx": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@turbodocx/html-to-docx/-/html-to-docx-1.10.0.tgz",
"integrity": "sha512-zVA/Z8kCSh4KgKmVpy3a9+DdL5Fhjbdih/OYywWSfDzG7h80mcVJRj6jN5iJWDSk/du9dtZvZ8CUNegPPf8fpg==",
"license": "MIT",
"dependencies": {
"@oozcitak/dom": "1.15.6",
"@oozcitak/util": "8.3.4",
"color-name": "^1.1.4",
"html-entities": "^2.3.3",
"html-minifier-terser": "^7.2.0",
"html-to-vdom": "^0.7.0",
"image-size": "^1.0.0",
"image-to-base64": "^2.2.0",
"jszip": "^3.7.1",
"lodash": "^4.17.21",
"mime-types": "^2.1.35",
"nanoid": "^3.1.25",
"virtual-dom": "^2.1.1",
"xmlbuilder2": "2.1.2"
}
},
"node_modules/@types/accepts": { "node_modules/@types/accepts": {
"version": "1.3.7", "version": "1.3.7",
"resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.7.tgz", "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.7.tgz",
@@ -6544,7 +6653,6 @@
"version": "8.14.0", "version": "8.14.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
"dev": true,
"license": "MIT", "license": "MIT",
"bin": { "bin": {
"acorn": "bin/acorn" "acorn": "bin/acorn"
@@ -7690,6 +7798,12 @@
"integrity": "sha512-8CVjaLJGuSKMVTxJ2DpBl5XnlNDiT4cQFeuCJJrvJmts9YrTZDizTX7PjC2s6W4x+MBGZeEY6dGMrF04/6Hgqg==", "integrity": "sha512-8CVjaLJGuSKMVTxJ2DpBl5XnlNDiT4cQFeuCJJrvJmts9YrTZDizTX7PjC2s6W4x+MBGZeEY6dGMrF04/6Hgqg==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/browser-split": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/browser-split/-/browser-split-0.0.1.tgz",
"integrity": "sha512-JhvgRb2ihQhsljNda3BI8/UcRHVzrVwo3Q+P8vDtSiyobXuFpuZ9mq+MbRGMnC22CjW3RrfXdg6j6ITX8M+7Ow==",
"license": "MIT"
},
"node_modules/browserslist": { "node_modules/browserslist": {
"version": "4.24.2", "version": "4.24.2",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz",
@@ -7912,6 +8026,15 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/camelize": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz",
"integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001676", "version": "1.0.30001676",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001676.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001676.tgz",
@@ -9046,6 +9169,11 @@
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
} }
}, },
"node_modules/dom-walk": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
"integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w=="
},
"node_modules/domelementtype": { "node_modules/domelementtype": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
@@ -9293,6 +9421,24 @@
"node": ">=10.13.0" "node": ">=10.13.0"
} }
}, },
"node_modules/ent": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ent/-/ent-2.2.1.tgz",
"integrity": "sha512-QHuXVeZx9d+tIQAz/XztU0ZwZf2Agg9CcXcgE1rurqvdBeDBrpSwjl8/6XUqMg7tw2Y7uAdKb2sRv+bSEFqQ5A==",
"license": "MIT",
"dependencies": {
"punycode": "^1.4.1"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/ent/node_modules/punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
"integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==",
"license": "MIT"
},
"node_modules/entities": { "node_modules/entities": {
"version": "4.5.0", "version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
@@ -9309,6 +9455,16 @@
"resolved": "", "resolved": "",
"link": true "link": true
}, },
"node_modules/error": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/error/-/error-4.4.0.tgz",
"integrity": "sha512-SNDKualLUtT4StGFP7xNfuFybL2f6iJujFtrWuvJqGbVQGaN+adE23veqzPz1hjUjTunLi2EnJ+0SJxtbJreKw==",
"dependencies": {
"camelize": "^1.0.0",
"string-template": "~0.2.0",
"xtend": "~4.0.0"
}
},
"node_modules/error-ex": { "node_modules/error-ex": {
"version": "1.3.2", "version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -9645,6 +9801,14 @@
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/ev-store": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/ev-store/-/ev-store-7.0.0.tgz",
"integrity": "sha512-otazchNRnGzp2YarBJ+GXKVGvhxVATB1zmaStxJBYet0Dyq7A9VhH8IUEB/gRcL6Ch52lfpgPTRJ2m49epyMsQ==",
"dependencies": {
"individual": "^3.0.0"
}
},
"node_modules/event-target-shim": { "node_modules/event-target-shim": {
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
@@ -10500,6 +10664,16 @@
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
"license": "BSD-2-Clause" "license": "BSD-2-Clause"
}, },
"node_modules/global": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz",
"integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==",
"license": "MIT",
"dependencies": {
"min-document": "^2.19.0",
"process": "^0.11.10"
}
},
"node_modules/globals": { "node_modules/globals": {
"version": "15.11.0", "version": "15.11.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-15.11.0.tgz", "resolved": "https://registry.npmjs.org/globals/-/globals-15.11.0.tgz",
@@ -10996,6 +11170,22 @@
"node": ">=18" "node": ">=18"
} }
}, },
"node_modules/html-entities": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz",
"integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/mdevils"
},
{
"type": "patreon",
"url": "https://patreon.com/mdevils"
}
],
"license": "MIT"
},
"node_modules/html-escaper": { "node_modules/html-escaper": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
@@ -11025,6 +11215,57 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/html-minifier-terser": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz",
"integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==",
"license": "MIT",
"dependencies": {
"camel-case": "^4.1.2",
"clean-css": "~5.3.2",
"commander": "^10.0.0",
"entities": "^4.4.0",
"param-case": "^3.0.4",
"relateurl": "^0.2.7",
"terser": "^5.15.1"
},
"bin": {
"html-minifier-terser": "cli.js"
},
"engines": {
"node": "^14.13.1 || >=16.0.0"
}
},
"node_modules/html-minifier-terser/node_modules/clean-css": {
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz",
"integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==",
"license": "MIT",
"dependencies": {
"source-map": "~0.6.0"
},
"engines": {
"node": ">= 10.0"
}
},
"node_modules/html-minifier-terser/node_modules/commander": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
"integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
"license": "MIT",
"engines": {
"node": ">=14"
}
},
"node_modules/html-minifier-terser/node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/html-minifier/node_modules/camel-case": { "node_modules/html-minifier/node_modules/camel-case": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz",
@@ -11094,6 +11335,92 @@
"node": ">=14" "node": ">=14"
} }
}, },
"node_modules/html-to-vdom": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/html-to-vdom/-/html-to-vdom-0.7.0.tgz",
"integrity": "sha512-k+d2qNkbx0JO00KezQsNcn6k2I/xSBP4yXYFLvXbcasTTDh+RDLUJS3puxqyNnpdyXWRHFGoKU7cRmby8/APcQ==",
"license": "ISC",
"dependencies": {
"ent": "^2.0.0",
"htmlparser2": "^3.8.2"
}
},
"node_modules/html-to-vdom/node_modules/dom-serializer": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
"integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==",
"license": "MIT",
"dependencies": {
"domelementtype": "^2.0.1",
"entities": "^2.0.0"
}
},
"node_modules/html-to-vdom/node_modules/dom-serializer/node_modules/domelementtype": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
],
"license": "BSD-2-Clause"
},
"node_modules/html-to-vdom/node_modules/dom-serializer/node_modules/entities": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
"integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
"license": "BSD-2-Clause",
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/html-to-vdom/node_modules/domelementtype": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
"integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
"license": "BSD-2-Clause"
},
"node_modules/html-to-vdom/node_modules/domhandler": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
"integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
"license": "BSD-2-Clause",
"dependencies": {
"domelementtype": "1"
}
},
"node_modules/html-to-vdom/node_modules/domutils": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
"integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
"license": "BSD-2-Clause",
"dependencies": {
"dom-serializer": "0",
"domelementtype": "1"
}
},
"node_modules/html-to-vdom/node_modules/entities": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
"license": "BSD-2-Clause"
},
"node_modules/html-to-vdom/node_modules/htmlparser2": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
"integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
"license": "MIT",
"dependencies": {
"domelementtype": "^1.3.1",
"domhandler": "^2.3.0",
"domutils": "^1.5.1",
"entities": "^1.1.1",
"inherits": "^2.0.1",
"readable-stream": "^3.1.1"
}
},
"node_modules/htmlparser2": { "node_modules/htmlparser2": {
"version": "8.0.2", "version": "8.0.2",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
@@ -11218,6 +11545,36 @@
"node": ">= 4" "node": ">= 4"
} }
}, },
"node_modules/image-size": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz",
"integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==",
"license": "MIT",
"dependencies": {
"queue": "6.0.2"
},
"bin": {
"image-size": "bin/image-size.js"
},
"engines": {
"node": ">=16.x"
}
},
"node_modules/image-to-base64": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/image-to-base64/-/image-to-base64-2.2.0.tgz",
"integrity": "sha512-Z+aMwm/91UOQqHhrz7Upre2ytKhWejZlWV/JxUTD1sT7GWWKFDJUEV5scVQKnkzSgPHFuQBUEWcanO+ma0PSVw==",
"license": "MIT",
"dependencies": {
"node-fetch": "^2.6.0"
}
},
"node_modules/immediate": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
"integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
"license": "MIT"
},
"node_modules/immutable": { "node_modules/immutable": {
"version": "3.7.6", "version": "3.7.6",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz", "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz",
@@ -11306,6 +11663,11 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/individual": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/individual/-/individual-3.0.0.tgz",
"integrity": "sha512-rUY5vtT748NMRbEMrTNiFfy29BgGZwGXUi2NFUVMWQrogSLzlJvQV9eeMWi+g1aVaQ53tpyLAQtd5x/JH0Nh1g=="
},
"node_modules/inflight": { "node_modules/inflight": {
"version": "1.0.6", "version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@@ -11599,6 +11961,15 @@
"node": ">=0.12.0" "node": ">=0.12.0"
} }
}, },
"node_modules/is-object": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz",
"integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-path-inside": { "node_modules/is-path-inside": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
@@ -12895,6 +13266,48 @@
"promise": "^7.0.1" "promise": "^7.0.1"
} }
}, },
"node_modules/jszip": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
"integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
"license": "(MIT OR GPL-3.0-or-later)",
"dependencies": {
"lie": "~3.3.0",
"pako": "~1.0.2",
"readable-stream": "~2.3.6",
"setimmediate": "^1.0.5"
}
},
"node_modules/jszip/node_modules/readable-stream": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"license": "MIT",
"dependencies": {
"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"
}
},
"node_modules/jszip/node_modules/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==",
"license": "MIT"
},
"node_modules/jszip/node_modules/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==",
"license": "MIT",
"dependencies": {
"safe-buffer": "~5.1.0"
}
},
"node_modules/juice": { "node_modules/juice": {
"version": "10.0.1", "version": "10.0.1",
"resolved": "https://registry.npmjs.org/juice/-/juice-10.0.1.tgz", "resolved": "https://registry.npmjs.org/juice/-/juice-10.0.1.tgz",
@@ -13067,6 +13480,15 @@
"license": "MIT", "license": "MIT",
"optional": true "optional": true
}, },
"node_modules/lie": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
"integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
"license": "MIT",
"dependencies": {
"immediate": "~3.0.5"
}
},
"node_modules/lines-and-columns": { "node_modules/lines-and-columns": {
"version": "1.2.4", "version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
@@ -13765,6 +14187,14 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/min-document": {
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
"integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==",
"dependencies": {
"dom-walk": "^0.1.0"
}
},
"node_modules/minimatch": { "node_modules/minimatch": {
"version": "3.1.2", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@@ -14384,6 +14814,24 @@
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
"node_modules/nanoid": {
"version": "3.3.7",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/natural-compare": { "node_modules/natural-compare": {
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
@@ -14420,6 +14868,12 @@
"@nestjs/core": ">7.0.0" "@nestjs/core": ">7.0.0"
} }
}, },
"node_modules/next-tick": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-0.2.2.tgz",
"integrity": "sha512-f7h4svPtl+QidoBv4taKXUjJ70G2asaZ8G28nS0OkqaalX8dwwrtWtyxEDPK62AC00ur/+/E0pUwBwY5EPn15Q==",
"license": "MIT"
},
"node_modules/nice-try": { "node_modules/nice-try": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
@@ -14898,6 +15352,12 @@
"devOptional": true, "devOptional": true,
"license": "BlueOak-1.0.0" "license": "BlueOak-1.0.0"
}, },
"node_modules/pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
"license": "(MIT AND Zlib)"
},
"node_modules/param-case": { "node_modules/param-case": {
"version": "3.0.4", "version": "3.0.4",
"resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
@@ -15384,6 +15844,15 @@
"fsevents": "2.3.3" "fsevents": "2.3.3"
} }
}, },
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
"license": "MIT",
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/process-nextick-args": { "node_modules/process-nextick-args": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@@ -15665,6 +16134,15 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/queue": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz",
"integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==",
"license": "MIT",
"dependencies": {
"inherits": "~2.0.3"
}
},
"node_modules/queue-microtask": { "node_modules/queue-microtask": {
"version": "1.2.3", "version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -15890,7 +16368,6 @@
"resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
"integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==",
"license": "MIT", "license": "MIT",
"optional": true,
"engines": { "engines": {
"node": ">= 0.10" "node": ">= 0.10"
} }
@@ -16630,7 +17107,6 @@
"version": "0.5.21", "version": "0.5.21",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"buffer-from": "^1.0.0", "buffer-from": "^1.0.0",
@@ -16641,7 +17117,6 @@
"version": "0.6.1", "version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
@@ -16778,6 +17253,11 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/string-template": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz",
"integrity": "sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw=="
},
"node_modules/string-width": { "node_modules/string-width": {
"version": "4.2.3", "version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
@@ -17104,7 +17584,6 @@
"version": "5.36.0", "version": "5.36.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.36.0.tgz", "resolved": "https://registry.npmjs.org/terser/-/terser-5.36.0.tgz",
"integrity": "sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==", "integrity": "sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==",
"dev": true,
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"dependencies": { "dependencies": {
"@jridgewell/source-map": "^0.3.3", "@jridgewell/source-map": "^0.3.3",
@@ -17189,7 +17668,6 @@
"version": "2.20.3", "version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/test-exclude": { "node_modules/test-exclude": {
@@ -17978,6 +18456,22 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/virtual-dom": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/virtual-dom/-/virtual-dom-2.1.1.tgz",
"integrity": "sha512-wb6Qc9Lbqug0kRqo/iuApfBpJJAq14Sk1faAnSmtqXiwahg7PVTvWMs9L02Z8nNIMqbwsxzBAA90bbtRLbw0zg==",
"license": "MIT",
"dependencies": {
"browser-split": "0.0.1",
"error": "^4.3.0",
"ev-store": "^7.0.0",
"global": "^4.3.0",
"is-object": "^1.0.1",
"next-tick": "^0.2.2",
"x-is-array": "0.1.0",
"x-is-string": "0.1.0"
}
},
"node_modules/void-elements": { "node_modules/void-elements": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
@@ -18476,6 +18970,16 @@
} }
} }
}, },
"node_modules/x-is-array": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/x-is-array/-/x-is-array-0.1.0.tgz",
"integrity": "sha512-goHPif61oNrr0jJgsXRfc8oqtYzvfiMJpTqwE7Z4y9uH+T3UozkGqQ4d2nX9mB9khvA8U2o/UbPOFjgC7hLWIA=="
},
"node_modules/x-is-string": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz",
"integrity": "sha512-GojqklwG8gpzOVEVki5KudKNoq7MbbjYZCbyWzEz7tyPA7eleiE0+ePwOWQQRb5fm86rD3S8Tc0tSFf3AOv50w=="
},
"node_modules/xml-name-validator": { "node_modules/xml-name-validator": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
@@ -18507,6 +19011,52 @@
"node": ">=4.0" "node": ">=4.0"
} }
}, },
"node_modules/xmlbuilder2": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/xmlbuilder2/-/xmlbuilder2-2.1.2.tgz",
"integrity": "sha512-PI710tmtVlQ5VmwzbRTuhmVhKnj9pM8Si+iOZCV2g2SNo3gCrpzR2Ka9wNzZtqfD+mnP+xkrqoNy0sjKZqP4Dg==",
"license": "MIT",
"dependencies": {
"@oozcitak/dom": "1.15.5",
"@oozcitak/infra": "1.0.5",
"@oozcitak/util": "8.3.3"
},
"engines": {
"node": ">=8.0"
}
},
"node_modules/xmlbuilder2/node_modules/@oozcitak/dom": {
"version": "1.15.5",
"resolved": "https://registry.npmjs.org/@oozcitak/dom/-/dom-1.15.5.tgz",
"integrity": "sha512-L6v3Mwb0TaYBYgeYlIeBaHnc+2ZEaDSbFiRm5KmqZQSoBlbPlf+l6aIH/sD5GUf2MYwULw00LT7+dOnEuAEC0A==",
"license": "MIT",
"dependencies": {
"@oozcitak/infra": "1.0.5",
"@oozcitak/url": "1.0.0",
"@oozcitak/util": "8.0.0"
},
"engines": {
"node": ">=8.0"
}
},
"node_modules/xmlbuilder2/node_modules/@oozcitak/dom/node_modules/@oozcitak/util": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-8.0.0.tgz",
"integrity": "sha512-+9Hq6yuoq/3TRV/n/xcpydGBq2qN2/DEDMqNTG7rm95K6ZE2/YY/sPyx62+1n8QsE9O26e5M1URlXsk+AnN9Jw==",
"license": "MIT",
"engines": {
"node": ">=6.0"
}
},
"node_modules/xmlbuilder2/node_modules/@oozcitak/util": {
"version": "8.3.3",
"resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-8.3.3.tgz",
"integrity": "sha512-Ufpab7G5PfnEhQyy5kDg9C8ltWJjsVT1P/IYqacjstaqydG4Q21HAT2HUZQYBrC/a1ZLKCz87pfydlDvv8y97w==",
"license": "MIT",
"engines": {
"node": ">=6.0"
}
},
"node_modules/xmlchars": { "node_modules/xmlchars": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",

View File

@@ -64,6 +64,7 @@
"@prisma/client": "^5.21.1", "@prisma/client": "^5.21.1",
"@smatch-corp/nestjs-pothos": "^0.3.0", "@smatch-corp/nestjs-pothos": "^0.3.0",
"@smatch-corp/nestjs-pothos-apollo-driver": "^0.1.0", "@smatch-corp/nestjs-pothos-apollo-driver": "^0.1.0",
"@turbodocx/html-to-docx": "^1.10.0",
"apollo-server-express": "^3.13.0", "apollo-server-express": "^3.13.0",
"axios": "^1.7.7", "axios": "^1.7.7",
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",

View File

@@ -155,7 +155,7 @@ export class CenterMentorSchema extends PothosSchema {
} }
// build signature // build signature
const token = this.jwtUtils.signTokenRS256( const token = this.jwtUtils.signTokenRS256(
JSON.stringify({ centerId: center.id, email: args.email }), { centerId: center.id, email: args.email },
'1d', '1d',
) )
// build invite url // build invite url
@@ -185,7 +185,7 @@ export class CenterMentorSchema extends PothosSchema {
return this.prisma.$transaction(async () => { return this.prisma.$transaction(async () => {
// sign token // sign token
const token = this.jwtUtils.signTokenRS256( const token = this.jwtUtils.signTokenRS256(
JSON.stringify({ centerId: args.centerId, email: args.email }), { centerId: args.centerId, email: args.email },
'1d', '1d',
) )
// build invite url // build invite url

View File

@@ -11,11 +11,13 @@ import { DocumentEvent } from './document.event'
import { Document } from '@prisma/client' import { Document } from '@prisma/client'
import { DocumentDelta } from './document.type' import { DocumentDelta } from './document.type'
import Delta from 'quill-delta' import Delta from 'quill-delta'
import { MinioService } from 'src/Minio/minio.service'
@Injectable() @Injectable()
export class DocumentSchema extends PothosSchema { export class DocumentSchema extends PothosSchema {
constructor( constructor(
@Inject(SchemaBuilderToken) private readonly builder: Builder, @Inject(SchemaBuilderToken) private readonly builder: Builder,
private readonly prisma: PrismaService, private readonly prisma: PrismaService,
private readonly minio: MinioService,
) { ) {
super() super()
} }
@@ -46,6 +48,7 @@ export class DocumentSchema extends PothosSchema {
delta: t.field({ delta: t.field({
type: 'Delta', type: 'Delta',
}), }),
senderId: t.string(),
}), }),
}) })
} }
@@ -88,6 +91,30 @@ export class DocumentSchema extends PothosSchema {
}) })
}, },
}), }),
newDocument: t.field({
type: this.document(),
args: {},
resolve: async (query, _args, ctx, _info) => {
if (ctx.isSubscription) throw new Error('Not allowed')
const userId = ctx.http?.me?.id
if (!userId) throw new Error('User not found')
const fileUrl = await this.minio.getFileUrl(
'document',
'document',
'document',
)
if (!fileUrl) throw new Error('File not found')
const document = await this.prisma.document.create({
...query,
data: {
name: 'Untitled',
fileUrl,
ownerId: userId,
},
})
return document
},
}),
})) }))
this.builder.mutationFields((t) => ({ this.builder.mutationFields((t) => ({
@@ -99,10 +126,16 @@ export class DocumentSchema extends PothosSchema {
required: true, required: true,
}), }),
}, },
resolve: async (query, _root, args) => { resolve: async (query, _root, args, ctx: SchemaContext) => {
if (ctx.isSubscription) throw new Error('Not allowed')
const userId = ctx.http?.me?.id
if (!userId) throw new Error('User not found')
return await this.prisma.document.create({ return await this.prisma.document.create({
...query, ...query,
data: args.data, data: {
...args.data,
// ownerId: userId,
},
}) })
}, },
}), }),
@@ -120,6 +153,7 @@ export class DocumentSchema extends PothosSchema {
documentId: args.documentId, documentId: args.documentId,
pageIndex: args.pageIndex, pageIndex: args.pageIndex,
delta, delta,
senderId: ctx.http?.me?.id,
} }
ctx.http.pubSub.publish( ctx.http.pubSub.publish(
`${DocumentEvent.CHANGED}.${args.documentId}`, `${DocumentEvent.CHANGED}.${args.documentId}`,
@@ -142,10 +176,12 @@ export class DocumentSchema extends PothosSchema {
const { const {
http: { pubSub }, http: { pubSub },
} = ctx } = ctx
pubSub.publish( const senderId = ctx.http?.me?.id
`${DocumentEvent.CHANGED}.${args.data.documentId}`, if (!senderId) throw new Error('User not found')
args.data, pubSub.publish(`${DocumentEvent.CHANGED}.${args.data.documentId}`, {
) ...args.data,
senderId,
})
return args.data return args.data
}, },
}), }),
@@ -172,7 +208,11 @@ export class DocumentSchema extends PothosSchema {
`${DocumentEvent.SAVED}.${args.documentId}`, `${DocumentEvent.SAVED}.${args.documentId}`,
]) as unknown as AsyncIterable<DocumentDelta> ]) as unknown as AsyncIterable<DocumentDelta>
}, },
resolve: async (payload: DocumentDelta) => payload, resolve: async (payload: DocumentDelta, _args, ctx: SchemaContext) => {
if (!ctx.isSubscription) throw new Error('Not allowed')
if (payload.senderId === ctx.websocket?.me?.id) return
return payload
},
}), }),
})) }))
} }

View File

@@ -31,7 +31,7 @@ export class DocumentService {
const { default: Quill } = await import('quill') const { default: Quill } = await import('quill')
this.quill = Quill this.quill = Quill
} }
// TODO: maybe never do :)
async handleOnChange(delta: DocumentDelta) {} async handleOnChange(delta: DocumentDelta) {}
async handleOnSave() {} async handleOnSave() {}

View File

@@ -3,4 +3,5 @@ import Delta from 'quill-delta'
export type DocumentDelta = Delta & { export type DocumentDelta = Delta & {
pageIndex: number pageIndex: number
documentId: string documentId: string
senderId?: string
} }

View File

@@ -34,6 +34,7 @@ export type SchemaContext =
websocket: { websocket: {
req: Request req: Request
pubSub: PubSub pubSub: PubSub
sessionId: string
me: User me: User
generator: PrismaCrudGenerator<BuilderTypes> generator: PrismaCrudGenerator<BuilderTypes>
} }
@@ -159,8 +160,8 @@ export class Builder extends SchemaBuilder<SchemaBuilderOption> {
}, },
}) })
this.scalarType('Delta', { this.scalarType('Delta', {
serialize: (value) => value.toString(), serialize: (value) => JSON.stringify(value),
parseValue: (value: unknown) => value as unknown as Delta, parseValue: (value: unknown) => JSON.parse(value as string) as Delta,
parseLiteral: (ast: ValueNode) => ast as unknown as Delta, parseLiteral: (ast: ValueNode) => ast as unknown as Delta,
}) })

View File

@@ -41,6 +41,7 @@ import { WorkshopSubscriptionModule } from '../WorkshopSubscription/workshopsubs
import { initContextCache } from '@pothos/core' import { initContextCache } from '@pothos/core'
import { PubSub } from 'graphql-subscriptions' import { PubSub } from 'graphql-subscriptions'
import { DocumentModule } from 'src/Document/document.module' import { DocumentModule } from 'src/Document/document.module'
import { Context } from 'graphql-ws'
@Global() @Global()
@Module({ @Module({
@@ -90,25 +91,43 @@ import { DocumentModule } from 'src/Document/document.module'
debug: process.env.NODE_ENV === 'development' || false, debug: process.env.NODE_ENV === 'development' || false,
playground: process.env.NODE_ENV === 'development' || false, playground: process.env.NODE_ENV === 'development' || false,
introspection: process.env.NODE_ENV === 'development' || false, introspection: process.env.NODE_ENV === 'development' || false,
installSubscriptionHandlers: true,
subscriptions: { subscriptions: {
'graphql-ws': true, 'graphql-ws': {
onConnect: (ctx: Context<Record<string, unknown>>) => {
if (!ctx.connectionParams) {
throw new Error('No connectionParams provided')
}
if (!ctx.extra) {
throw new Error('No extra provided')
}
// @ts-expect-error: TODO
ctx.extra.request.headers['x-session-id'] = ctx.connectionParams['x-session-id']
},
},
}, },
context: async ({ context: async ({
req, req,
subscriptions, subscriptions,
extra, extra,
// biome-ignore lint/suspicious/noExplicitAny: <explanation> }: {
}: { req?: Request; subscriptions?: any; extra?: any }) => { req?: Request
subscriptions?: Record<string, never>
extra?: Record<string, never>
}) => {
initContextCache() initContextCache()
if (subscriptions) { if (subscriptions) {
// @ts-expect-error: TODO
if (!extra?.request?.headers['x-session-id']) {
throw new Error('No sessionId provided')
}
return { return {
isSubscription: true, isSubscription: true,
websocket: { websocket: {
req: extra.request, req: extra?.request,
pubSub: pubsub, pubSub: pubsub,
me: await graphqlService.acquireContext( // @ts-expect-error: TODO
extra.request.headers['x-session-id'], me: await graphqlService.acquireContextFromSessionId(extra.request.headers['x-session-id']),
),
}, },
} }
} }
@@ -118,10 +137,7 @@ import { DocumentModule } from 'src/Document/document.module'
req, req,
me: req ? await graphqlService.acquireContext(req) : null, me: req ? await graphqlService.acquireContext(req) : null,
pubSub: pubsub, pubSub: pubsub,
invalidateCache: () => invalidateCache: () => graphqlService.invalidateCache(req?.headers['x-session-id'] as string),
graphqlService.invalidateCache(
req?.headers['x-session-id'] as string,
),
}, },
} }
}, },
@@ -132,8 +148,7 @@ import { DocumentModule } from 'src/Document/document.module'
RedisService, RedisService,
{ {
provide: GraphqlService, provide: GraphqlService,
useFactory: (prisma: PrismaService, redis: RedisService) => useFactory: (prisma: PrismaService, redis: RedisService) => new GraphqlService(prisma, redis),
new GraphqlService(prisma, redis),
inject: [PrismaService, 'REDIS_CLIENT'], inject: [PrismaService, 'REDIS_CLIENT'],
}, },
{ {
@@ -151,12 +166,6 @@ import { DocumentModule } from 'src/Document/document.module'
useFactory: () => new PubSub(), useFactory: () => new PubSub(),
}, },
], ],
exports: [ exports: [Builder, PrismaCrudGenerator, GraphqlService, RedisService, 'PUB_SUB'],
Builder,
PrismaCrudGenerator,
GraphqlService,
RedisService,
'PUB_SUB',
],
}) })
export class GraphqlModule {} export class GraphqlModule {}

View File

@@ -18,6 +18,12 @@ export class GraphqlService {
@Inject('REDIS_CLIENT') private readonly redis: RedisService, @Inject('REDIS_CLIENT') private readonly redis: RedisService,
) {} ) {}
async acquireContextFromSessionId(sessionId: string) {
return this.acquireContext({
headers: { 'x-session-id': sessionId },
} as unknown as Request)
}
async acquireContext(req: Request) { async acquireContext(req: Request) {
// get x-session-id from headers // get x-session-id from headers
let sessionId: string let sessionId: string

View File

@@ -433,7 +433,6 @@ export class UserSchema extends PothosSchema {
const { const {
websocket: { pubSub }, websocket: { pubSub },
} = ctx } = ctx
Logger.log(ctx.websocket.me?.id, 'Me ID')
return pubSub.asyncIterator([ return pubSub.asyncIterator([
`${PubSubEvent.NEW_MESSAGE}.${ctx.websocket.me?.id}`, `${PubSubEvent.NEW_MESSAGE}.${ctx.websocket.me?.id}`,
]) as unknown as AsyncIterable<Message> ]) as unknown as AsyncIterable<Message>

View File

@@ -4,10 +4,10 @@ import { Injectable } from '@nestjs/common'
@Injectable() @Injectable()
export class JwtUtils { export class JwtUtils {
signToken(payload: string, expiresIn: string) { signToken(payload: object, expiresIn: string) {
return sign(payload, process.env.JWT_SECRET!, { expiresIn }) return sign(payload, process.env.JWT_SECRET!, { expiresIn })
} }
signTokenRS256(payload: string, expiresIn: string) { signTokenRS256(payload: object, expiresIn: string) {
const privateKey = process.env.JWT_RS256_PRIVATE_KEY const privateKey = process.env.JWT_RS256_PRIVATE_KEY
if (!privateKey) { if (!privateKey) {
throw new Error('JWT_RS256_PRIVATE_KEY is not defined') throw new Error('JWT_RS256_PRIVATE_KEY is not defined')

View File

@@ -7,54 +7,32 @@ import { clerkMiddleware } from '@clerk/express'
import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.js' import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.js'
import path from 'node:path' import path from 'node:path'
import { readFileSync } from 'node:fs' import { readFileSync } from 'node:fs'
import { json } from 'express'
async function bootstrap() { async function bootstrap() {
const app = await NestFactory.create(AppModule) const app = await NestFactory.create(AppModule)
// load private key and public key // load private key and public key
const privateKey = readFileSync( const privateKey = readFileSync(path.join(__dirname, 'KeyStore', 'private_key.pem'), 'utf8')
path.join(__dirname, 'KeyStore', 'private_key.pem'), const publicKey = readFileSync(path.join(__dirname, 'KeyStore', 'public_key.pem'), 'utf8')
'utf8',
)
const publicKey = readFileSync(
path.join(__dirname, 'KeyStore', 'public_key.pem'),
'utf8',
)
// set private key and public key to env // set private key and public key to env
process.env.JWT_RS256_PRIVATE_KEY = privateKey process.env.JWT_RS256_PRIVATE_KEY = privateKey
process.env.JWT_RS256_PUBLIC_KEY = publicKey process.env.JWT_RS256_PUBLIC_KEY = publicKey
Logger.log( Logger.log(`Private key: ${privateKey.slice(0, 10).replace(/\n/g, '')}...`, 'Bootstrap')
`Private key: ${privateKey.slice(0, 10).replace(/\n/g, '')}...`, Logger.log(`Public key: ${publicKey.slice(0, 10).replace(/\n/g, '')}...`, 'Bootstrap')
'Bootstrap',
)
Logger.log(
`Public key: ${publicKey.slice(0, 10).replace(/\n/g, '')}...`,
'Bootstrap',
)
const corsOrigin = (process.env.CORS_ORIGIN ?? '').split(',') // split by comma to array const corsOrigin = (process.env.CORS_ORIGIN ?? '').split(',') // split by comma to array
app.enableCors({ app.enableCors({
origin: corsOrigin, origin: corsOrigin,
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'], methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
allowedHeaders: [ allowedHeaders: ['Content-Type', '*', 'x-apollo-operation-name', 'x-session-id'],
'Content-Type',
'*',
'x-apollo-operation-name',
'x-session-id',
],
credentials: true, credentials: true,
}) })
// set base path for api // set base path for api
app.setGlobalPrefix(process.env.API_PATH ?? '/v1') app.setGlobalPrefix(process.env.API_PATH ?? '/v1')
const config = new DocumentBuilder() const config = new DocumentBuilder().setTitle('EPESS API').setDescription('API documentation for EPESS application').setVersion('0.0.1').addBearerAuth().build()
.setTitle('EPESS API')
.setDescription('API documentation for EPESS application')
.setVersion('0.0.1')
.addBearerAuth()
.build()
const document = SwaggerModule.createDocument(app, config) const document = SwaggerModule.createDocument(app, config)
SwaggerModule.setup(process.env.SWAGGER_PATH ?? 'v1', app, document) SwaggerModule.setup(process.env.SWAGGER_PATH ?? 'v1', app, document)
@@ -63,8 +41,7 @@ async function bootstrap() {
get: { get: {
tags: ['GraphQL'], tags: ['GraphQL'],
summary: 'GraphQL Playground', summary: 'GraphQL Playground',
description: description: 'Access the GraphQL Playground to interact with the GraphQL API.',
'Access the GraphQL Playground to interact with the GraphQL API.',
responses: { responses: {
'200': { '200': {
description: 'GraphQL Playground', description: 'GraphQL Playground',
@@ -74,6 +51,9 @@ async function bootstrap() {
} }
try { try {
// body parser
app.use(json({ limit: '50mb' }))
// clerk middleware // clerk middleware
app.use(clerkMiddleware({})) app.use(clerkMiddleware({}))
@@ -87,10 +67,7 @@ async function bootstrap() {
) )
// biome-ignore lint/suspicious/noExplicitAny: <explanation> // biome-ignore lint/suspicious/noExplicitAny: <explanation>
} catch (error: any) { } catch (error: any) {
Logger.error( Logger.error(`Error in file upload middleware: ${error.message}`, 'Bootstrap')
`Error in file upload middleware: ${error.message}`,
'Bootstrap',
)
// Optionally, you can handle the error further or rethrow it // Optionally, you can handle the error further or rethrow it
} }