diff --git a/apps/vdb-backend/package.json b/apps/vdb-backend/package.json index 3541d6d..c85b825 100644 --- a/apps/vdb-backend/package.json +++ b/apps/vdb-backend/package.json @@ -25,6 +25,7 @@ "express": "^5.1.0", "google-auth-library": "^10.3.0", "googleapis": "^159.0.0", + "node-fetch": "^3.3.2", "reflect-metadata": "^0.2.2", "sqlite3": "^5.1.7", "typeorm": "0.3.26" diff --git a/apps/vdb-backend/src/auth.ts b/apps/vdb-backend/src/auth.ts index d91e281..734c0cf 100644 --- a/apps/vdb-backend/src/auth.ts +++ b/apps/vdb-backend/src/auth.ts @@ -1,5 +1,6 @@ import { promises as fs } from "fs"; +import fetch from 'node-fetch'; import * as path from "path"; import { authenticate } from "@google-cloud/local-auth"; import { google } from "googleapis"; diff --git a/apps/vdb-backend/src/db/dbservice.ts b/apps/vdb-backend/src/db/dbmapper.ts similarity index 100% rename from apps/vdb-backend/src/db/dbservice.ts rename to apps/vdb-backend/src/db/dbmapper.ts diff --git a/apps/vdb-backend/src/db/dbmodel.ts b/apps/vdb-backend/src/db/dbmodel.ts index 5189e12..18143e4 100644 --- a/apps/vdb-backend/src/db/dbmodel.ts +++ b/apps/vdb-backend/src/db/dbmodel.ts @@ -1,124 +1,120 @@ -import "reflect-metadata" +import "reflect-metadata"; import { - Entity, - PrimaryGeneratedColumn, - Column, - PrimaryColumn, - BaseEntity, - ManyToOne, - OneToMany, - OneToOne, - ManyToMany, - JoinTable, - ColumnType + Entity, + PrimaryGeneratedColumn, + Column, + PrimaryColumn, + BaseEntity, + ManyToOne, + OneToMany, + OneToOne, + ManyToMany, + JoinTable, + ColumnType, } from "typeorm"; - @Entity() export class Lemma extends BaseEntity { - @PrimaryColumn({type: 'text'}) - lemma_name: string; + @PrimaryColumn({ type: "text" }) + lemma_name: string; - @OneToMany(() => WordForm, (word_form) => word_form.lemma) - word_forms: WordForm[]; + @OneToMany(() => WordForm, (word_form) => word_form.lemma, { cascade: true}) + word_forms: WordForm[]; - @OneToMany(() => Example, (example) => example.lemma) - examples: Example[]; + @OneToMany(() => Example, (example) => example.lemma) + examples: Example[]; - @OneToMany(() => Definition, (definition) => definition.lemma) - definitions: Definition[]; + @OneToMany(() => Definition, (definition) => definition.lemma) + definitions: Definition[]; - @OneToMany(() => Comment, (comment) => comment.lemma) - comments: Comment[]; + @OneToMany(() => Comment, (comment) => comment.lemma) + comments: Comment[]; - @OneToMany(() => Media, (media) => media.lemma) - media: Media[]; - - @ManyToMany(() => PartOfSpeech) - @JoinTable() - parts_of_speech: PartOfSpeech[]; + @OneToMany(() => Media, (media) => media.lemma) + media: Media[]; + @ManyToMany(() => PartOfSpeech) + @JoinTable() + parts_of_speech: PartOfSpeech[]; } @Entity() export class Lect extends BaseEntity { - @PrimaryColumn({type: 'text'}) - name: string; - - @OneToMany(() => WordForm, (w) => w.lect) - word_forms: WordForm[]; + @PrimaryColumn({ type: "text" }) + name: string; + @OneToMany(() => WordForm, (w) => w.lect) + word_forms: WordForm[]; } @Entity() export class WordForm extends BaseEntity { - @PrimaryColumn({type: 'integer'}) - word_form_id: number - - @Column({type: 'text'}) - word_form: string; + @PrimaryColumn({ type: "integer" }) + word_form_id: number; - @ManyToOne(() => Lemma, (lemma) => lemma.word_forms) - lemma: Lemma; + @Column({ type: "text" }) + word_form: string; - @ManyToOne(() => Lect, (lect) => lect.word_forms) - lect: Lect; + @ManyToOne(() => Lemma, (lemma) => lemma.word_forms) + lemma: Lemma; + + @ManyToOne(() => Lect, (lect) => lect.word_forms) + lect: Lect; } @Entity() export class Example extends BaseEntity { - @PrimaryGeneratedColumn() - example_id: number; + @PrimaryGeneratedColumn() + example_id: number; - @Column({ nullable: false, type: 'text' }) - example_text: string; + @Column({ nullable: false, type: "text" }) + example_text: string; - @ManyToOne(() => Lemma, (lemma) => lemma.examples) - lemma: Lemma; + @ManyToOne(() => Lemma, (lemma) => lemma.examples) + lemma: Lemma; } @Entity() export class Media extends BaseEntity { - @PrimaryGeneratedColumn() - media_id: number; + @PrimaryGeneratedColumn() + media_id: number; - @Column({ nullable: false, type: 'text'}) - media_url: string; + @Column({ nullable: false, type: "text" }) + media_url: string; - @ManyToOne(() => Lemma, (lemma) => lemma.media) - lemma: Lemma; + @ManyToOne(() => Lemma, (lemma) => lemma.media) + lemma: Lemma; } @Entity() export class Definition extends BaseEntity { - @PrimaryGeneratedColumn() - definition_id: number; + @PrimaryGeneratedColumn() + definition_id: number; - @Column({ nullable: false, type: 'text' }) - definition_text: string; + @Column({ nullable: false, type: "text" }) + definition_text: string; - @ManyToOne(() => Lemma, (lemma) => lemma.definitions) - lemma: Lemma; + @ManyToOne(() => Lemma, (lemma) => lemma.definitions) + lemma: Lemma; } @Entity() export class Comment extends BaseEntity { - @PrimaryGeneratedColumn() - comment_id: number; + @PrimaryGeneratedColumn() + comment_id: number; - @Column({ nullable: false, type: 'text' }) - comment_text: string; + @Column({ nullable: false, type: "text" }) + comment_text: string; - @ManyToOne(() => Lemma, (lemma) => lemma.comments) - lemma: Lemma; + @ManyToOne(() => Lemma, (lemma) => lemma.comments) + lemma: Lemma; } @Entity() export class PartOfSpeech extends BaseEntity { - @PrimaryColumn({type: 'text'}) - long_form: string; + @PrimaryColumn({ type: "text" }) + long_form: string; - @Column({ nullable: false, unique: true, type: 'text' }) - short_form: string; + @Column({ nullable: false, unique: true, type: "text" }) +short_form: string; } - diff --git a/apps/vdb-backend/src/index.ts b/apps/vdb-backend/src/index.ts index 7fdba31..e948ff2 100644 --- a/apps/vdb-backend/src/index.ts +++ b/apps/vdb-backend/src/index.ts @@ -1,10 +1,11 @@ import "reflect-metadata"; +import fetch from "node-fetch"; import { SAMPLE } from "@repo/common/sample"; import express from "express"; import { google, sheets_v4 } from "googleapis"; -import { OAuth2Client } from 'google-auth-library'; +import { OAuth2Client } from "google-auth-library"; import { appDataSource } from "./config/dbconfig.js"; -import { authorize } from "./auth.js" +import { authorize } from "./auth.js"; import { Lemma, WordForm, @@ -18,7 +19,7 @@ import { const RELOAD_SHEET_ON_START = false; - +global.fetch = fetch as any; appDataSource .initialize() @@ -39,7 +40,6 @@ appDataSource }) .catch((error) => console.log(error)); - function initExpress() { const app = express(); const PORT = 1225; @@ -48,28 +48,19 @@ function initExpress() { const word_form_repository = appDataSource.getRepository(WordForm); const lemma_repository = appDataSource.getRepository(Lemma); - app.get("/", (req, res) => { - res.render("search", { title: "Suha", message: "Bratsa" }); - }); - app.get("/sample", (_req, res) => { res.status(200).send(SAMPLE); }); app.get("/search", async (req, res) => { - const search_term = req.query.search_term?.toString(); - if(!search_term) { + if (!search_term) { return; } const lemmas: Lemma[] = ( - await Lemma.find({ - relations: { - word_forms: { lect: true }, - }, - }) + await Lemma.find({ relations: { word_forms: { lect: true } } }) ).filter((e) => { for (const wf of e.word_forms) { if (wf.word_form.includes(search_term)) { @@ -79,15 +70,34 @@ function initExpress() { }); const lects = await Lect.find(); - return res.render("search_results", { + res.status(200).send({ terms: lemmas.length, results: lemmas, lects: lects, }); }); - app.set("views", "./res/views"); - app.set("view engine", "pug"); + app.get("/lect", async (req, res) => { + const name = req.query.name?.toString(); + + if (!name) { + return; + } + + const lect = await Lect.findOne({ + where: { name: name }, + relations: { word_forms: { lemma: true } }, + }); + + res.status(200).send({ lect }); + }); + + app.get("/lects", async (req, res) => { + const lects = await Lect.find() + res.status(200).send({ + lects + }); + }); app.listen(PORT, () => { console.log(`Backend started @ http://localhost:${PORT} !`); @@ -99,86 +109,101 @@ function initExpress() { * @param {google.auth.OAuth2Client} auth The authenticated Google OAuth client. */ async function loadSheet(auth: OAuth2Client) { - const options: any = { version: "v4", auth }; - const sheets = google.sheets(options); - const res = await sheets.spreadsheets.values.get({ - spreadsheetId: "1-YkCeynx_-KYdubvt14augSPo37_20YgUv_f-i8HVwY", - range: "al_ko_mit_govor", - }); + const lect_repository = appDataSource.getRepository(Lect); + const word_form_repository = appDataSource.getRepository(WordForm); + const lemma_repository = appDataSource.getRepository(Lemma); + const options: any = { version: "v4", auth }; + const sheets = google.sheets(options); + const res = await sheets.spreadsheets.values.get({ + spreadsheetId: "1-YkCeynx_-KYdubvt14augSPo37_20YgUv_f-i8HVwY", + range: "al_ko_mit_govor", + }); - const rows = res.data.values; - - const keys_res = await sheets.spreadsheets.values.get({ - spreadsheetId: "1-YkCeynx_-KYdubvt14augSPo37_20YgUv_f-i8HVwY", - range: "klucz", - }); + const rows = res.data.values; - const keys = keys_res.data.values; - - if (!rows || rows.length === 0) { - console.error("No data found."); - return; - } + const keys_res = await sheets.spreadsheets.values.get({ + spreadsheetId: "1-YkCeynx_-KYdubvt14augSPo37_20YgUv_f-i8HVwY", + range: "klucz", + }); - if (!keys || keys.length === 0) { - console.error("No lemma keys found."); - return; - } + const keys = keys_res.data.values; - const lects = rows.shift(); + if (!rows || rows.length === 0) { + console.error("No data found."); + return; + } - if (keys.length != rows.length) { - console.error("Lemma count doesn't match number of rows."); - return; - } + if (!keys || keys.length === 0) { + console.error("No lemma keys found."); + return; + } - if (!lects){ - console.error("No lects found"); - return; - } + const lects = rows.shift(); - for (const lect of lects) { - let l = new Lect(); - l.name = lect; - l.save(); - console.log(l); - } + if (keys.length != rows.length) { + console.error("Lemma count doesn't match number of rows."); + return; + } - const nikolect = lects.indexOf("Nikomiko"); + if (!lects) { + console.error("No lects found"); + return; + } - for (let i = 0; i < rows.length; i++) { - const row = rows[i]; + for (const lect of lects) { + let l = new Lect(); + l.name = lect; + l.save(); + console.log(l); + } - const lemma_key = keys[i]?.[0]; - const lemma = new Lemma(); + const nikolect = lects.indexOf("Nikomiko"); + const lemmas = Array(); + for (let i = 0; i < rows.length; i++) { + const row = rows[i]; - if (lemma_key == null || lemma_key.length == 0) { - //assign a random UUID to the lemma as punishment for our failures - lemma.lemma_name = crypto.randomUUID(); - console.log(`womp womp, missing lemma name, calling it ${lemma.lemma_name}`) - } else { - lemma.lemma_name = lemma_key; - } + const lemma_key = keys[i]?.[0]; + const lemma = new Lemma(); - console.log(lemma); - await lemma.save(); + if (lemma_key == null || lemma_key.length == 0) { + //assign a random UUID to the lemma as punishment for our failures + lemma.lemma_name = crypto.randomUUID(); + console.log( + `womp womp, missing lemma name, calling it ${lemma.lemma_name}`, + ); + } else { + lemma.lemma_name = lemma_key; + } - for(let i=0; i(); - for (let word_form of cell.split(";")) { - const f = new WordForm(); - f.word_form = word_form; - f.lemma = lemma; - f.lect = lects[i]; - //console.log(f); - await f.save(); - } + for (let i = 0; i < rows.length; i++) { + const cell = row?.[i]; + if ( + cell === null + || cell === undefined + || (typeof cell === "string" && cell.length === 0) + ) { + continue; + } - } + for (let word_form of cell.split(";")) { + const f = new WordForm(); + f.word_form = word_form; + f.lect = lects[i]; + //console.log(f); + lemma.word_forms.push(f); + } + } + } - } -} \ No newline at end of file + for (let i = 0; i < lemmas.length; i += 100) { + await lemma_repository.save(lemmas.slice(i, i + 100)); + console.log( + `Saved ${Math.min(i + 100, lemmas.length)} / ${lemmas.length} lemmas...`, + ); + } + + console.log(`Loaded ${lemmas.length} lemmas!`); +} diff --git a/apps/vdn-static/package.json b/apps/vdn-static/package.json index 599813b..c7a1edc 100644 --- a/apps/vdn-static/package.json +++ b/apps/vdn-static/package.json @@ -11,6 +11,7 @@ "dependencies": { "@tailwindcss/vite": "^4.1.6", "@types/node": "^22.15.17", + "axios": "^1.11.0", "bulma": "^1.0.4", "tailwindcss": "^4.1.6", "vue": "^3.5.13", diff --git a/apps/vdn-static/src/App.vue b/apps/vdn-static/src/App.vue index 371ef2a..7d86f51 100644 --- a/apps/vdn-static/src/App.vue +++ b/apps/vdn-static/src/App.vue @@ -42,9 +42,9 @@ const toggleBurger = (): void => { Resources - {{ - SAMPLE - }} + + Kotoba + diff --git a/apps/vdn-static/src/components/pages/KotobaPage.vue b/apps/vdn-static/src/components/pages/KotobaPage.vue new file mode 100644 index 0000000..6df35e7 --- /dev/null +++ b/apps/vdn-static/src/components/pages/KotobaPage.vue @@ -0,0 +1,17 @@ + + + + + diff --git a/apps/vdn-static/src/routes/index.ts b/apps/vdn-static/src/routes/index.ts index 506679d..d98e3fc 100644 --- a/apps/vdn-static/src/routes/index.ts +++ b/apps/vdn-static/src/routes/index.ts @@ -3,10 +3,12 @@ import type { RouteRecordRaw } from "vue-router"; import HomePage from "@/components/pages/HomePage.vue"; import ResourcesPage from "@/components/pages/ResourcesPage.vue"; +import KotobaPage from "@/components/pages/KotobaPage.vue"; const routes: RouteRecordRaw[] = [ { path: "/", name: "Home", component: HomePage }, { path: "/resources", name: "Resources", component: ResourcesPage }, + { path: "/kotoba", name: "Kotoba", component: KotobaPage }, // { // path: '/:pathMatch(.*)*', // Vue Router 4 catch-all for 404s // name: 'NotFound', diff --git a/libs/common/package.json b/libs/common/package.json index af3f69b..f4865cc 100644 --- a/libs/common/package.json +++ b/libs/common/package.json @@ -21,5 +21,8 @@ "devDependencies": { "rimraf": "^6.0.1", "typescript": "~5.8.3" + }, + "dependencies": { + "class-transformer": "^0.5.1" } } diff --git a/libs/common/src/dto.ts b/libs/common/src/dto.ts new file mode 100644 index 0000000..9fffed4 --- /dev/null +++ b/libs/common/src/dto.ts @@ -0,0 +1,51 @@ +export interface LemmaDto { + lemma_name: string; + word_forms: WordFormDto[]; + examples: ExampleDto[]; + definitions: DefinitionDto[]; + comments: CommentDto[]; + media: MediaDto[]; + + parts_of_speech: PartOfSpeechDto[]; +} + +export interface LectDto { + name: string; + word_forms: WordFormDto[]; +} + +export interface WordFormDto { + word_form_id: number; + word_form: string; + lemma: LemmaDto; + lect: LectDto; +} + +export interface ExampleDto { + example_id: number; + example_text: string; + lemma: LemmaDto; +} + +export interface MediaDto { + media_id: number; + media_url: string; + lemma: LemmaDto; +} + +export interface DefinitionDto { + definition_id: number; + definition_text: string; + lemma: LemmaDto; +} + +export interface CommentDto { + comment_id: number; + comment_text: string; + lemma: LemmaDto; +} + +export interface PartOfSpeechDto { + long_form: string; + short_form: string; +} diff --git a/package.json b/package.json index ec05281..a0d36ed 100644 --- a/package.json +++ b/package.json @@ -2,5 +2,16 @@ "devDependencies": { "turbo": "^2.5.4" }, - "packageManager": "pnpm@10.11.0" + "packageManager": "pnpm@10.11.0", + "scripts": { + "build:vdb-backend": "npm run build -w apps/vdb-backend", + "build:vdn-static": "npm run build -w apps/vdn-static", + "run:dev:vdb-backend": "npm run dev -w apps/vdb-backend", + "run:dev:vdn-static": "npm run dev -w apps/vdn-static", + "run:dev:all": "run-p run:dev:vdb-backend run:dev:vdn-static" + }, + "workspaces": [ + "apps/vdb-backend", + "apps/vdn-static" + ] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0cd4bfc..f3669e7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -32,6 +32,9 @@ importers: googleapis: specifier: ^159.0.0 version: 159.0.0 + node-fetch: + specifier: ^3.3.2 + version: 3.3.2 reflect-metadata: specifier: ^0.2.2 version: 0.2.2 @@ -60,6 +63,9 @@ importers: '@types/node': specifier: ^22.15.17 version: 22.15.31 + axios: + specifier: ^1.11.0 + version: 1.11.0 bulma: specifier: ^1.0.4 version: 1.0.4 @@ -114,6 +120,10 @@ importers: version: 2.2.10(typescript@5.8.3) libs/common: + dependencies: + class-transformer: + specifier: ^0.5.1 + version: 0.5.1 devDependencies: rimraf: specifier: ^6.0.1 @@ -979,10 +989,16 @@ packages: resolution: {integrity: sha512-1UWOyC50xI3QZkRuDj6PqDtpm1oHWtYs+NQGwqL/2R11eN3Q81PHAHPM0SWW3BNQm53UDwS//Jv8L4CCVLM1bQ==} engines: {node: '>=16.14.0'} + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} + axios@1.11.0: + resolution: {integrity: sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -1074,6 +1090,9 @@ packages: resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} engines: {node: '>=18'} + class-transformer@0.5.1: + resolution: {integrity: sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==} + clean-stack@2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} @@ -1093,6 +1112,10 @@ packages: resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} hasBin: true + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -1175,6 +1198,10 @@ packages: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + delegates@1.0.0: resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} @@ -1251,6 +1278,10 @@ packages: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + esbuild@0.25.5: resolution: {integrity: sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==} engines: {node: '>=18'} @@ -1398,6 +1429,15 @@ packages: flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + for-each@0.3.5: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} @@ -1406,6 +1446,10 @@ packages: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} + form-data@4.0.4: + resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} + engines: {node: '>= 6'} + formdata-polyfill@4.0.10: resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} @@ -1857,10 +1901,18 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + mime-db@1.54.0: resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} engines: {node: '>= 0.6'} + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + mime-types@3.0.1: resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==} engines: {node: '>= 0.6'} @@ -2142,6 +2194,9 @@ packages: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + pump@3.0.3: resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} @@ -3508,10 +3563,20 @@ snapshots: '@babel/parser': 7.27.5 ast-kit: 1.4.3 + asynckit@0.4.0: {} + available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.1.0 + axios@1.11.0: + dependencies: + follow-redirects: 1.15.11 + form-data: 4.0.4 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + balanced-match@1.0.2: {} base64-js@1.5.1: {} @@ -3637,6 +3702,8 @@ snapshots: chownr@3.0.0: {} + class-transformer@0.5.1: {} + clean-stack@2.2.0: optional: true @@ -3655,6 +3722,10 @@ snapshots: color-support@1.1.3: optional: true + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + concat-map@0.0.1: {} confbox@0.1.8: {} @@ -3710,6 +3781,8 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 + delayed-stream@1.0.0: {} + delegates@1.0.0: optional: true @@ -3772,6 +3845,13 @@ snapshots: dependencies: es-errors: 1.3.0 + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + esbuild@0.25.5: optionalDependencies: '@esbuild/aix-ppc64': 0.25.5 @@ -3992,6 +4072,8 @@ snapshots: flatted@3.3.3: {} + follow-redirects@1.15.11: {} + for-each@0.3.5: dependencies: is-callable: 1.2.7 @@ -4001,6 +4083,14 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 + form-data@4.0.4: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + formdata-polyfill@4.0.10: dependencies: fetch-blob: 3.2.0 @@ -4497,8 +4587,14 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 + mime-db@1.52.0: {} + mime-db@1.54.0: {} + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + mime-types@3.0.1: dependencies: mime-db: 1.54.0 @@ -4781,6 +4877,8 @@ snapshots: forwarded: 0.2.0 ipaddr.js: 1.9.1 + proxy-from-env@1.1.0: {} + pump@3.0.3: dependencies: end-of-stream: 1.4.5