Refactor code structure for improved readability and maintainability
This commit is contained in:
Vendored
-12
@@ -1,12 +0,0 @@
|
||||
export interface AiModelInfo {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
model: string;
|
||||
path: string;
|
||||
trigger: string;
|
||||
access: string;
|
||||
}
|
||||
export declare class AiController {
|
||||
getModels(): AiModelInfo[];
|
||||
}
|
||||
Vendored
-79
@@ -1,79 +0,0 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AiController = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const public_decorator_1 = require("../auth/decorators/public.decorator");
|
||||
const ai_service_1 = require("./ai.service");
|
||||
const RECEIPT_IMPORT_MODEL = 'mistral-small-2603';
|
||||
let AiController = class AiController {
|
||||
getModels() {
|
||||
return [
|
||||
{
|
||||
id: 'receipt-pdf',
|
||||
name: 'Kvittoimport — PDF-tolkning',
|
||||
description: 'Extraherar varunamn, mängd och pris ur PDF-kvitton via textanalys.',
|
||||
model: RECEIPT_IMPORT_MODEL,
|
||||
path: '/import',
|
||||
trigger: 'Vid uppladdning av PDF-kvitto',
|
||||
access: 'Alla inloggade',
|
||||
},
|
||||
{
|
||||
id: 'receipt-image',
|
||||
name: 'Kvittoimport — Bildtolkning',
|
||||
description: 'Extraherar varunamn, mängd och pris ur kvittofoton via bildanalys.',
|
||||
model: RECEIPT_IMPORT_MODEL,
|
||||
path: '/import',
|
||||
trigger: 'Vid uppladdning av kvittobild (JPEG, PNG, WebP, HEIC)',
|
||||
access: 'Alla inloggade',
|
||||
},
|
||||
{
|
||||
id: 'receipt-category',
|
||||
name: 'Kvittoimport — Kategorisuggestion',
|
||||
description: 'För varor som inte matchas mot befintliga produkter visas ett AI-förslag på kategori som ledtråd.',
|
||||
model: ai_service_1.AI_CATEGORIZATION_MODEL,
|
||||
path: '/import',
|
||||
trigger: 'Automatiskt efter kvittotolkning (om inga träffar hittas)',
|
||||
access: 'Premium-användare + Admin',
|
||||
},
|
||||
{
|
||||
id: 'product-suggest',
|
||||
name: 'AI-kategorisering per produkt',
|
||||
description: 'Ger ett AI-förslag på kategori för en enskild produkt med säkerhetsindikation (hög/medel/låg).',
|
||||
model: ai_service_1.AI_CATEGORIZATION_MODEL,
|
||||
path: '/admin/products',
|
||||
trigger: 'Manuell — klick på "✨ Fråga AI" i produktlistan',
|
||||
access: 'Admin',
|
||||
},
|
||||
{
|
||||
id: 'product-bulk',
|
||||
name: 'AI-bulk-kategorisering',
|
||||
description: 'Analyserar alla okategoriserade produkter och presenterar förslag i ett bekräftelsemodal.',
|
||||
model: ai_service_1.AI_CATEGORIZATION_MODEL,
|
||||
path: '/admin/products',
|
||||
trigger: 'Manuell — knappen "✨ AI-kategorisera okategoriserade"',
|
||||
access: 'Admin',
|
||||
},
|
||||
];
|
||||
}
|
||||
};
|
||||
exports.AiController = AiController;
|
||||
__decorate([
|
||||
(0, common_1.Get)('models'),
|
||||
(0, public_decorator_1.Public)(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", []),
|
||||
__metadata("design:returntype", Array)
|
||||
], AiController.prototype, "getModels", null);
|
||||
exports.AiController = AiController = __decorate([
|
||||
(0, common_1.Controller)('ai')
|
||||
], AiController);
|
||||
//# sourceMappingURL=ai.controller.js.map
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"ai.controller.js","sourceRoot":"","sources":["../../src/ai/ai.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAiD;AACjD,0EAA6D;AAC7D,6CAAuD;AAEvD,MAAM,oBAAoB,GAAG,oBAAoB,CAAC;AAa3C,IAAM,YAAY,GAAlB,MAAM,YAAY;IAGvB,SAAS;QACP,OAAO;YACL;gBACE,EAAE,EAAE,aAAa;gBACjB,IAAI,EAAE,6BAA6B;gBACnC,WAAW,EAAE,oEAAoE;gBACjF,KAAK,EAAE,oBAAoB;gBAC3B,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,+BAA+B;gBACxC,MAAM,EAAE,gBAAgB;aACzB;YACD;gBACE,EAAE,EAAE,eAAe;gBACnB,IAAI,EAAE,6BAA6B;gBACnC,WAAW,EAAE,oEAAoE;gBACjF,KAAK,EAAE,oBAAoB;gBAC3B,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,uDAAuD;gBAChE,MAAM,EAAE,gBAAgB;aACzB;YACD;gBACE,EAAE,EAAE,kBAAkB;gBACtB,IAAI,EAAE,mCAAmC;gBACzC,WAAW,EAAE,mGAAmG;gBAChH,KAAK,EAAE,oCAAuB;gBAC9B,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,2DAA2D;gBACpE,MAAM,EAAE,2BAA2B;aACpC;YACD;gBACE,EAAE,EAAE,iBAAiB;gBACrB,IAAI,EAAE,+BAA+B;gBACrC,WAAW,EAAE,gGAAgG;gBAC7G,KAAK,EAAE,oCAAuB;gBAC9B,IAAI,EAAE,iBAAiB;gBACvB,OAAO,EAAE,iDAAiD;gBAC1D,MAAM,EAAE,OAAO;aAChB;YACD;gBACE,EAAE,EAAE,cAAc;gBAClB,IAAI,EAAE,wBAAwB;gBAC9B,WAAW,EAAE,2FAA2F;gBACxG,KAAK,EAAE,oCAAuB;gBAC9B,IAAI,EAAE,iBAAiB;gBACvB,OAAO,EAAE,uDAAuD;gBAChE,MAAM,EAAE,OAAO;aAChB;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AApDY,oCAAY;AAGvB;IAFC,IAAA,YAAG,EAAC,QAAQ,CAAC;IACb,IAAA,yBAAM,GAAE;;;;6CAiDR;uBAnDU,YAAY;IADxB,IAAA,mBAAU,EAAC,IAAI,CAAC;GACJ,YAAY,CAoDxB"}
|
||||
Vendored
-2
@@ -1,2 +0,0 @@
|
||||
export declare class AiModule {
|
||||
}
|
||||
Vendored
-23
@@ -1,23 +0,0 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AiModule = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const ai_service_1 = require("./ai.service");
|
||||
const ai_controller_1 = require("./ai.controller");
|
||||
let AiModule = class AiModule {
|
||||
};
|
||||
exports.AiModule = AiModule;
|
||||
exports.AiModule = AiModule = __decorate([
|
||||
(0, common_1.Module)({
|
||||
controllers: [ai_controller_1.AiController],
|
||||
providers: [ai_service_1.AiService],
|
||||
exports: [ai_service_1.AiService],
|
||||
})
|
||||
], AiModule);
|
||||
//# sourceMappingURL=ai.module.js.map
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"ai.module.js","sourceRoot":"","sources":["../../src/ai/ai.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,6CAAyC;AACzC,mDAA+C;AAOxC,IAAM,QAAQ,GAAd,MAAM,QAAQ;CAAG,CAAA;AAAX,4BAAQ;mBAAR,QAAQ;IALpB,IAAA,eAAM,EAAC;QACN,WAAW,EAAE,CAAC,4BAAY,CAAC;QAC3B,SAAS,EAAE,CAAC,sBAAS,CAAC;QACtB,OAAO,EAAE,CAAC,sBAAS,CAAC;KACrB,CAAC;GACW,QAAQ,CAAG"}
|
||||
Vendored
-34
@@ -1,34 +0,0 @@
|
||||
import { FlatCategory } from '../categories/categories.service';
|
||||
export declare const AI_CATEGORIZATION_MODEL = "mistral-tiny";
|
||||
export type CategorySuggestion = {
|
||||
categoryId: number;
|
||||
categoryName: string;
|
||||
path: string;
|
||||
confidence: 'high' | 'medium' | 'low';
|
||||
usedFallback: boolean;
|
||||
};
|
||||
export type AiIngredientMatchSuggestion = {
|
||||
productId: number;
|
||||
reason?: string;
|
||||
confidence: 'high' | 'medium' | 'low';
|
||||
};
|
||||
export type AiSubstitutionSuggestion = {
|
||||
productId: number;
|
||||
reason?: string;
|
||||
confidence: 'high' | 'medium' | 'low';
|
||||
};
|
||||
export declare class AiService {
|
||||
private readonly logger;
|
||||
suggestIngredientMatches(rawIngredient: string, candidates: Array<{
|
||||
id: number;
|
||||
name: string;
|
||||
canonicalName?: string | null;
|
||||
}>): Promise<AiIngredientMatchSuggestion[]>;
|
||||
suggestSubstitutions(rawIngredient: string, availableProducts: Array<{
|
||||
id: number;
|
||||
name: string;
|
||||
canonicalName?: string | null;
|
||||
}>): Promise<AiSubstitutionSuggestion[]>;
|
||||
suggestCategory(productName: string, categories: FlatCategory[]): Promise<CategorySuggestion>;
|
||||
private fallbackToOvrigt;
|
||||
}
|
||||
Vendored
-240
@@ -1,240 +0,0 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var AiService_1;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AiService = exports.AI_CATEGORIZATION_MODEL = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const MISTRAL_API_URL = 'https://api.mistral.ai/v1/chat/completions';
|
||||
exports.AI_CATEGORIZATION_MODEL = 'mistral-tiny';
|
||||
const MODEL = exports.AI_CATEGORIZATION_MODEL;
|
||||
let AiService = AiService_1 = class AiService {
|
||||
constructor() {
|
||||
this.logger = new common_1.Logger(AiService_1.name);
|
||||
}
|
||||
async suggestIngredientMatches(rawIngredient, candidates) {
|
||||
const apiKey = process.env.MISTRAL_API_KEY;
|
||||
if (!apiKey || candidates.length === 0)
|
||||
return [];
|
||||
const candidateList = candidates
|
||||
.map((c) => `[${c.id}] ${c.canonicalName || c.name}`)
|
||||
.join('\n');
|
||||
const systemPrompt = `Du matchar en ingrediensrad mot produktkandidater.
|
||||
Svara ENDAST med JSON: {"matches":[{"productId":123,"reason":"...","confidence":"high|medium|low"}]}
|
||||
Regler:
|
||||
1. Välj max 3 kandidater.
|
||||
2. Om inget passar, returnera tom lista.`;
|
||||
const userPrompt = `Ingrediens: "${rawIngredient}"\nKandidater:\n${candidateList}`;
|
||||
try {
|
||||
const response = await fetch(MISTRAL_API_URL, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${apiKey}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: MODEL,
|
||||
messages: [
|
||||
{ role: 'system', content: systemPrompt },
|
||||
{ role: 'user', content: userPrompt },
|
||||
],
|
||||
max_tokens: 300,
|
||||
temperature: 0.1,
|
||||
response_format: { type: 'json_object' },
|
||||
}),
|
||||
});
|
||||
if (!response.ok) {
|
||||
this.logger.warn(`suggestIngredientMatches API-fel: ${response.status}`);
|
||||
return [];
|
||||
}
|
||||
const data = (await response.json());
|
||||
const raw = data.choices?.[0]?.message?.content ?? '{}';
|
||||
const parsed = JSON.parse(raw);
|
||||
return Array.isArray(parsed.matches) ? parsed.matches.slice(0, 3) : [];
|
||||
}
|
||||
catch (err) {
|
||||
this.logger.warn(`suggestIngredientMatches misslyckades: ${String(err)}`);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
async suggestSubstitutions(rawIngredient, availableProducts) {
|
||||
const apiKey = process.env.MISTRAL_API_KEY;
|
||||
if (!apiKey || availableProducts.length === 0)
|
||||
return [];
|
||||
const productList = availableProducts
|
||||
.map((p) => `[${p.id}] ${p.canonicalName || p.name}`)
|
||||
.join('\n');
|
||||
const systemPrompt = `Du föreslår ersättningsvaror för en ingrediens.
|
||||
Svara ENDAST med JSON: {"substitutions":[{"productId":123,"reason":"...","confidence":"high|medium|low"}]}
|
||||
Regler:
|
||||
1. Välj max 3 ersättningar.
|
||||
2. Om inget passar, returnera tom lista.`;
|
||||
const userPrompt = `Ingrediens: "${rawIngredient}"\nTillgängliga produkter:\n${productList}`;
|
||||
try {
|
||||
const response = await fetch(MISTRAL_API_URL, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${apiKey}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: MODEL,
|
||||
messages: [
|
||||
{ role: 'system', content: systemPrompt },
|
||||
{ role: 'user', content: userPrompt },
|
||||
],
|
||||
max_tokens: 300,
|
||||
temperature: 0.2,
|
||||
response_format: { type: 'json_object' },
|
||||
}),
|
||||
});
|
||||
if (!response.ok) {
|
||||
this.logger.warn(`suggestSubstitutions API-fel: ${response.status}`);
|
||||
return [];
|
||||
}
|
||||
const data = (await response.json());
|
||||
const raw = data.choices?.[0]?.message?.content ?? '{}';
|
||||
const parsed = JSON.parse(raw);
|
||||
return Array.isArray(parsed.substitutions) ? parsed.substitutions.slice(0, 3) : [];
|
||||
}
|
||||
catch (err) {
|
||||
this.logger.warn(`suggestSubstitutions misslyckades: ${String(err)}`);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
async suggestCategory(productName, categories) {
|
||||
const apiKey = process.env.MISTRAL_API_KEY;
|
||||
if (!apiKey) {
|
||||
throw new common_1.ServiceUnavailableException('MISTRAL_API_KEY är inte konfigurerad i miljövariabler');
|
||||
}
|
||||
const categoryList = categories
|
||||
.map((c) => `[${c.id}] ${c.path}`)
|
||||
.join('\n');
|
||||
const systemPrompt = `Du är ett kategoriseringssystem för en livsmedelsapp. Din uppgift är att hitta den mest lämpliga kategorin för en produkt.
|
||||
|
||||
Tillgängliga kategorier (format: [id] Sökväg):
|
||||
${categoryList}
|
||||
|
||||
Regler:
|
||||
1. Välj den mest specifika underkategorin som passar produkten.
|
||||
2. Om ingen specifik kategori passar, välj en underkategori under "Övrigt" om möjligt.
|
||||
3. Om ingen underkategori under "Övrigt" passar, välj "Övrigt" (den kategori vars sökväg är exakt "Övrigt").
|
||||
4. Du MÅSTE alltid returnera ett svar — aldrig null eller tomt.
|
||||
5. Svara ENDAST med giltig JSON i detta format: { "categoryId": <nummer>, "confidence": "high" | "medium" | "low" }
|
||||
- "high": uppenbart matchande kategori
|
||||
- "medium": trolig matchning
|
||||
- "low": osäker, används fallback (Övrigt eller underkategori till Övrigt)`;
|
||||
const userPrompt = `Produkt: "${productName}"`;
|
||||
let raw = '';
|
||||
const MAX_RETRIES = 3;
|
||||
for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
|
||||
try {
|
||||
const response = await fetch(MISTRAL_API_URL, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${apiKey}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: MODEL,
|
||||
messages: [
|
||||
{ role: 'system', content: systemPrompt },
|
||||
{ role: 'user', content: userPrompt },
|
||||
],
|
||||
max_tokens: 100,
|
||||
temperature: 0.1,
|
||||
response_format: { type: 'json_object' },
|
||||
}),
|
||||
});
|
||||
if (response.status === 503 || response.status === 429) {
|
||||
const err = await response.text();
|
||||
this.logger.warn(`Mistral API ${response.status} (försök ${attempt}/${MAX_RETRIES}): ${err}`);
|
||||
if (attempt < MAX_RETRIES) {
|
||||
await new Promise((r) => setTimeout(r, attempt * 1500));
|
||||
continue;
|
||||
}
|
||||
throw new common_1.ServiceUnavailableException('AI-tjänsten är tillfälligt otillgänglig, försök igen');
|
||||
}
|
||||
if (!response.ok) {
|
||||
const err = await response.text();
|
||||
this.logger.error(`Mistral API-fel: ${response.status} ${err}`);
|
||||
throw new common_1.ServiceUnavailableException('AI-tjänsten svarade inte korrekt');
|
||||
}
|
||||
const data = await response.json();
|
||||
raw = data.choices?.[0]?.message?.content ?? '';
|
||||
break;
|
||||
}
|
||||
catch (err) {
|
||||
if (err instanceof common_1.ServiceUnavailableException)
|
||||
throw err;
|
||||
this.logger.error(`Mistral fetch-fel (försök ${attempt}/${MAX_RETRIES}): ${String(err)}`);
|
||||
if (attempt < MAX_RETRIES) {
|
||||
await new Promise((r) => setTimeout(r, attempt * 1500));
|
||||
continue;
|
||||
}
|
||||
throw new common_1.ServiceUnavailableException('Kunde inte nå AI-tjänsten');
|
||||
}
|
||||
}
|
||||
let parsed;
|
||||
try {
|
||||
parsed = JSON.parse(raw);
|
||||
}
|
||||
catch {
|
||||
this.logger.warn(`AI returnerade ogiltig JSON: ${raw}`);
|
||||
return this.fallbackToOvrigt(categories);
|
||||
}
|
||||
const validId = typeof parsed.categoryId === 'number';
|
||||
const matchedCategory = validId ? categories.find((c) => c.id === parsed.categoryId) : null;
|
||||
if (!matchedCategory) {
|
||||
this.logger.warn(`AI returnerade okänt categoryId ${parsed.categoryId}, använder fallback`);
|
||||
return this.fallbackToOvrigt(categories);
|
||||
}
|
||||
const confidence = ['high', 'medium', 'low'].includes(parsed.confidence)
|
||||
? parsed.confidence
|
||||
: 'medium';
|
||||
if (confidence === 'low') {
|
||||
const l1Name = matchedCategory.path.split(' > ')[0];
|
||||
const l1 = categories.find((c) => c.path === l1Name);
|
||||
if (l1 && l1.id !== matchedCategory.id) {
|
||||
this.logger.log(`AI-guardrail: ${confidence} konfidenspoäng → remappar "${matchedCategory.path}" → L1 "${l1.path}"`);
|
||||
return {
|
||||
categoryId: l1.id,
|
||||
categoryName: l1.name,
|
||||
path: l1.path,
|
||||
confidence,
|
||||
usedFallback: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
return {
|
||||
categoryId: matchedCategory.id,
|
||||
categoryName: matchedCategory.name,
|
||||
path: matchedCategory.path,
|
||||
confidence,
|
||||
usedFallback: confidence === 'low',
|
||||
};
|
||||
}
|
||||
fallbackToOvrigt(categories) {
|
||||
const ovrigt = categories.find((c) => c.path === 'Övrigt');
|
||||
if (!ovrigt) {
|
||||
const first = categories[0];
|
||||
return { categoryId: first.id, categoryName: first.name, path: first.path, confidence: 'low', usedFallback: true };
|
||||
}
|
||||
return {
|
||||
categoryId: ovrigt.id,
|
||||
categoryName: ovrigt.name,
|
||||
path: ovrigt.path,
|
||||
confidence: 'low',
|
||||
usedFallback: true,
|
||||
};
|
||||
}
|
||||
};
|
||||
exports.AiService = AiService;
|
||||
exports.AiService = AiService = AiService_1 = __decorate([
|
||||
(0, common_1.Injectable)()
|
||||
], AiService);
|
||||
//# sourceMappingURL=ai.service.js.map
|
||||
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
-2
@@ -1,2 +0,0 @@
|
||||
export declare class AppModule {
|
||||
}
|
||||
Vendored
-75
@@ -1,75 +0,0 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AppModule = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const core_1 = require("@nestjs/core");
|
||||
const throttler_1 = require("@nestjs/throttler");
|
||||
const health_module_1 = require("./health/health.module");
|
||||
const prisma_module_1 = require("./prisma/prisma.module");
|
||||
const products_module_1 = require("./products/products.module");
|
||||
const inventory_module_1 = require("./inventory/inventory.module");
|
||||
const recipes_module_1 = require("./recipes/recipes.module");
|
||||
const quick_import_module_1 = require("./quick-import/quick-import.module");
|
||||
const pantry_module_1 = require("./pantry/pantry.module");
|
||||
const meal_plan_module_1 = require("./meal-plan/meal-plan.module");
|
||||
const receipt_import_module_1 = require("./receipt-import/receipt-import.module");
|
||||
const receipt_alias_module_1 = require("./receipt-alias/receipt-alias.module");
|
||||
const auth_module_1 = require("./auth/auth.module");
|
||||
const users_module_1 = require("./users/users.module");
|
||||
const user_products_module_1 = require("./user-products/user-products.module");
|
||||
const categories_module_1 = require("./categories/categories.module");
|
||||
const ai_module_1 = require("./ai/ai.module");
|
||||
const jwt_auth_guard_1 = require("./auth/jwt-auth.guard");
|
||||
const roles_guard_1 = require("./auth/roles.guard");
|
||||
let AppModule = class AppModule {
|
||||
};
|
||||
exports.AppModule = AppModule;
|
||||
exports.AppModule = AppModule = __decorate([
|
||||
(0, common_1.Module)({
|
||||
imports: [
|
||||
throttler_1.ThrottlerModule.forRoot([
|
||||
{
|
||||
name: 'default',
|
||||
ttl: 60_000,
|
||||
limit: 120,
|
||||
},
|
||||
]),
|
||||
health_module_1.HealthModule,
|
||||
prisma_module_1.PrismaModule,
|
||||
products_module_1.ProductsModule,
|
||||
inventory_module_1.InventoryModule,
|
||||
recipes_module_1.RecipesModule,
|
||||
quick_import_module_1.QuickImportModule,
|
||||
pantry_module_1.PantryModule,
|
||||
meal_plan_module_1.MealPlanModule,
|
||||
receipt_import_module_1.ReceiptImportModule,
|
||||
receipt_alias_module_1.ReceiptAliasModule,
|
||||
auth_module_1.AuthModule,
|
||||
users_module_1.UsersModule,
|
||||
user_products_module_1.UserProductsModule,
|
||||
categories_module_1.CategoriesModule,
|
||||
ai_module_1.AiModule,
|
||||
],
|
||||
providers: [
|
||||
{
|
||||
provide: core_1.APP_GUARD,
|
||||
useClass: throttler_1.ThrottlerGuard,
|
||||
},
|
||||
{
|
||||
provide: core_1.APP_GUARD,
|
||||
useClass: jwt_auth_guard_1.JwtAuthGuard,
|
||||
},
|
||||
{
|
||||
provide: core_1.APP_GUARD,
|
||||
useClass: roles_guard_1.RolesGuard,
|
||||
},
|
||||
],
|
||||
})
|
||||
], AppModule);
|
||||
//# sourceMappingURL=app.module.js.map
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"app.module.js","sourceRoot":"","sources":["../src/app.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,uCAAyC;AACzC,iDAAoE;AACpE,0DAAsD;AACtD,0DAAsD;AACtD,gEAA4D;AAC5D,mEAA+D;AAC/D,6DAAyD;AACzD,4EAAuE;AACvE,0DAAsD;AACtD,mEAA8D;AAC9D,kFAA6E;AAC7E,+EAA0E;AAC1E,oDAAgD;AAChD,uDAAmD;AACnD,+EAA0E;AAC1E,sEAAkE;AAClE,8CAA0C;AAC1C,0DAAqD;AACrD,oDAAgD;AA2CzC,IAAM,SAAS,GAAf,MAAM,SAAS;CAAG,CAAA;AAAZ,8BAAS;oBAAT,SAAS;IAxCrB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,2BAAe,CAAC,OAAO,CAAC;gBACtB;oBACE,IAAI,EAAE,SAAS;oBACf,GAAG,EAAE,MAAM;oBACX,KAAK,EAAE,GAAG;iBACX;aACF,CAAC;YACF,4BAAY;YACZ,4BAAY;YACZ,gCAAc;YACd,kCAAe;YACf,8BAAa;YACb,uCAAiB;YACjB,4BAAY;YACZ,iCAAc;YACd,2CAAmB;YACnB,yCAAkB;YAClB,wBAAU;YACV,0BAAW;YACX,yCAAkB;YAClB,oCAAgB;YAChB,oBAAQ;SACT;QACD,SAAS,EAAE;YACT;gBACE,OAAO,EAAE,gBAAS;gBAClB,QAAQ,EAAE,0BAAc;aACzB;YACD;gBACE,OAAO,EAAE,gBAAS;gBAClB,QAAQ,EAAE,6BAAY;aACvB;YACD;gBACE,OAAO,EAAE,gBAAS;gBAClB,QAAQ,EAAE,wBAAU;aACrB;SACF;KACF,CAAC;GACW,SAAS,CAAG"}
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
import { AuthService } from './auth.service';
|
||||
import { RegisterDto } from './dto/register.dto';
|
||||
import { LoginDto } from './dto/login.dto';
|
||||
export declare class AuthController {
|
||||
private readonly authService;
|
||||
constructor(authService: AuthService);
|
||||
register(dto: RegisterDto): Promise<{
|
||||
accessToken: string;
|
||||
userId: number;
|
||||
username: string;
|
||||
role: string;
|
||||
isPremium: boolean;
|
||||
}>;
|
||||
login(dto: LoginDto): Promise<{
|
||||
accessToken: string;
|
||||
userId: number;
|
||||
username: string;
|
||||
role: string;
|
||||
isPremium: boolean;
|
||||
}>;
|
||||
}
|
||||
Vendored
-57
@@ -1,57 +0,0 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
return function (target, key) { decorator(target, key, paramIndex); }
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AuthController = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const throttler_1 = require("@nestjs/throttler");
|
||||
const auth_service_1 = require("./auth.service");
|
||||
const register_dto_1 = require("./dto/register.dto");
|
||||
const login_dto_1 = require("./dto/login.dto");
|
||||
const public_decorator_1 = require("./decorators/public.decorator");
|
||||
let AuthController = class AuthController {
|
||||
constructor(authService) {
|
||||
this.authService = authService;
|
||||
}
|
||||
register(dto) {
|
||||
return this.authService.register(dto);
|
||||
}
|
||||
login(dto) {
|
||||
return this.authService.login(dto);
|
||||
}
|
||||
};
|
||||
exports.AuthController = AuthController;
|
||||
__decorate([
|
||||
(0, public_decorator_1.Public)(),
|
||||
(0, throttler_1.Throttle)({ default: { ttl: 60_000, limit: 10 } }),
|
||||
(0, common_1.Post)('register'),
|
||||
__param(0, (0, common_1.Body)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [register_dto_1.RegisterDto]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], AuthController.prototype, "register", null);
|
||||
__decorate([
|
||||
(0, public_decorator_1.Public)(),
|
||||
(0, throttler_1.Throttle)({ default: { ttl: 60_000, limit: 10 } }),
|
||||
(0, common_1.HttpCode)(common_1.HttpStatus.OK),
|
||||
(0, common_1.Post)('login'),
|
||||
__param(0, (0, common_1.Body)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [login_dto_1.LoginDto]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], AuthController.prototype, "login", null);
|
||||
exports.AuthController = AuthController = __decorate([
|
||||
(0, common_1.Controller)('auth'),
|
||||
__metadata("design:paramtypes", [auth_service_1.AuthService])
|
||||
], AuthController);
|
||||
//# sourceMappingURL=auth.controller.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"auth.controller.js","sourceRoot":"","sources":["../../src/auth/auth.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAA8E;AAC9E,iDAA6C;AAC7C,iDAA6C;AAC7C,qDAAiD;AACjD,+CAA2C;AAC3C,oEAAuD;AAGhD,IAAM,cAAc,GAApB,MAAM,cAAc;IACzB,YAA6B,WAAwB;QAAxB,gBAAW,GAAX,WAAW,CAAa;IAAG,CAAC;IAKzD,QAAQ,CAAS,GAAgB;QAC/B,OAAO,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACxC,CAAC;IAMD,KAAK,CAAS,GAAa;QACzB,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACrC,CAAC;CACF,CAAA;AAjBY,wCAAc;AAMzB;IAHC,IAAA,yBAAM,GAAE;IACR,IAAA,oBAAQ,EAAC,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC;IACjD,IAAA,aAAI,EAAC,UAAU,CAAC;IACP,WAAA,IAAA,aAAI,GAAE,CAAA;;qCAAM,0BAAW;;8CAEhC;AAMD;IAJC,IAAA,yBAAM,GAAE;IACR,IAAA,oBAAQ,EAAC,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC;IACjD,IAAA,iBAAQ,EAAC,mBAAU,CAAC,EAAE,CAAC;IACvB,IAAA,aAAI,EAAC,OAAO,CAAC;IACP,WAAA,IAAA,aAAI,GAAE,CAAA;;qCAAM,oBAAQ;;2CAE1B;yBAhBU,cAAc;IAD1B,IAAA,mBAAU,EAAC,MAAM,CAAC;qCAEyB,0BAAW;GAD1C,cAAc,CAiB1B"}
|
||||
Vendored
-2
@@ -1,2 +0,0 @@
|
||||
export declare class AuthModule {
|
||||
}
|
||||
Vendored
-40
@@ -1,40 +0,0 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AuthModule = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const jwt_1 = require("@nestjs/jwt");
|
||||
const passport_1 = require("@nestjs/passport");
|
||||
const auth_controller_1 = require("./auth.controller");
|
||||
const auth_service_1 = require("./auth.service");
|
||||
const jwt_strategy_1 = require("./jwt.strategy");
|
||||
const users_module_1 = require("../users/users.module");
|
||||
let AuthModule = class AuthModule {
|
||||
};
|
||||
exports.AuthModule = AuthModule;
|
||||
exports.AuthModule = AuthModule = __decorate([
|
||||
(0, common_1.Module)({
|
||||
imports: [
|
||||
users_module_1.UsersModule,
|
||||
passport_1.PassportModule,
|
||||
jwt_1.JwtModule.register({
|
||||
secret: (() => {
|
||||
const secret = process.env.JWT_SECRET;
|
||||
if (!secret)
|
||||
throw new Error('JWT_SECRET saknas i miljövariabler');
|
||||
return secret;
|
||||
})(),
|
||||
signOptions: { expiresIn: '7d' },
|
||||
}),
|
||||
],
|
||||
controllers: [auth_controller_1.AuthController],
|
||||
providers: [auth_service_1.AuthService, jwt_strategy_1.JwtStrategy],
|
||||
exports: [auth_service_1.AuthService],
|
||||
})
|
||||
], AuthModule);
|
||||
//# sourceMappingURL=auth.module.js.map
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"auth.module.js","sourceRoot":"","sources":["../../src/auth/auth.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,qCAAwC;AACxC,+CAAkD;AAClD,uDAAmD;AACnD,iDAA6C;AAC7C,iDAA6C;AAC7C,wDAAoD;AAmB7C,IAAM,UAAU,GAAhB,MAAM,UAAU;CAAG,CAAA;AAAb,gCAAU;qBAAV,UAAU;IAjBtB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,0BAAW;YACX,yBAAc;YACd,eAAS,CAAC,QAAQ,CAAC;gBACjB,MAAM,EAAE,CAAC,GAAG,EAAE;oBACZ,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;oBACtC,IAAI,CAAC,MAAM;wBAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;oBACnE,OAAO,MAAM,CAAC;gBAChB,CAAC,CAAC,EAAE;gBACJ,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE;aACjC,CAAC;SACH;QACD,WAAW,EAAE,CAAC,gCAAc,CAAC;QAC7B,SAAS,EAAE,CAAC,0BAAW,EAAE,0BAAW,CAAC;QACrC,OAAO,EAAE,CAAC,0BAAW,CAAC;KACvB,CAAC;GACW,UAAU,CAAG"}
|
||||
Vendored
-24
@@ -1,24 +0,0 @@
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
import { UsersService } from '../users/users.service';
|
||||
import { RegisterDto } from './dto/register.dto';
|
||||
import { LoginDto } from './dto/login.dto';
|
||||
export declare class AuthService {
|
||||
private readonly usersService;
|
||||
private readonly jwtService;
|
||||
constructor(usersService: UsersService, jwtService: JwtService);
|
||||
register(dto: RegisterDto): Promise<{
|
||||
accessToken: string;
|
||||
userId: number;
|
||||
username: string;
|
||||
role: string;
|
||||
isPremium: boolean;
|
||||
}>;
|
||||
login(dto: LoginDto): Promise<{
|
||||
accessToken: string;
|
||||
userId: number;
|
||||
username: string;
|
||||
role: string;
|
||||
isPremium: boolean;
|
||||
}>;
|
||||
private issueToken;
|
||||
}
|
||||
Vendored
-60
@@ -1,60 +0,0 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AuthService = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const jwt_1 = require("@nestjs/jwt");
|
||||
const bcrypt = require("bcryptjs");
|
||||
const users_service_1 = require("../users/users.service");
|
||||
let AuthService = class AuthService {
|
||||
constructor(usersService, jwtService) {
|
||||
this.usersService = usersService;
|
||||
this.jwtService = jwtService;
|
||||
}
|
||||
async register(dto) {
|
||||
const existing = await this.usersService.findByUsername(dto.username);
|
||||
if (existing)
|
||||
throw new common_1.ConflictException('Användarnamnet är redan taget');
|
||||
const passwordHash = await bcrypt.hash(dto.password, 12);
|
||||
const user = await this.usersService.create({
|
||||
username: dto.username,
|
||||
email: dto.email,
|
||||
passwordHash,
|
||||
});
|
||||
return this.issueToken(user.id, user.username, user.role, user.isPremium);
|
||||
}
|
||||
async login(dto) {
|
||||
const user = await this.usersService.findByUsername(dto.username);
|
||||
if (!user)
|
||||
throw new common_1.UnauthorizedException('Felaktigt användarnamn eller lösenord');
|
||||
const valid = await bcrypt.compare(dto.password, user.passwordHash);
|
||||
if (!valid)
|
||||
throw new common_1.UnauthorizedException('Felaktigt användarnamn eller lösenord');
|
||||
return this.issueToken(user.id, user.username, user.role, user.isPremium);
|
||||
}
|
||||
issueToken(userId, username, role, isPremium) {
|
||||
const payload = { sub: userId, username, role, isPremium };
|
||||
return {
|
||||
accessToken: this.jwtService.sign(payload),
|
||||
userId,
|
||||
username,
|
||||
role,
|
||||
isPremium,
|
||||
};
|
||||
}
|
||||
};
|
||||
exports.AuthService = AuthService;
|
||||
exports.AuthService = AuthService = __decorate([
|
||||
(0, common_1.Injectable)(),
|
||||
__metadata("design:paramtypes", [users_service_1.UsersService,
|
||||
jwt_1.JwtService])
|
||||
], AuthService);
|
||||
//# sourceMappingURL=auth.service.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"auth.service.js","sourceRoot":"","sources":["../../src/auth/auth.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAIwB;AACxB,qCAAyC;AACzC,mCAAmC;AACnC,0DAAsD;AAK/C,IAAM,WAAW,GAAjB,MAAM,WAAW;IACtB,YACmB,YAA0B,EAC1B,UAAsB;QADtB,iBAAY,GAAZ,YAAY,CAAc;QAC1B,eAAU,GAAV,UAAU,CAAY;IACtC,CAAC;IAEJ,KAAK,CAAC,QAAQ,CAAC,GAAgB;QAC7B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACtE,IAAI,QAAQ;YAAE,MAAM,IAAI,0BAAiB,CAAC,+BAA+B,CAAC,CAAC;QAE3E,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACzD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC;YAC1C,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,YAAY;SACb,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAC5E,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,GAAa;QACvB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAClE,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,8BAAqB,CAAC,uCAAuC,CAAC,CAAC;QAEpF,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QACpE,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,8BAAqB,CAAC,uCAAuC,CAAC,CAAC;QAErF,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAC5E,CAAC;IAEO,UAAU,CAAC,MAAc,EAAE,QAAgB,EAAE,IAAY,EAAE,SAAkB;QACnF,MAAM,OAAO,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC3D,OAAO;YACL,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC;YAC1C,MAAM;YACN,QAAQ;YACR,IAAI;YACJ,SAAS;SACV,CAAC;IACJ,CAAC;CACF,CAAA;AAxCY,kCAAW;sBAAX,WAAW;IADvB,IAAA,mBAAU,GAAE;qCAGsB,4BAAY;QACd,gBAAU;GAH9B,WAAW,CAwCvB"}
|
||||
@@ -1 +0,0 @@
|
||||
export declare const CurrentUser: (...dataOrPipes: unknown[]) => ParameterDecorator;
|
||||
@@ -1,9 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CurrentUser = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
exports.CurrentUser = (0, common_1.createParamDecorator)((_data, ctx) => {
|
||||
const request = ctx.switchToHttp().getRequest();
|
||||
return request.user;
|
||||
});
|
||||
//# sourceMappingURL=current-user.decorator.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"current-user.decorator.js","sourceRoot":"","sources":["../../../src/auth/decorators/current-user.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAAwE;AAE3D,QAAA,WAAW,GAAG,IAAA,6BAAoB,EAC7C,CAAC,KAAc,EAAE,GAAqB,EAAE,EAAE;IACxC,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;IAChD,OAAO,OAAO,CAAC,IAA4C,CAAC;AAC9D,CAAC,CACF,CAAC"}
|
||||
@@ -1,2 +0,0 @@
|
||||
export declare const IS_PUBLIC_KEY = "isPublic";
|
||||
export declare const Public: () => import("@nestjs/common").CustomDecorator<string>;
|
||||
@@ -1,8 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Public = exports.IS_PUBLIC_KEY = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
exports.IS_PUBLIC_KEY = 'isPublic';
|
||||
const Public = () => (0, common_1.SetMetadata)(exports.IS_PUBLIC_KEY, true);
|
||||
exports.Public = Public;
|
||||
//# sourceMappingURL=public.decorator.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"public.decorator.js","sourceRoot":"","sources":["../../../src/auth/decorators/public.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA6C;AAEhC,QAAA,aAAa,GAAG,UAAU,CAAC;AACjC,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,IAAA,oBAAW,EAAC,qBAAa,EAAE,IAAI,CAAC,CAAC;AAAhD,QAAA,MAAM,UAA0C"}
|
||||
@@ -1,2 +0,0 @@
|
||||
export declare const ROLES_KEY = "roles";
|
||||
export declare const Roles: (...roles: string[]) => import("@nestjs/common").CustomDecorator<string>;
|
||||
@@ -1,8 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Roles = exports.ROLES_KEY = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
exports.ROLES_KEY = 'roles';
|
||||
const Roles = (...roles) => (0, common_1.SetMetadata)(exports.ROLES_KEY, roles);
|
||||
exports.Roles = Roles;
|
||||
//# sourceMappingURL=roles.decorator.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"roles.decorator.js","sourceRoot":"","sources":["../../../src/auth/decorators/roles.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA6C;AAEhC,QAAA,SAAS,GAAG,OAAO,CAAC;AAC1B,MAAM,KAAK,GAAG,CAAC,GAAG,KAAe,EAAE,EAAE,CAAC,IAAA,oBAAW,EAAC,iBAAS,EAAE,KAAK,CAAC,CAAC;AAA9D,QAAA,KAAK,SAAyD"}
|
||||
Vendored
-4
@@ -1,4 +0,0 @@
|
||||
export declare class LoginDto {
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
Vendored
-25
@@ -1,25 +0,0 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.LoginDto = void 0;
|
||||
const class_validator_1 = require("class-validator");
|
||||
class LoginDto {
|
||||
}
|
||||
exports.LoginDto = LoginDto;
|
||||
__decorate([
|
||||
(0, class_validator_1.IsString)(),
|
||||
__metadata("design:type", String)
|
||||
], LoginDto.prototype, "username", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsString)(),
|
||||
__metadata("design:type", String)
|
||||
], LoginDto.prototype, "password", void 0);
|
||||
//# sourceMappingURL=login.dto.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"login.dto.js","sourceRoot":"","sources":["../../../src/auth/dto/login.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAA2C;AAE3C,MAAa,QAAQ;CAMpB;AAND,4BAMC;AAJC;IADC,IAAA,0BAAQ,GAAE;;0CACM;AAGjB;IADC,IAAA,0BAAQ,GAAE;;0CACM"}
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
export declare class RegisterDto {
|
||||
username: string;
|
||||
email: string;
|
||||
password: string;
|
||||
}
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.RegisterDto = void 0;
|
||||
const class_validator_1 = require("class-validator");
|
||||
class RegisterDto {
|
||||
}
|
||||
exports.RegisterDto = RegisterDto;
|
||||
__decorate([
|
||||
(0, class_validator_1.IsString)(),
|
||||
__metadata("design:type", String)
|
||||
], RegisterDto.prototype, "username", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsEmail)(),
|
||||
__metadata("design:type", String)
|
||||
], RegisterDto.prototype, "email", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsString)(),
|
||||
(0, class_validator_1.MinLength)(8),
|
||||
__metadata("design:type", String)
|
||||
], RegisterDto.prototype, "password", void 0);
|
||||
//# sourceMappingURL=register.dto.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"register.dto.js","sourceRoot":"","sources":["../../../src/auth/dto/register.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAA+D;AAE/D,MAAa,WAAW;CAUvB;AAVD,kCAUC;AARC;IADC,IAAA,0BAAQ,GAAE;;6CACM;AAGjB;IADC,IAAA,yBAAO,GAAE;;0CACI;AAId;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,2BAAS,EAAC,CAAC,CAAC;;6CACI"}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
import { ExecutionContext } from '@nestjs/common';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Reflector } from '@nestjs/core';
|
||||
declare const JwtAuthGuard_base: import("@nestjs/passport").Type<import("@nestjs/passport").IAuthGuard>;
|
||||
export declare class JwtAuthGuard extends JwtAuthGuard_base {
|
||||
private reflector;
|
||||
private readonly logger;
|
||||
constructor(reflector: Reflector);
|
||||
canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean>;
|
||||
handleRequest<TUser = any>(err: any, user: TUser, info: any): TUser;
|
||||
}
|
||||
export {};
|
||||
Vendored
-48
@@ -1,48 +0,0 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
var JwtAuthGuard_1;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.JwtAuthGuard = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const core_1 = require("@nestjs/core");
|
||||
const passport_1 = require("@nestjs/passport");
|
||||
const public_decorator_1 = require("./decorators/public.decorator");
|
||||
let JwtAuthGuard = JwtAuthGuard_1 = class JwtAuthGuard extends (0, passport_1.AuthGuard)('jwt') {
|
||||
constructor(reflector) {
|
||||
super();
|
||||
this.reflector = reflector;
|
||||
this.logger = new common_1.Logger(JwtAuthGuard_1.name);
|
||||
}
|
||||
canActivate(context) {
|
||||
const isPublic = this.reflector.getAllAndOverride(public_decorator_1.IS_PUBLIC_KEY, [
|
||||
context.getHandler(),
|
||||
context.getClass(),
|
||||
]);
|
||||
if (isPublic)
|
||||
return true;
|
||||
return super.canActivate(context);
|
||||
}
|
||||
handleRequest(err, user, info) {
|
||||
if (err || !user) {
|
||||
throw err || new common_1.UnauthorizedException();
|
||||
}
|
||||
if (user) {
|
||||
this.logger.log(`Authenticated user ID: ${user.userId}`);
|
||||
}
|
||||
return user;
|
||||
}
|
||||
};
|
||||
exports.JwtAuthGuard = JwtAuthGuard;
|
||||
exports.JwtAuthGuard = JwtAuthGuard = JwtAuthGuard_1 = __decorate([
|
||||
(0, common_1.Injectable)(),
|
||||
__metadata("design:paramtypes", [core_1.Reflector])
|
||||
], JwtAuthGuard);
|
||||
//# sourceMappingURL=jwt-auth.guard.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"jwt-auth.guard.js","sourceRoot":"","sources":["../../src/auth/jwt-auth.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,2CAA0G;AAE1G,uCAAyC;AACzC,+CAA6C;AAC7C,oEAA8D;AAGvD,IAAM,YAAY,oBAAlB,MAAM,YAAa,SAAQ,IAAA,oBAAS,EAAC,KAAK,CAAC;IAGhD,YAAoB,SAAoB;QACtC,KAAK,EAAE,CAAC;QADU,cAAS,GAAT,SAAS,CAAW;QAFvB,WAAM,GAAG,IAAI,eAAM,CAAC,cAAY,CAAC,IAAI,CAAC,CAAC;IAIxD,CAAC;IAED,WAAW,CAAC,OAAyB;QACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAU,gCAAa,EAAE;YACxE,OAAO,CAAC,UAAU,EAAE;YACpB,OAAO,CAAC,QAAQ,EAAE;SACnB,CAAC,CAAC;QACH,IAAI,QAAQ;YAAE,OAAO,IAAI,CAAC;QAC1B,OAAO,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;IAGD,aAAa,CAAc,GAAQ,EAAE,IAAW,EAAE,IAAS;QACzD,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YACjB,MAAM,GAAG,IAAI,IAAI,8BAAqB,EAAE,CAAC;QAC3C,CAAC;QACD,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,0BAA2B,IAAY,CAAC,MAAM,EAAE,CAAC,CAAC;QACpE,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AA1BY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,mBAAU,GAAE;qCAIoB,gBAAS;GAH7B,YAAY,CA0BxB"}
|
||||
Vendored
-21
@@ -1,21 +0,0 @@
|
||||
import { Strategy } from 'passport-jwt';
|
||||
declare const JwtStrategy_base: new (...args: any[]) => Strategy;
|
||||
export declare class JwtStrategy extends JwtStrategy_base {
|
||||
private readonly logger;
|
||||
constructor();
|
||||
validate(payload: {
|
||||
sub?: number;
|
||||
id?: number;
|
||||
userId?: number;
|
||||
username?: string;
|
||||
role?: string;
|
||||
isPremium?: boolean;
|
||||
}): Promise<{
|
||||
id: number | undefined;
|
||||
userId: number | undefined;
|
||||
username: string | undefined;
|
||||
role: string;
|
||||
isPremium: boolean;
|
||||
}>;
|
||||
}
|
||||
export {};
|
||||
Vendored
-43
@@ -1,43 +0,0 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
var JwtStrategy_1;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.JwtStrategy = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const passport_1 = require("@nestjs/passport");
|
||||
const passport_jwt_1 = require("passport-jwt");
|
||||
let JwtStrategy = JwtStrategy_1 = class JwtStrategy extends (0, passport_1.PassportStrategy)(passport_jwt_1.Strategy) {
|
||||
constructor() {
|
||||
super({
|
||||
jwtFromRequest: passport_jwt_1.ExtractJwt.fromAuthHeaderAsBearerToken(),
|
||||
ignoreExpiration: false,
|
||||
secretOrKey: process.env.JWT_SECRET,
|
||||
});
|
||||
this.logger = new common_1.Logger(JwtStrategy_1.name);
|
||||
}
|
||||
async validate(payload) {
|
||||
const resolvedUserId = payload.sub ?? payload.id ?? payload.userId;
|
||||
this.logger.log(`Validating token for user ID: ${resolvedUserId}, Username: ${payload.username}`);
|
||||
return {
|
||||
id: resolvedUserId,
|
||||
userId: resolvedUserId,
|
||||
username: payload.username,
|
||||
role: payload.role ?? 'user',
|
||||
isPremium: payload.isPremium ?? false,
|
||||
};
|
||||
}
|
||||
};
|
||||
exports.JwtStrategy = JwtStrategy;
|
||||
exports.JwtStrategy = JwtStrategy = JwtStrategy_1 = __decorate([
|
||||
(0, common_1.Injectable)(),
|
||||
__metadata("design:paramtypes", [])
|
||||
], JwtStrategy);
|
||||
//# sourceMappingURL=jwt.strategy.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"jwt.strategy.js","sourceRoot":"","sources":["../../src/auth/jwt.strategy.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,2CAAoD;AACpD,+CAAoD;AACpD,+CAAoD;AAG7C,IAAM,WAAW,mBAAjB,MAAM,WAAY,SAAQ,IAAA,2BAAgB,EAAC,uBAAQ,CAAC;IAGzD;QACE,KAAK,CAAC;YACJ,cAAc,EAAE,yBAAU,CAAC,2BAA2B,EAAE;YACxD,gBAAgB,EAAE,KAAK;YACvB,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU;SACpC,CAAC,CAAC;QAPY,WAAM,GAAG,IAAI,eAAM,CAAC,aAAW,CAAC,IAAI,CAAC,CAAC;IAQvD,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,OAA8G;QAC3H,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,EAAE,IAAI,OAAO,CAAC,MAAM,CAAC;QACnE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,iCAAiC,cAAc,eAAe,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;QAClG,OAAO;YACL,EAAE,EAAE,cAAc;YAClB,MAAM,EAAE,cAAc;YACtB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,MAAM;YAC5B,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,KAAK;SACtC,CAAC;IACJ,CAAC;CACF,CAAA;AAtBY,kCAAW;sBAAX,WAAW;IADvB,IAAA,mBAAU,GAAE;;GACA,WAAW,CAsBvB"}
|
||||
@@ -1,4 +0,0 @@
|
||||
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
||||
export declare class PremiumOrAdminGuard implements CanActivate {
|
||||
canActivate(context: ExecutionContext): boolean;
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.PremiumOrAdminGuard = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
let PremiumOrAdminGuard = class PremiumOrAdminGuard {
|
||||
canActivate(context) {
|
||||
const { user } = context.switchToHttp().getRequest();
|
||||
if (user?.role === 'admin' || user?.isPremium === true) {
|
||||
return true;
|
||||
}
|
||||
throw new common_1.ForbiddenException('Denna funktion kräver premiumkonto eller admin-behörighet.');
|
||||
}
|
||||
};
|
||||
exports.PremiumOrAdminGuard = PremiumOrAdminGuard;
|
||||
exports.PremiumOrAdminGuard = PremiumOrAdminGuard = __decorate([
|
||||
(0, common_1.Injectable)()
|
||||
], PremiumOrAdminGuard);
|
||||
//# sourceMappingURL=premium-or-admin.guard.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"premium-or-admin.guard.js","sourceRoot":"","sources":["../../src/auth/premium-or-admin.guard.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA+F;AAOxF,IAAM,mBAAmB,GAAzB,MAAM,mBAAmB;IAC9B,WAAW,CAAC,OAAyB;QACnC,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;QAErD,IAAI,IAAI,EAAE,IAAI,KAAK,OAAO,IAAI,IAAI,EAAE,SAAS,KAAK,IAAI,EAAE,CAAC;YACvD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,IAAI,2BAAkB,CAAC,4DAA4D,CAAC,CAAC;IAC7F,CAAC;CACF,CAAA;AAVY,kDAAmB;8BAAnB,mBAAmB;IAD/B,IAAA,mBAAU,GAAE;GACA,mBAAmB,CAU/B"}
|
||||
Vendored
-7
@@ -1,7 +0,0 @@
|
||||
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
||||
import { Reflector } from '@nestjs/core';
|
||||
export declare class RolesGuard implements CanActivate {
|
||||
private reflector;
|
||||
constructor(reflector: Reflector);
|
||||
canActivate(context: ExecutionContext): boolean;
|
||||
}
|
||||
Vendored
-39
@@ -1,39 +0,0 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.RolesGuard = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const core_1 = require("@nestjs/core");
|
||||
const roles_decorator_1 = require("./decorators/roles.decorator");
|
||||
let RolesGuard = class RolesGuard {
|
||||
constructor(reflector) {
|
||||
this.reflector = reflector;
|
||||
}
|
||||
canActivate(context) {
|
||||
const requiredRoles = this.reflector.getAllAndOverride(roles_decorator_1.ROLES_KEY, [
|
||||
context.getHandler(),
|
||||
context.getClass(),
|
||||
]);
|
||||
if (!requiredRoles || requiredRoles.length === 0)
|
||||
return true;
|
||||
const { user } = context.switchToHttp().getRequest();
|
||||
if (!user?.role || !requiredRoles.includes(user.role)) {
|
||||
throw new common_1.ForbiddenException('Åtkomst nekad — admin-behörighet krävs');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
exports.RolesGuard = RolesGuard;
|
||||
exports.RolesGuard = RolesGuard = __decorate([
|
||||
(0, common_1.Injectable)(),
|
||||
__metadata("design:paramtypes", [core_1.Reflector])
|
||||
], RolesGuard);
|
||||
//# sourceMappingURL=roles.guard.js.map
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"roles.guard.js","sourceRoot":"","sources":["../../src/auth/roles.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA+F;AAC/F,uCAAyC;AACzC,kEAAyD;AAGlD,IAAM,UAAU,GAAhB,MAAM,UAAU;IACrB,YAAoB,SAAoB;QAApB,cAAS,GAAT,SAAS,CAAW;IAAG,CAAC;IAE5C,WAAW,CAAC,OAAyB;QACnC,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAW,2BAAS,EAAE;YAC1E,OAAO,CAAC,UAAU,EAAE;YACpB,OAAO,CAAC,QAAQ,EAAE;SACnB,CAAC,CAAC;QAGH,IAAI,CAAC,aAAa,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAE9D,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;QACrD,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACtD,MAAM,IAAI,2BAAkB,CAAC,wCAAwC,CAAC,CAAC;QACzE,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AAlBY,gCAAU;qBAAV,UAAU;IADtB,IAAA,mBAAU,GAAE;qCAEoB,gBAAS;GAD7B,UAAU,CAkBtB"}
|
||||
@@ -1,11 +0,0 @@
|
||||
import { CategoriesService } from './categories.service';
|
||||
export declare class CategoriesController {
|
||||
private readonly categoriesService;
|
||||
constructor(categoriesService: CategoriesService);
|
||||
findAll(): Promise<{
|
||||
name: string;
|
||||
id: number;
|
||||
parentId: number | null;
|
||||
}[]>;
|
||||
findTree(): Promise<import("./categories.service").CategoryNode[]>;
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CategoriesController = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const categories_service_1 = require("./categories.service");
|
||||
const public_decorator_1 = require("../auth/decorators/public.decorator");
|
||||
let CategoriesController = class CategoriesController {
|
||||
constructor(categoriesService) {
|
||||
this.categoriesService = categoriesService;
|
||||
}
|
||||
findAll() {
|
||||
return this.categoriesService.findAll();
|
||||
}
|
||||
findTree() {
|
||||
return this.categoriesService.findTree();
|
||||
}
|
||||
};
|
||||
exports.CategoriesController = CategoriesController;
|
||||
__decorate([
|
||||
(0, public_decorator_1.Public)(),
|
||||
(0, common_1.Get)(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", []),
|
||||
__metadata("design:returntype", void 0)
|
||||
], CategoriesController.prototype, "findAll", null);
|
||||
__decorate([
|
||||
(0, public_decorator_1.Public)(),
|
||||
(0, common_1.Get)('tree'),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", []),
|
||||
__metadata("design:returntype", void 0)
|
||||
], CategoriesController.prototype, "findTree", null);
|
||||
exports.CategoriesController = CategoriesController = __decorate([
|
||||
(0, common_1.Controller)('categories'),
|
||||
__metadata("design:paramtypes", [categories_service_1.CategoriesService])
|
||||
], CategoriesController);
|
||||
//# sourceMappingURL=categories.controller.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"categories.controller.js","sourceRoot":"","sources":["../../src/categories/categories.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAiD;AACjD,6DAAyD;AACzD,0EAA6D;AAGtD,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;IAC/B,YAA6B,iBAAoC;QAApC,sBAAiB,GAAjB,iBAAiB,CAAmB;IAAG,CAAC;IAIrE,OAAO;QACL,OAAO,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,CAAC;IAC1C,CAAC;IAID,QAAQ;QACN,OAAO,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,CAAC;IAC3C,CAAC;CACF,CAAA;AAdY,oDAAoB;AAK/B;IAFC,IAAA,yBAAM,GAAE;IACR,IAAA,YAAG,GAAE;;;;mDAGL;AAID;IAFC,IAAA,yBAAM,GAAE;IACR,IAAA,YAAG,EAAC,MAAM,CAAC;;;;oDAGX;+BAbU,oBAAoB;IADhC,IAAA,mBAAU,EAAC,YAAY,CAAC;qCAEyB,sCAAiB;GADtD,oBAAoB,CAchC"}
|
||||
@@ -1,2 +0,0 @@
|
||||
export declare class CategoriesModule {
|
||||
}
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CategoriesModule = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const categories_service_1 = require("./categories.service");
|
||||
const categories_controller_1 = require("./categories.controller");
|
||||
const prisma_module_1 = require("../prisma/prisma.module");
|
||||
let CategoriesModule = class CategoriesModule {
|
||||
};
|
||||
exports.CategoriesModule = CategoriesModule;
|
||||
exports.CategoriesModule = CategoriesModule = __decorate([
|
||||
(0, common_1.Module)({
|
||||
imports: [prisma_module_1.PrismaModule],
|
||||
providers: [categories_service_1.CategoriesService],
|
||||
controllers: [categories_controller_1.CategoriesController],
|
||||
exports: [categories_service_1.CategoriesService],
|
||||
})
|
||||
], CategoriesModule);
|
||||
//# sourceMappingURL=categories.module.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"categories.module.js","sourceRoot":"","sources":["../../src/categories/categories.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,6DAAyD;AACzD,mEAA+D;AAC/D,2DAAuD;AAQhD,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;CAAG,CAAA;AAAnB,4CAAgB;2BAAhB,gBAAgB;IAN5B,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,4BAAY,CAAC;QACvB,SAAS,EAAE,CAAC,sCAAiB,CAAC;QAC9B,WAAW,EAAE,CAAC,4CAAoB,CAAC;QACnC,OAAO,EAAE,CAAC,sCAAiB,CAAC;KAC7B,CAAC;GACW,gBAAgB,CAAG"}
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
export type CategoryNode = {
|
||||
id: number;
|
||||
name: string;
|
||||
parentId: number | null;
|
||||
children: CategoryNode[];
|
||||
};
|
||||
export type FlatCategory = {
|
||||
id: number;
|
||||
name: string;
|
||||
path: string;
|
||||
};
|
||||
export declare class CategoriesService {
|
||||
private readonly prisma;
|
||||
constructor(prisma: PrismaService);
|
||||
findAll(): Promise<{
|
||||
name: string;
|
||||
id: number;
|
||||
parentId: number | null;
|
||||
}[]>;
|
||||
findTree(): Promise<CategoryNode[]>;
|
||||
findFlattened(): Promise<FlatCategory[]>;
|
||||
}
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CategoriesService = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const prisma_service_1 = require("../prisma/prisma.service");
|
||||
let CategoriesService = class CategoriesService {
|
||||
constructor(prisma) {
|
||||
this.prisma = prisma;
|
||||
}
|
||||
async findAll() {
|
||||
return this.prisma.category.findMany({ orderBy: { name: 'asc' } });
|
||||
}
|
||||
async findTree() {
|
||||
const all = await this.prisma.category.findMany({ orderBy: { name: 'asc' } });
|
||||
const map = new Map();
|
||||
all.forEach((c) => map.set(c.id, { ...c, children: [] }));
|
||||
const roots = [];
|
||||
map.forEach((node) => {
|
||||
if (node.parentId === null) {
|
||||
roots.push(node);
|
||||
}
|
||||
else {
|
||||
map.get(node.parentId)?.children.push(node);
|
||||
}
|
||||
});
|
||||
return roots;
|
||||
}
|
||||
async findFlattened() {
|
||||
const all = await this.prisma.category.findMany({ orderBy: { name: 'asc' } });
|
||||
const byId = new Map();
|
||||
all.forEach((c) => byId.set(c.id, c));
|
||||
const pathCache = new Map();
|
||||
const buildPath = (id) => {
|
||||
const cached = pathCache.get(id);
|
||||
if (cached)
|
||||
return cached;
|
||||
const current = byId.get(id);
|
||||
if (!current)
|
||||
return '';
|
||||
const path = current.parentId == null
|
||||
? current.name
|
||||
: `${buildPath(current.parentId)} > ${current.name}`;
|
||||
pathCache.set(id, path);
|
||||
return path;
|
||||
};
|
||||
return all.map((c) => ({
|
||||
id: c.id,
|
||||
name: c.name,
|
||||
path: buildPath(c.id),
|
||||
}));
|
||||
}
|
||||
};
|
||||
exports.CategoriesService = CategoriesService;
|
||||
exports.CategoriesService = CategoriesService = __decorate([
|
||||
(0, common_1.Injectable)(),
|
||||
__metadata("design:paramtypes", [prisma_service_1.PrismaService])
|
||||
], CategoriesService);
|
||||
//# sourceMappingURL=categories.service.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"categories.service.js","sourceRoot":"","sources":["../../src/categories/categories.service.ts"],"names":[],"mappings":"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"}
|
||||
@@ -1,5 +0,0 @@
|
||||
import { ExceptionFilter, ArgumentsHost } from '@nestjs/common';
|
||||
export declare class GlobalExceptionFilter implements ExceptionFilter {
|
||||
private readonly logger;
|
||||
catch(exception: any, host: ArgumentsHost): void;
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var GlobalExceptionFilter_1;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.GlobalExceptionFilter = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
let GlobalExceptionFilter = GlobalExceptionFilter_1 = class GlobalExceptionFilter {
|
||||
constructor() {
|
||||
this.logger = new common_1.Logger(GlobalExceptionFilter_1.name);
|
||||
}
|
||||
catch(exception, host) {
|
||||
if (!host || host.getType() !== 'http') {
|
||||
this.logger.error(`Non-HTTP exception caught: ${exception?.message ?? exception}`);
|
||||
return;
|
||||
}
|
||||
const ctx = host.switchToHttp();
|
||||
const response = ctx.getResponse();
|
||||
const request = ctx.getRequest();
|
||||
const path = request.url;
|
||||
let statusCode = common_1.HttpStatus.INTERNAL_SERVER_ERROR;
|
||||
let message = 'Ett internt serverfel inträffade.';
|
||||
if (exception instanceof common_1.HttpException) {
|
||||
statusCode = exception.getStatus();
|
||||
const exceptionResponse = exception.getResponse();
|
||||
if (typeof exceptionResponse === 'object' && 'message' in exceptionResponse) {
|
||||
message = exceptionResponse.message || message;
|
||||
}
|
||||
else if (typeof exceptionResponse === 'string') {
|
||||
message = exceptionResponse;
|
||||
}
|
||||
}
|
||||
else if (exception instanceof Error) {
|
||||
message = exception.message || message;
|
||||
statusCode = common_1.HttpStatus.BAD_REQUEST;
|
||||
this.logger.error(`Error: ${exception.message}`, exception.stack);
|
||||
}
|
||||
if (message.includes('Unknown unit')) {
|
||||
message = 'Okänd enhet. Kontrollera enheten och försök igen.';
|
||||
}
|
||||
else if (message.includes('Cannot convert between incompatible unit types')) {
|
||||
message = 'Kan inte konvertera mellan dessa enhetstyper.';
|
||||
}
|
||||
else if (message.includes('Inventory item with id') && message.includes('not found')) {
|
||||
message = 'Hemmavarorna hittades inte.';
|
||||
}
|
||||
else if (message.includes('Product with id') && message.includes('not found')) {
|
||||
message = 'Produkten hittades inte.';
|
||||
}
|
||||
else if (message.includes('Recipe with id') && message.includes('not found')) {
|
||||
message = 'Receptet hittades inte.';
|
||||
}
|
||||
else if (message.includes('sourceProductId och targetProductId kan inte vara samma')) {
|
||||
message = 'Du kan inte slå samman en produkt med sig själv.';
|
||||
}
|
||||
const errorResponse = {
|
||||
statusCode,
|
||||
message,
|
||||
timestamp: new Date().toISOString(),
|
||||
path,
|
||||
};
|
||||
this.logger.warn(`${request.method} ${path} - Status: ${statusCode}, Message: ${message}`);
|
||||
response.status(statusCode).json(errorResponse);
|
||||
}
|
||||
};
|
||||
exports.GlobalExceptionFilter = GlobalExceptionFilter;
|
||||
exports.GlobalExceptionFilter = GlobalExceptionFilter = GlobalExceptionFilter_1 = __decorate([
|
||||
(0, common_1.Catch)()
|
||||
], GlobalExceptionFilter);
|
||||
//# sourceMappingURL=global-exception.filter.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"global-exception.filter.js","sourceRoot":"","sources":["../../../src/common/filters/global-exception.filter.ts"],"names":[],"mappings":"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"}
|
||||
@@ -1 +0,0 @@
|
||||
export declare function downloadAndOptimizeImage(sourceUrl: string, destDir: string): Promise<string>;
|
||||
-64
@@ -1,64 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.downloadAndOptimizeImage = downloadAndOptimizeImage;
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const sharp = require("sharp");
|
||||
const uuid_1 = require("uuid");
|
||||
const BLOCKED_HOSTNAMES = /^(localhost|127\.|10\.|172\.(1[6-9]|2\d|3[01])\.|192\.168\.|0\.0\.0\.0|::1|fc00:|fe80:)/i;
|
||||
async function downloadAndOptimizeImage(sourceUrl, destDir) {
|
||||
const raw = sourceUrl.trim();
|
||||
const protocolNormalized = raw.startsWith('//') ? `https:${raw}` : raw;
|
||||
let parsedUrl;
|
||||
try {
|
||||
parsedUrl = new URL(protocolNormalized);
|
||||
}
|
||||
catch {
|
||||
throw new Error('Ogiltig bild-URL');
|
||||
}
|
||||
if (parsedUrl.protocol !== 'https:') {
|
||||
throw new Error('Bild-URL måste använda https://');
|
||||
}
|
||||
const hostname = parsedUrl.hostname;
|
||||
if (BLOCKED_HOSTNAMES.test(hostname)) {
|
||||
throw new Error('Bild-URL pekar på ett blockerat nätverk');
|
||||
}
|
||||
const controller = new AbortController();
|
||||
const timeout = setTimeout(() => controller.abort(), 10_000);
|
||||
let response;
|
||||
try {
|
||||
response = await fetch(parsedUrl.toString(), {
|
||||
signal: controller.signal,
|
||||
headers: { 'User-Agent': 'Mozilla/5.0 (compatible; RecipeApp/1.0)' },
|
||||
});
|
||||
}
|
||||
finally {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status} vid nedladdning av bild`);
|
||||
}
|
||||
const contentType = response.headers.get('content-type') ?? '';
|
||||
if (!contentType.startsWith('image/')) {
|
||||
throw new Error(`Ogiltig content-type: ${contentType}`);
|
||||
}
|
||||
const arrayBuffer = await response.arrayBuffer();
|
||||
if (arrayBuffer.byteLength > 5 * 1024 * 1024) {
|
||||
throw new Error('Bilden är för stor (max 5 MB)');
|
||||
}
|
||||
const imageBuffer = Buffer.from(arrayBuffer);
|
||||
if (!fs.existsSync(destDir)) {
|
||||
fs.mkdirSync(destDir, { recursive: true });
|
||||
}
|
||||
const filename = `${(0, uuid_1.v4)()}.jpg`;
|
||||
const outputPath = path.join(destDir, filename);
|
||||
await sharp(imageBuffer)
|
||||
.resize(1200, 800, {
|
||||
fit: 'inside',
|
||||
withoutEnlargement: true,
|
||||
})
|
||||
.jpeg({ quality: 80 })
|
||||
.toFile(outputPath);
|
||||
return `/images/${filename}`;
|
||||
}
|
||||
//# sourceMappingURL=download-image.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"download-image.js","sourceRoot":"","sources":["../../../src/common/utils/download-image.ts"],"names":[],"mappings":"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"}
|
||||
@@ -1 +0,0 @@
|
||||
export declare function normalizeName(value: string): string;
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.normalizeName = normalizeName;
|
||||
function normalizeName(value) {
|
||||
return value
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.normalize('NFD')
|
||||
.replace(/[\u0300-\u036f]/g, '')
|
||||
.replace(/[^a-z0-9\s]/g, '')
|
||||
.replace(/\s+/g, '');
|
||||
}
|
||||
//# sourceMappingURL=normalize-name.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"normalize-name.js","sourceRoot":"","sources":["../../../src/common/utils/normalize-name.ts"],"names":[],"mappings":";;AAAA,sCAQC;AARD,SAAgB,aAAa,CAAC,KAAa;IACzC,OAAO,KAAK;SACT,IAAI,EAAE;SACN,WAAW,EAAE;SACb,SAAS,CAAC,KAAK,CAAC;SAChB,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;SAC/B,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;SAC3B,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACzB,CAAC"}
|
||||
@@ -1 +0,0 @@
|
||||
export {};
|
||||
@@ -1,36 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const normalize_name_1 = require("./normalize-name");
|
||||
describe('normalizeName', () => {
|
||||
it('gör om till gemener', () => {
|
||||
expect((0, normalize_name_1.normalizeName)('Kycklingfilé')).toBe('kycklingfile');
|
||||
});
|
||||
it('tar bort svenska diakritiska tecken', () => {
|
||||
expect((0, normalize_name_1.normalizeName)('åäö')).toBe('aao');
|
||||
expect((0, normalize_name_1.normalizeName)('ÅÄÖ')).toBe('aao');
|
||||
});
|
||||
it('tar bort mellanslag', () => {
|
||||
expect((0, normalize_name_1.normalizeName)('rökt paprikapulver')).toBe('roktpaprikapulver');
|
||||
});
|
||||
it('tar bort inledande och avslutande mellanslag', () => {
|
||||
expect((0, normalize_name_1.normalizeName)(' lax ')).toBe('lax');
|
||||
});
|
||||
it('tar bort specialtecken', () => {
|
||||
expect((0, normalize_name_1.normalizeName)('Curry (mild)')).toBe('currymild');
|
||||
});
|
||||
it('hanterar siffror', () => {
|
||||
expect((0, normalize_name_1.normalizeName)('Omega-3')).toBe('omega3');
|
||||
});
|
||||
it('hanterar tom sträng', () => {
|
||||
expect((0, normalize_name_1.normalizeName)('')).toBe('');
|
||||
});
|
||||
it('hanterar sträng med bara mellanslag', () => {
|
||||
expect((0, normalize_name_1.normalizeName)(' ')).toBe('');
|
||||
});
|
||||
it('normaliserar accenter korrekt', () => {
|
||||
expect((0, normalize_name_1.normalizeName)('Fläskfilé')).toBe('flaskfile');
|
||||
expect((0, normalize_name_1.normalizeName)('Gräddfil')).toBe('graddfil');
|
||||
expect((0, normalize_name_1.normalizeName)('Rödlök')).toBe('rodlok');
|
||||
});
|
||||
});
|
||||
//# sourceMappingURL=normalize-name.spec.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"normalize-name.spec.js","sourceRoot":"","sources":["../../../src/common/utils/normalize-name.spec.ts"],"names":[],"mappings":";;AAAA,qDAAiD;AAEjD,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;QAC7B,MAAM,CAAC,IAAA,8BAAa,EAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,IAAA,8BAAa,EAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,CAAC,IAAA,8BAAa,EAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;QAC7B,MAAM,CAAC,IAAA,8BAAa,EAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,CAAC,IAAA,8BAAa,EAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,MAAM,CAAC,IAAA,8BAAa,EAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAC1B,MAAM,CAAC,IAAA,8BAAa,EAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;QAC7B,MAAM,CAAC,IAAA,8BAAa,EAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,IAAA,8BAAa,EAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,IAAA,8BAAa,EAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACrD,MAAM,CAAC,IAAA,8BAAa,EAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACnD,MAAM,CAAC,IAAA,8BAAa,EAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
export interface ParsedIngredient {
|
||||
rawName: string;
|
||||
quantity: number;
|
||||
unit: string;
|
||||
note: string | null;
|
||||
alternatives: string[];
|
||||
}
|
||||
export interface ParsedRecipe {
|
||||
name: string;
|
||||
description: string;
|
||||
instructions: string;
|
||||
ingredients: ParsedIngredient[];
|
||||
}
|
||||
export declare function parseRecipeMarkdown(markdown: string): ParsedRecipe;
|
||||
-124
@@ -1,124 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parseRecipeMarkdown = parseRecipeMarkdown;
|
||||
const KNOWN_UNITS = new Set([
|
||||
'g', 'kg', 'hg', 'mg', 'ml', 'dl', 'l', 'tl',
|
||||
'st', 'tsk', 'msk', 'krm', 'matsled', 'tesled',
|
||||
'pris', 'portion', 'port', 'burk', 'förp', 'paket', 'efter smak', 'klyfta',
|
||||
]);
|
||||
const H1_RE = /^#\s+/;
|
||||
const H2_RE = /^##\s+/;
|
||||
const INGREDIENT_HEADING_RE = /ingrediens/;
|
||||
const INSTRUCTION_HEADING_RE = /instruktion|tillagning|gör så här|steg|tillväg|metod/;
|
||||
const BULLET_RE = /^[-*]\s+/;
|
||||
const PAREN_NOTE_RE = /\(([^)]+)\)\s*$/;
|
||||
const FRACTION_RE = /^(\d+)?\s*(\d+)\s*\/\s*([\d.]+)\s+(\S+)\s+(.+)$/;
|
||||
const RANGE_RE = /^(?:ca\.?\s+)?(\d+(?:[.,]\d+)?)\s*[-–]\s*(?:ca\.?\s+)?(\d+(?:[.,]\d+)?)\s+(\S+)\s+(.+)$/i;
|
||||
const QTY_UNIT_NAME_RE = /^(\d+(?:[.,]\d+)?)\s+(\S+)\s+(.+)$/;
|
||||
const QTY_NAME_RE = /^(\d+(?:[.,]\d+)?)\s+(.+)$/;
|
||||
const ALTERNATIVES_RE = /\s+eller\s+/i;
|
||||
function parseRecipeMarkdown(markdown) {
|
||||
const lines = markdown.split('\n');
|
||||
let name = '';
|
||||
let description = '';
|
||||
let instructions = '';
|
||||
const ingredients = [];
|
||||
let currentSection = 'none';
|
||||
const descriptionLines = [];
|
||||
const instructionLines = [];
|
||||
for (const line of lines) {
|
||||
const trimmed = line.trim();
|
||||
if (H1_RE.test(trimmed) && !trimmed.startsWith('##')) {
|
||||
name = trimmed.replace(H1_RE, '').trim();
|
||||
currentSection = 'description';
|
||||
continue;
|
||||
}
|
||||
if (H2_RE.test(trimmed)) {
|
||||
const heading = trimmed.replace(H2_RE, '').trim().toLowerCase();
|
||||
if (INGREDIENT_HEADING_RE.test(heading)) {
|
||||
currentSection = 'ingredients';
|
||||
}
|
||||
else if (INSTRUCTION_HEADING_RE.test(heading)) {
|
||||
currentSection = 'instructions';
|
||||
}
|
||||
else {
|
||||
currentSection = 'none';
|
||||
}
|
||||
continue;
|
||||
}
|
||||
switch (currentSection) {
|
||||
case 'description':
|
||||
if (trimmed.length > 0) {
|
||||
descriptionLines.push(trimmed);
|
||||
}
|
||||
break;
|
||||
case 'ingredients':
|
||||
if (BULLET_RE.test(trimmed)) {
|
||||
const ingredientText = trimmed.replace(BULLET_RE, '');
|
||||
ingredients.push(parseIngredientLine(ingredientText));
|
||||
}
|
||||
break;
|
||||
case 'instructions':
|
||||
if (trimmed.length > 0) {
|
||||
instructionLines.push(trimmed);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
description = descriptionLines.join('\n');
|
||||
instructions = instructionLines.join('\n');
|
||||
return { name, description, instructions, ingredients };
|
||||
}
|
||||
function parseIngredientLine(text) {
|
||||
const trimmed = text.trim();
|
||||
const toAlternatives = (rawName) => ALTERNATIVES_RE.test(rawName)
|
||||
? rawName.split(ALTERNATIVES_RE).map((s) => s.trim()).filter(Boolean)
|
||||
: [rawName];
|
||||
let note = null;
|
||||
let main = trimmed;
|
||||
const parenMatch = trimmed.match(PAREN_NOTE_RE);
|
||||
if (parenMatch) {
|
||||
note = parenMatch[1].trim();
|
||||
main = trimmed.slice(0, parenMatch.index).trim();
|
||||
}
|
||||
const fractionMatch = main.match(FRACTION_RE);
|
||||
if (fractionMatch) {
|
||||
const whole = fractionMatch[1] ? parseFloat(fractionMatch[1]) : 0;
|
||||
const quantity = whole + parseFloat(fractionMatch[2]) / parseFloat(fractionMatch[3]);
|
||||
const candidateUnit = fractionMatch[4].toLowerCase();
|
||||
if (KNOWN_UNITS.has(candidateUnit)) {
|
||||
const rawName = fractionMatch[5].trim();
|
||||
return { quantity, unit: candidateUnit, rawName, note, alternatives: toAlternatives(rawName) };
|
||||
}
|
||||
}
|
||||
const rangeMatch = main.match(RANGE_RE);
|
||||
if (rangeMatch) {
|
||||
const candidateUnit = rangeMatch[3].toLowerCase();
|
||||
if (KNOWN_UNITS.has(candidateUnit)) {
|
||||
const lo = parseNumber(rangeMatch[1]);
|
||||
const hi = parseNumber(rangeMatch[2]);
|
||||
const rawName = rangeMatch[4].trim();
|
||||
return { quantity: (lo + hi) / 2, unit: candidateUnit, rawName, note, alternatives: toAlternatives(rawName) };
|
||||
}
|
||||
}
|
||||
const fullMatch = main.match(QTY_UNIT_NAME_RE);
|
||||
if (fullMatch) {
|
||||
const candidateUnit = fullMatch[2].toLowerCase();
|
||||
if (KNOWN_UNITS.has(candidateUnit)) {
|
||||
const rawName = fullMatch[3].trim();
|
||||
return { quantity: parseNumber(fullMatch[1]), unit: candidateUnit, rawName, note, alternatives: toAlternatives(rawName) };
|
||||
}
|
||||
const rawName = fullMatch[2] + ' ' + fullMatch[3];
|
||||
return { quantity: parseNumber(fullMatch[1]), unit: 'st', rawName, note, alternatives: toAlternatives(rawName) };
|
||||
}
|
||||
const noUnitMatch = main.match(QTY_NAME_RE);
|
||||
if (noUnitMatch) {
|
||||
const rawName = noUnitMatch[2].trim();
|
||||
return { quantity: parseNumber(noUnitMatch[1]), unit: 'st', rawName, note, alternatives: toAlternatives(rawName) };
|
||||
}
|
||||
return { quantity: 0, unit: '', rawName: main, note, alternatives: toAlternatives(main) };
|
||||
}
|
||||
function parseNumber(s) {
|
||||
return parseFloat(s.replace(',', '.'));
|
||||
}
|
||||
//# sourceMappingURL=recipe-parser.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
export {};
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const recipe_parser_1 = require("./recipe-parser");
|
||||
describe('parseRecipeMarkdown — ingrediensformat', () => {
|
||||
const parse = (line) => {
|
||||
const md = `# Test\n## Ingredienser\n- ${line}\n## Instruktioner\n1. Gör det.`;
|
||||
return (0, recipe_parser_1.parseRecipeMarkdown)(md).ingredients[0];
|
||||
};
|
||||
it('vanlig rad: kvantitet enhet namn', () => {
|
||||
const ing = parse('400 g kycklingfilé');
|
||||
expect(ing).toMatchObject({ quantity: 400, unit: 'g', rawName: 'kycklingfilé' });
|
||||
});
|
||||
it('bråk: 1 1/2 dl grädde', () => {
|
||||
const ing = parse('1 1/2 dl grädde');
|
||||
expect(ing.quantity).toBeCloseTo(1.5);
|
||||
expect(ing).toMatchObject({ unit: 'dl', rawName: 'grädde' });
|
||||
});
|
||||
it('bråk utan heltal: 1/2 dl mjölk', () => {
|
||||
const ing = parse('1/2 dl mjölk');
|
||||
expect(ing.quantity).toBeCloseTo(0.5);
|
||||
expect(ing).toMatchObject({ unit: 'dl', rawName: 'mjölk' });
|
||||
});
|
||||
it('intervall: 600 - ca 700 g kycklingfilé', () => {
|
||||
const ing = parse('600 - ca 700 g kycklingfilé');
|
||||
expect(ing.quantity).toBeCloseTo(650);
|
||||
expect(ing).toMatchObject({ unit: 'g', rawName: 'kycklingfilé' });
|
||||
});
|
||||
it('intervall: ca 600-700 g kycklingfilé', () => {
|
||||
const ing = parse('ca 600-700 g kycklingfilé');
|
||||
expect(ing.quantity).toBeCloseTo(650);
|
||||
expect(ing).toMatchObject({ unit: 'g' });
|
||||
});
|
||||
it('intervall med alternativt namn: 600 - ca 700 g kycklingfilé eller kycklinginnerfilé', () => {
|
||||
const ing = parse('600 - ca 700 g kycklingfilé eller kycklinginnerfilé');
|
||||
expect(ing.quantity).toBeCloseTo(650);
|
||||
expect(ing).toMatchObject({ unit: 'g', rawName: 'kycklingfilé eller kycklinginnerfilé' });
|
||||
});
|
||||
it('parentes-not: 2 dl grädde (eller crème fraiche)', () => {
|
||||
const ing = parse('2 dl grädde (eller crème fraiche)');
|
||||
expect(ing).toMatchObject({ quantity: 2, unit: 'dl', rawName: 'grädde', note: 'eller crème fraiche' });
|
||||
});
|
||||
it('utan enhet: 3 ägg', () => {
|
||||
const ing = parse('3 ägg');
|
||||
expect(ing).toMatchObject({ quantity: 3, unit: 'st', rawName: 'ägg' });
|
||||
});
|
||||
it('bara namn: salt', () => {
|
||||
const ing = parse('salt');
|
||||
expect(ing).toMatchObject({ quantity: 0, unit: '', rawName: 'salt' });
|
||||
});
|
||||
it('decimalkomma: 2,5 dl mjölk', () => {
|
||||
const ing = parse('2,5 dl mjölk');
|
||||
expect(ing.quantity).toBeCloseTo(2.5);
|
||||
expect(ing).toMatchObject({ unit: 'dl', rawName: 'mjölk' });
|
||||
});
|
||||
});
|
||||
//# sourceMappingURL=recipe-parser.spec.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"recipe-parser.spec.js","sourceRoot":"","sources":["../../../src/common/utils/recipe-parser.spec.ts"],"names":[],"mappings":"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"}
|
||||
Vendored
-14
@@ -1,14 +0,0 @@
|
||||
export type UnitType = 'weight' | 'volume' | 'cooking' | 'piece' | 'other';
|
||||
export interface UnitDefinition {
|
||||
value: string;
|
||||
labelSv: string;
|
||||
type: UnitType;
|
||||
toBaseFactor: number;
|
||||
aliases: string[];
|
||||
}
|
||||
export declare const UNIT_DEFINITIONS: UnitDefinition[];
|
||||
export declare function normalizeUnit(unit: string): string;
|
||||
export declare function getUnitDefinition(unit: string): UnitDefinition | undefined;
|
||||
export declare function getUnitType(unit: string): UnitType | null;
|
||||
export declare function canConvert(fromUnit: string, toUnit: string): boolean;
|
||||
export declare function convertUnit(quantity: number, fromUnit: string, toUnit: string): number;
|
||||
Vendored
-78
@@ -1,78 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.UNIT_DEFINITIONS = void 0;
|
||||
exports.normalizeUnit = normalizeUnit;
|
||||
exports.getUnitDefinition = getUnitDefinition;
|
||||
exports.getUnitType = getUnitType;
|
||||
exports.canConvert = canConvert;
|
||||
exports.convertUnit = convertUnit;
|
||||
exports.UNIT_DEFINITIONS = [
|
||||
{ value: 'g', labelSv: 'g (gram)', type: 'weight', toBaseFactor: 1, aliases: ['gram'] },
|
||||
{ value: 'hg', labelSv: 'hg (hektogram)', type: 'weight', toBaseFactor: 100, aliases: ['hektogram'] },
|
||||
{ value: 'kg', labelSv: 'kg (kilogram)', type: 'weight', toBaseFactor: 1000, aliases: ['kilo', 'kilogram'] },
|
||||
{ value: 'mg', labelSv: 'mg (milligram)', type: 'weight', toBaseFactor: 0.001, aliases: ['milligram'] },
|
||||
{ value: 'ml', labelSv: 'ml (milliliter)', type: 'volume', toBaseFactor: 1, aliases: ['milliliter'] },
|
||||
{ value: 'cl', labelSv: 'cl (centiliter)', type: 'volume', toBaseFactor: 10, aliases: ['centiliter'] },
|
||||
{ value: 'dl', labelSv: 'dl (deciliter)', type: 'volume', toBaseFactor: 100, aliases: ['deciliter'] },
|
||||
{ value: 'l', labelSv: 'l (liter)', type: 'volume', toBaseFactor: 1000, aliases: ['liter'] },
|
||||
{ value: 'krm', labelSv: 'krm (kryddmått)', type: 'cooking', toBaseFactor: 1, aliases: ['kryddmatt', 'kryddmått'] },
|
||||
{ value: 'tsk', labelSv: 'tsk (tesked)', type: 'cooking', toBaseFactor: 5, aliases: ['tesked', 'test'] },
|
||||
{ value: 'msk', labelSv: 'msk (matsked)', type: 'cooking', toBaseFactor: 15, aliases: ['matsked', 'matsled'] },
|
||||
{ value: 'st', labelSv: 'st (styck)', type: 'piece', toBaseFactor: 1, aliases: ['stycke', 'styck', 'stk'] },
|
||||
{ value: 'port', labelSv: 'port (portioner)', type: 'piece', toBaseFactor: 1, aliases: ['portion', 'portioner'] },
|
||||
{ value: 'förp', labelSv: 'förp (förpackning)', type: 'piece', toBaseFactor: 1, aliases: ['forp', 'förpackning', 'forpackning'] },
|
||||
{ value: 'klyfta', labelSv: 'klyfta', type: 'piece', toBaseFactor: 1, aliases: [] },
|
||||
{ value: 'efter smak', labelSv: 'efter smak', type: 'other', toBaseFactor: 1, aliases: ['eftr smak', 'efter smak'] },
|
||||
];
|
||||
const _unitLookup = new Map();
|
||||
for (const def of exports.UNIT_DEFINITIONS) {
|
||||
_unitLookup.set(def.value.toLowerCase(), def);
|
||||
for (const alias of def.aliases) {
|
||||
_unitLookup.set(alias.toLowerCase(), def);
|
||||
}
|
||||
}
|
||||
function normalizeUnit(unit) {
|
||||
const key = unit.trim().toLowerCase();
|
||||
return _unitLookup.get(key)?.value ?? key;
|
||||
}
|
||||
function getUnitDefinition(unit) {
|
||||
const key = unit.trim().toLowerCase();
|
||||
return _unitLookup.get(key);
|
||||
}
|
||||
function getUnitType(unit) {
|
||||
return getUnitDefinition(unit)?.type ?? null;
|
||||
}
|
||||
function canConvert(fromUnit, toUnit) {
|
||||
const from = getUnitDefinition(fromUnit);
|
||||
const to = getUnitDefinition(toUnit);
|
||||
if (!from || !to)
|
||||
return false;
|
||||
if (from.type !== to.type)
|
||||
return false;
|
||||
if (from.type === 'piece' || from.type === 'other')
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
function convertUnit(quantity, fromUnit, toUnit) {
|
||||
if (quantity <= 0) {
|
||||
throw new Error(`Invalid quantity: ${quantity}. Quantity must be positive.`);
|
||||
}
|
||||
const normalizedFrom = normalizeUnit(fromUnit);
|
||||
const normalizedTo = normalizeUnit(toUnit);
|
||||
if (normalizedFrom === normalizedTo)
|
||||
return quantity;
|
||||
const fromDef = getUnitDefinition(normalizedFrom);
|
||||
const toDef = getUnitDefinition(normalizedTo);
|
||||
if (!fromDef)
|
||||
throw new Error(`Unknown unit: "${fromUnit}"`);
|
||||
if (!toDef)
|
||||
throw new Error(`Unknown unit: "${toUnit}"`);
|
||||
if (fromDef.type !== toDef.type) {
|
||||
throw new Error(`Cannot convert between incompatible unit types: "${fromUnit}" (${fromDef.type}) and "${toUnit}" (${toDef.type})`);
|
||||
}
|
||||
if (fromDef.type === 'piece' || fromDef.type === 'other') {
|
||||
return quantity;
|
||||
}
|
||||
return (quantity * fromDef.toBaseFactor) / toDef.toBaseFactor;
|
||||
}
|
||||
//# sourceMappingURL=units.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"units.js","sourceRoot":"","sources":["../../../src/common/utils/units.ts"],"names":[],"mappings":"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"}
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
import { Response } from 'express';
|
||||
import { HealthService } from './health.service';
|
||||
export declare class HealthController {
|
||||
private readonly healthService;
|
||||
constructor(healthService: HealthService);
|
||||
getHealth(res: Response): Promise<void>;
|
||||
getDatabaseHealth(res: Response): Promise<void>;
|
||||
}
|
||||
-64
@@ -1,64 +0,0 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
return function (target, key) { decorator(target, key, paramIndex); }
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.HealthController = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const health_service_1 = require("./health.service");
|
||||
const public_decorator_1 = require("../auth/decorators/public.decorator");
|
||||
let HealthController = class HealthController {
|
||||
constructor(healthService) {
|
||||
this.healthService = healthService;
|
||||
}
|
||||
async getHealth(res) {
|
||||
const health = await this.healthService.getOverallHealth();
|
||||
res.status(health.statusCode).json({
|
||||
status: health.status,
|
||||
service: health.service,
|
||||
timestamp: health.timestamp,
|
||||
uptime: health.uptime,
|
||||
checks: health.checks,
|
||||
});
|
||||
}
|
||||
async getDatabaseHealth(res) {
|
||||
const dbHealth = await this.healthService.getDatabaseHealth();
|
||||
res.status(dbHealth.statusCode).json({
|
||||
status: dbHealth.status,
|
||||
database: dbHealth.database,
|
||||
responseTime: `${dbHealth.responseTime}ms`,
|
||||
timestamp: dbHealth.timestamp,
|
||||
details: dbHealth.details,
|
||||
});
|
||||
}
|
||||
};
|
||||
exports.HealthController = HealthController;
|
||||
__decorate([
|
||||
(0, common_1.Get)(),
|
||||
__param(0, (0, common_1.Res)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], HealthController.prototype, "getHealth", null);
|
||||
__decorate([
|
||||
(0, common_1.Get)('db'),
|
||||
__param(0, (0, common_1.Res)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], HealthController.prototype, "getDatabaseHealth", null);
|
||||
exports.HealthController = HealthController = __decorate([
|
||||
(0, public_decorator_1.Public)(),
|
||||
(0, common_1.Controller)('health'),
|
||||
__metadata("design:paramtypes", [health_service_1.HealthService])
|
||||
], HealthController);
|
||||
//# sourceMappingURL=health.controller.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"health.controller.js","sourceRoot":"","sources":["../../src/health/health.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAgE;AAEhE,qDAAiD;AACjD,0EAA6D;AAItD,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;IAC3B,YAA6B,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;IAAG,CAAC;IAOvD,AAAN,KAAK,CAAC,SAAS,CAAQ,GAAa;QAClC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,gBAAgB,EAAE,CAAC;QAC3D,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;YACjC,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAC,CAAC;IACL,CAAC;IAOK,AAAN,KAAK,CAAC,iBAAiB,CAAQ,GAAa;QAC1C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,iBAAiB,EAAE,CAAC;QAC9D,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;YACnC,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,YAAY,EAAE,GAAG,QAAQ,CAAC,YAAY,IAAI;YAC1C,SAAS,EAAE,QAAQ,CAAC,SAAS;YAC7B,OAAO,EAAE,QAAQ,CAAC,OAAO;SAC1B,CAAC,CAAC;IACL,CAAC;CACF,CAAA;AAlCY,4CAAgB;AAQrB;IADL,IAAA,YAAG,GAAE;IACW,WAAA,IAAA,YAAG,GAAE,CAAA;;;;iDASrB;AAOK;IADL,IAAA,YAAG,EAAC,IAAI,CAAC;IACe,WAAA,IAAA,YAAG,GAAE,CAAA;;;;yDAS7B;2BAjCU,gBAAgB;IAF5B,IAAA,yBAAM,GAAE;IACR,IAAA,mBAAU,EAAC,QAAQ,CAAC;qCAEyB,8BAAa;GAD9C,gBAAgB,CAkC5B"}
|
||||
-2
@@ -1,2 +0,0 @@
|
||||
export declare class HealthModule {
|
||||
}
|
||||
Vendored
-24
@@ -1,24 +0,0 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.HealthModule = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const health_controller_1 = require("./health.controller");
|
||||
const health_service_1 = require("./health.service");
|
||||
const prisma_module_1 = require("../prisma/prisma.module");
|
||||
let HealthModule = class HealthModule {
|
||||
};
|
||||
exports.HealthModule = HealthModule;
|
||||
exports.HealthModule = HealthModule = __decorate([
|
||||
(0, common_1.Module)({
|
||||
imports: [prisma_module_1.PrismaModule],
|
||||
controllers: [health_controller_1.HealthController],
|
||||
providers: [health_service_1.HealthService],
|
||||
})
|
||||
], HealthModule);
|
||||
//# sourceMappingURL=health.module.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"health.module.js","sourceRoot":"","sources":["../../src/health/health.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,2DAAuD;AACvD,qDAAiD;AACjD,2DAAuD;AAOhD,IAAM,YAAY,GAAlB,MAAM,YAAY;CAAG,CAAA;AAAf,oCAAY;uBAAZ,YAAY;IALxB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,4BAAY,CAAC;QACvB,WAAW,EAAE,CAAC,oCAAgB,CAAC;QAC/B,SAAS,EAAE,CAAC,8BAAa,CAAC;KAC3B,CAAC;GACW,YAAY,CAAG"}
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
export interface HealthStatus {
|
||||
status: 'healthy' | 'degraded' | 'unhealthy';
|
||||
service: string;
|
||||
timestamp: string;
|
||||
uptime: number;
|
||||
checks: {
|
||||
database: {
|
||||
status: 'ok' | 'error';
|
||||
responseTime: number;
|
||||
details?: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
export declare class HealthService {
|
||||
private readonly prisma;
|
||||
private readonly startTime;
|
||||
constructor(prisma: PrismaService);
|
||||
getOverallHealth(): Promise<{
|
||||
status: 'healthy' | 'degraded' | 'unhealthy';
|
||||
statusCode: number;
|
||||
service: string;
|
||||
timestamp: string;
|
||||
uptime: number;
|
||||
checks: {
|
||||
database: {
|
||||
status: 'ok' | 'error';
|
||||
responseTime: number;
|
||||
details?: string;
|
||||
};
|
||||
};
|
||||
}>;
|
||||
getDatabaseHealth(): Promise<{
|
||||
status: 'ok' | 'error';
|
||||
database: string;
|
||||
responseTime: number;
|
||||
timestamp: string;
|
||||
details?: string;
|
||||
statusCode: number;
|
||||
}>;
|
||||
}
|
||||
-89
@@ -1,89 +0,0 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.HealthService = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const prisma_service_1 = require("../prisma/prisma.service");
|
||||
let HealthService = class HealthService {
|
||||
constructor(prisma) {
|
||||
this.prisma = prisma;
|
||||
this.startTime = Date.now();
|
||||
}
|
||||
async getOverallHealth() {
|
||||
const timestamp = new Date().toISOString();
|
||||
const uptime = Date.now() - this.startTime;
|
||||
const dbStart = Date.now();
|
||||
let dbStatus = 'ok';
|
||||
let dbResponseTime = 0;
|
||||
let dbDetails;
|
||||
try {
|
||||
await this.prisma.$queryRaw `SELECT 1`;
|
||||
dbResponseTime = Date.now() - dbStart;
|
||||
}
|
||||
catch (error) {
|
||||
dbStatus = 'error';
|
||||
dbResponseTime = Date.now() - dbStart;
|
||||
dbDetails = error instanceof Error ? error.message : 'Unknown database error';
|
||||
}
|
||||
let overallStatus = 'healthy';
|
||||
if (dbStatus === 'error') {
|
||||
overallStatus = 'unhealthy';
|
||||
}
|
||||
const statusCode = overallStatus === 'unhealthy' ? 503 : 200;
|
||||
return {
|
||||
status: overallStatus,
|
||||
statusCode,
|
||||
service: 'recipe-api',
|
||||
timestamp,
|
||||
uptime,
|
||||
checks: {
|
||||
database: {
|
||||
status: dbStatus,
|
||||
responseTime: dbResponseTime,
|
||||
details: dbDetails,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
async getDatabaseHealth() {
|
||||
const timestamp = new Date().toISOString();
|
||||
const startTime = Date.now();
|
||||
try {
|
||||
await this.prisma.$queryRaw `SELECT 1`;
|
||||
const responseTime = Date.now() - startTime;
|
||||
return {
|
||||
status: 'ok',
|
||||
database: 'connected',
|
||||
responseTime,
|
||||
timestamp,
|
||||
statusCode: 200,
|
||||
};
|
||||
}
|
||||
catch (error) {
|
||||
const responseTime = Date.now() - startTime;
|
||||
const details = error instanceof Error ? error.message : 'Unknown database error';
|
||||
return {
|
||||
status: 'error',
|
||||
database: 'not reachable',
|
||||
responseTime,
|
||||
timestamp,
|
||||
details,
|
||||
statusCode: 503,
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
exports.HealthService = HealthService;
|
||||
exports.HealthService = HealthService = __decorate([
|
||||
(0, common_1.Injectable)(),
|
||||
__metadata("design:paramtypes", [prisma_service_1.PrismaService])
|
||||
], HealthService);
|
||||
//# sourceMappingURL=health.service.js.map
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"health.service.js","sourceRoot":"","sources":["../../src/health/health.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,6DAAyD;AAiBlD,IAAM,aAAa,GAAnB,MAAM,aAAa;IAGxB,YAA6B,MAAqB;QAArB,WAAM,GAAN,MAAM,CAAe;QAFjC,cAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEa,CAAC;IAEtD,KAAK,CAAC,gBAAgB;QAcpB,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC;QAG3C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,IAAI,QAAQ,GAAmB,IAAI,CAAC;QACpC,IAAI,cAAc,GAAG,CAAC,CAAC;QACvB,IAAI,SAA6B,CAAC;QAElC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAA,UAAU,CAAC;YACtC,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;QACxC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,QAAQ,GAAG,OAAO,CAAC;YACnB,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;YACtC,SAAS,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC;QAChF,CAAC;QAGD,IAAI,aAAa,GAAyC,SAAS,CAAC;QACpE,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YACzB,aAAa,GAAG,WAAW,CAAC;QAC9B,CAAC;QAED,MAAM,UAAU,GAAG,aAAa,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAE7D,OAAO;YACL,MAAM,EAAE,aAAa;YACrB,UAAU;YACV,OAAO,EAAE,YAAY;YACrB,SAAS;YACT,MAAM;YACN,MAAM,EAAE;gBACN,QAAQ,EAAE;oBACR,MAAM,EAAE,QAAQ;oBAChB,YAAY,EAAE,cAAc;oBAC5B,OAAO,EAAE,SAAS;iBACnB;aACF;SACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,iBAAiB;QAQrB,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAA,UAAU,CAAC;YACtC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAE5C,OAAO;gBACL,MAAM,EAAE,IAAI;gBACZ,QAAQ,EAAE,WAAW;gBACrB,YAAY;gBACZ,SAAS;gBACT,UAAU,EAAE,GAAG;aAChB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAC5C,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC;YAElF,OAAO;gBACL,MAAM,EAAE,OAAO;gBACf,QAAQ,EAAE,eAAe;gBACzB,YAAY;gBACZ,SAAS;gBACT,OAAO;gBACP,UAAU,EAAE,GAAG;aAChB,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAA;AAjGY,sCAAa;wBAAb,aAAa;IADzB,IAAA,mBAAU,GAAE;qCAI0B,8BAAa;GAHvC,aAAa,CAiGzB"}
|
||||
@@ -1,4 +0,0 @@
|
||||
export declare class ConsumeInventoryDto {
|
||||
amountUsed: number;
|
||||
comment?: string;
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ConsumeInventoryDto = void 0;
|
||||
const class_validator_1 = require("class-validator");
|
||||
class ConsumeInventoryDto {
|
||||
}
|
||||
exports.ConsumeInventoryDto = ConsumeInventoryDto;
|
||||
__decorate([
|
||||
(0, class_validator_1.IsNumber)(),
|
||||
(0, class_validator_1.Min)(0.01),
|
||||
__metadata("design:type", Number)
|
||||
], ConsumeInventoryDto.prototype, "amountUsed", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
(0, class_validator_1.IsString)(),
|
||||
__metadata("design:type", String)
|
||||
], ConsumeInventoryDto.prototype, "comment", void 0);
|
||||
//# sourceMappingURL=consume-inventory.dto.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"consume-inventory.dto.js","sourceRoot":"","sources":["../../../src/inventory/dto/consume-inventory.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAAsE;AAEtE,MAAa,mBAAmB;CAQ/B;AARD,kDAQC;AALC;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,qBAAG,EAAC,IAAI,CAAC;;uDACU;AAIpB;IAFC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;;oDACM"}
|
||||
@@ -1,14 +0,0 @@
|
||||
export declare class CreateInventoryDto {
|
||||
productId: number;
|
||||
quantity: number;
|
||||
unit: string;
|
||||
location?: string;
|
||||
purchaseDate?: string;
|
||||
bestBeforeDate?: string;
|
||||
brand?: string;
|
||||
origin?: string;
|
||||
receiptName?: string;
|
||||
opened?: boolean;
|
||||
suitableFor?: string;
|
||||
comment?: string;
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CreateInventoryDto = void 0;
|
||||
const class_validator_1 = require("class-validator");
|
||||
class CreateInventoryDto {
|
||||
}
|
||||
exports.CreateInventoryDto = CreateInventoryDto;
|
||||
__decorate([
|
||||
(0, class_validator_1.IsInt)(),
|
||||
__metadata("design:type", Number)
|
||||
], CreateInventoryDto.prototype, "productId", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsNumber)(),
|
||||
(0, class_validator_1.Min)(0),
|
||||
__metadata("design:type", Number)
|
||||
], CreateInventoryDto.prototype, "quantity", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsString)(),
|
||||
__metadata("design:type", String)
|
||||
], CreateInventoryDto.prototype, "unit", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
(0, class_validator_1.IsString)(),
|
||||
__metadata("design:type", String)
|
||||
], CreateInventoryDto.prototype, "location", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
__metadata("design:type", String)
|
||||
], CreateInventoryDto.prototype, "purchaseDate", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
__metadata("design:type", String)
|
||||
], CreateInventoryDto.prototype, "bestBeforeDate", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
(0, class_validator_1.IsString)(),
|
||||
__metadata("design:type", String)
|
||||
], CreateInventoryDto.prototype, "brand", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
(0, class_validator_1.IsString)(),
|
||||
__metadata("design:type", String)
|
||||
], CreateInventoryDto.prototype, "origin", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
(0, class_validator_1.IsString)(),
|
||||
__metadata("design:type", String)
|
||||
], CreateInventoryDto.prototype, "receiptName", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
(0, class_validator_1.IsBoolean)(),
|
||||
__metadata("design:type", Boolean)
|
||||
], CreateInventoryDto.prototype, "opened", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
(0, class_validator_1.IsString)(),
|
||||
__metadata("design:type", String)
|
||||
], CreateInventoryDto.prototype, "suitableFor", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
(0, class_validator_1.IsString)(),
|
||||
__metadata("design:type", String)
|
||||
], CreateInventoryDto.prototype, "comment", void 0);
|
||||
//# sourceMappingURL=create-inventory.dto.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"create-inventory.dto.js","sourceRoot":"","sources":["../../../src/inventory/dto/create-inventory.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAOyB;AAEzB,MAAa,kBAAkB;CA4C9B;AA5CD,gDA4CC;AA1CC;IADC,IAAA,uBAAK,GAAE;;qDACW;AAInB;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,qBAAG,EAAC,CAAC,CAAC;;oDACW;AAGlB;IADC,IAAA,0BAAQ,GAAE;;gDACG;AAId;IAFC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;;oDACO;AAGlB;IADC,IAAA,4BAAU,GAAE;;wDACS;AAGtB;IADC,IAAA,4BAAU,GAAE;;0DACW;AAIxB;IAFC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;;iDACI;AAIf;IAFC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;;kDACK;AAIhB;IAFC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;;uDACU;AAIrB;IAFC,IAAA,4BAAU,GAAE;IACZ,IAAA,2BAAS,GAAE;;kDACK;AAIjB;IAFC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;;uDACU;AAIrB;IAFC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;;mDACM"}
|
||||
@@ -1,13 +0,0 @@
|
||||
export declare class UpdateInventoryDto {
|
||||
productId?: number;
|
||||
quantity?: number;
|
||||
unit?: string;
|
||||
location?: string;
|
||||
purchaseDate?: string;
|
||||
bestBeforeDate?: string;
|
||||
brand?: string;
|
||||
receiptName?: string;
|
||||
opened?: boolean;
|
||||
suitableFor?: string;
|
||||
comment?: string;
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.UpdateInventoryDto = void 0;
|
||||
const class_validator_1 = require("class-validator");
|
||||
class UpdateInventoryDto {
|
||||
}
|
||||
exports.UpdateInventoryDto = UpdateInventoryDto;
|
||||
__decorate([
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
(0, class_validator_1.IsInt)(),
|
||||
__metadata("design:type", Number)
|
||||
], UpdateInventoryDto.prototype, "productId", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
(0, class_validator_1.IsNumber)(),
|
||||
(0, class_validator_1.Min)(0),
|
||||
__metadata("design:type", Number)
|
||||
], UpdateInventoryDto.prototype, "quantity", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
(0, class_validator_1.IsString)(),
|
||||
__metadata("design:type", String)
|
||||
], UpdateInventoryDto.prototype, "unit", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
(0, class_validator_1.IsString)(),
|
||||
__metadata("design:type", String)
|
||||
], UpdateInventoryDto.prototype, "location", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
__metadata("design:type", String)
|
||||
], UpdateInventoryDto.prototype, "purchaseDate", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
__metadata("design:type", String)
|
||||
], UpdateInventoryDto.prototype, "bestBeforeDate", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
(0, class_validator_1.IsString)(),
|
||||
__metadata("design:type", String)
|
||||
], UpdateInventoryDto.prototype, "brand", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
(0, class_validator_1.IsString)(),
|
||||
__metadata("design:type", String)
|
||||
], UpdateInventoryDto.prototype, "receiptName", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
(0, class_validator_1.IsBoolean)(),
|
||||
__metadata("design:type", Boolean)
|
||||
], UpdateInventoryDto.prototype, "opened", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
(0, class_validator_1.IsString)(),
|
||||
__metadata("design:type", String)
|
||||
], UpdateInventoryDto.prototype, "suitableFor", void 0);
|
||||
__decorate([
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
(0, class_validator_1.IsString)(),
|
||||
__metadata("design:type", String)
|
||||
], UpdateInventoryDto.prototype, "comment", void 0);
|
||||
//# sourceMappingURL=update-inventory.dto.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"update-inventory.dto.js","sourceRoot":"","sources":["../../../src/inventory/dto/update-inventory.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAOyB;AAEzB,MAAa,kBAAkB;CA2C9B;AA3CD,gDA2CC;AAxCC;IAFC,IAAA,4BAAU,GAAE;IACZ,IAAA,uBAAK,GAAE;;qDACW;AAKnB;IAHC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;IACV,IAAA,qBAAG,EAAC,CAAC,CAAC;;oDACW;AAIlB;IAFC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;;gDACG;AAId;IAFC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;;oDACO;AAGlB;IADC,IAAA,4BAAU,GAAE;;wDACS;AAGtB;IADC,IAAA,4BAAU,GAAE;;0DACW;AAIxB;IAFC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;;iDACI;AAIf;IAFC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;;uDACU;AAIrB;IAFC,IAAA,4BAAU,GAAE;IACZ,IAAA,2BAAS,GAAE;;kDACK;AAIjB;IAFC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;;uDACU;AAIrB;IAFC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;;mDACM"}
|
||||
-272
@@ -1,272 +0,0 @@
|
||||
import { CreateInventoryDto } from './dto/create-inventory.dto';
|
||||
import { UpdateInventoryDto } from './dto/update-inventory.dto';
|
||||
import { InventoryService } from './inventory.service';
|
||||
import { ConsumeInventoryDto } from './dto/consume-inventory.dto';
|
||||
export declare class InventoryController {
|
||||
private readonly inventoryService;
|
||||
constructor(inventoryService: InventoryService);
|
||||
consume(id: number, body: ConsumeInventoryDto): Promise<{
|
||||
product: {
|
||||
categoryRef: ({
|
||||
parent: ({
|
||||
parent: {
|
||||
name: string;
|
||||
id: number;
|
||||
parentId: number | null;
|
||||
} | null;
|
||||
} & {
|
||||
name: string;
|
||||
id: number;
|
||||
parentId: number | null;
|
||||
}) | null;
|
||||
} & {
|
||||
name: string;
|
||||
id: number;
|
||||
parentId: number | null;
|
||||
}) | null;
|
||||
} & {
|
||||
name: string;
|
||||
category: string | null;
|
||||
status: string;
|
||||
id: number;
|
||||
categoryId: number | null;
|
||||
normalizedName: string;
|
||||
canonicalName: string | null;
|
||||
isActive: boolean;
|
||||
deletedAt: Date | null;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
ownerId: number;
|
||||
isPrivate: boolean;
|
||||
};
|
||||
} & {
|
||||
origin: string | null;
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
productId: number;
|
||||
quantity: import("@prisma/client/runtime/library").Decimal;
|
||||
unit: string;
|
||||
brand: string | null;
|
||||
receiptName: string | null;
|
||||
location: string | null;
|
||||
purchaseDate: Date | null;
|
||||
opened: boolean | null;
|
||||
suitableFor: string | null;
|
||||
bestBeforeDate: Date | null;
|
||||
comment: string | null;
|
||||
}>;
|
||||
findConsumptionHistory(id: number): Promise<{
|
||||
inventoryItem: {
|
||||
unit: string;
|
||||
};
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
comment: string | null;
|
||||
inventoryItemId: number;
|
||||
amountUsed: import("@prisma/client/runtime/library").Decimal;
|
||||
}[]>;
|
||||
findAll(location?: string, sort?: string): Promise<({
|
||||
product: {
|
||||
categoryRef: ({
|
||||
parent: ({
|
||||
parent: {
|
||||
name: string;
|
||||
id: number;
|
||||
parentId: number | null;
|
||||
} | null;
|
||||
} & {
|
||||
name: string;
|
||||
id: number;
|
||||
parentId: number | null;
|
||||
}) | null;
|
||||
} & {
|
||||
name: string;
|
||||
id: number;
|
||||
parentId: number | null;
|
||||
}) | null;
|
||||
} & {
|
||||
name: string;
|
||||
category: string | null;
|
||||
status: string;
|
||||
id: number;
|
||||
categoryId: number | null;
|
||||
normalizedName: string;
|
||||
canonicalName: string | null;
|
||||
isActive: boolean;
|
||||
deletedAt: Date | null;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
ownerId: number;
|
||||
isPrivate: boolean;
|
||||
};
|
||||
} & {
|
||||
origin: string | null;
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
productId: number;
|
||||
quantity: import("@prisma/client/runtime/library").Decimal;
|
||||
unit: string;
|
||||
brand: string | null;
|
||||
receiptName: string | null;
|
||||
location: string | null;
|
||||
purchaseDate: Date | null;
|
||||
opened: boolean | null;
|
||||
suitableFor: string | null;
|
||||
bestBeforeDate: Date | null;
|
||||
comment: string | null;
|
||||
})[]>;
|
||||
findExpiring(): Promise<({
|
||||
product: {
|
||||
name: string;
|
||||
category: string | null;
|
||||
status: string;
|
||||
id: number;
|
||||
categoryId: number | null;
|
||||
normalizedName: string;
|
||||
canonicalName: string | null;
|
||||
isActive: boolean;
|
||||
deletedAt: Date | null;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
ownerId: number;
|
||||
isPrivate: boolean;
|
||||
};
|
||||
} & {
|
||||
origin: string | null;
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
productId: number;
|
||||
quantity: import("@prisma/client/runtime/library").Decimal;
|
||||
unit: string;
|
||||
brand: string | null;
|
||||
receiptName: string | null;
|
||||
location: string | null;
|
||||
purchaseDate: Date | null;
|
||||
opened: boolean | null;
|
||||
suitableFor: string | null;
|
||||
bestBeforeDate: Date | null;
|
||||
comment: string | null;
|
||||
})[]>;
|
||||
create(body: CreateInventoryDto): Promise<{
|
||||
product: {
|
||||
categoryRef: ({
|
||||
parent: ({
|
||||
parent: {
|
||||
name: string;
|
||||
id: number;
|
||||
parentId: number | null;
|
||||
} | null;
|
||||
} & {
|
||||
name: string;
|
||||
id: number;
|
||||
parentId: number | null;
|
||||
}) | null;
|
||||
} & {
|
||||
name: string;
|
||||
id: number;
|
||||
parentId: number | null;
|
||||
}) | null;
|
||||
} & {
|
||||
name: string;
|
||||
category: string | null;
|
||||
status: string;
|
||||
id: number;
|
||||
categoryId: number | null;
|
||||
normalizedName: string;
|
||||
canonicalName: string | null;
|
||||
isActive: boolean;
|
||||
deletedAt: Date | null;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
ownerId: number;
|
||||
isPrivate: boolean;
|
||||
};
|
||||
} & {
|
||||
origin: string | null;
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
productId: number;
|
||||
quantity: import("@prisma/client/runtime/library").Decimal;
|
||||
unit: string;
|
||||
brand: string | null;
|
||||
receiptName: string | null;
|
||||
location: string | null;
|
||||
purchaseDate: Date | null;
|
||||
opened: boolean | null;
|
||||
suitableFor: string | null;
|
||||
bestBeforeDate: Date | null;
|
||||
comment: string | null;
|
||||
}>;
|
||||
update(id: number, body: UpdateInventoryDto): Promise<{
|
||||
product: {
|
||||
categoryRef: ({
|
||||
parent: ({
|
||||
parent: {
|
||||
name: string;
|
||||
id: number;
|
||||
parentId: number | null;
|
||||
} | null;
|
||||
} & {
|
||||
name: string;
|
||||
id: number;
|
||||
parentId: number | null;
|
||||
}) | null;
|
||||
} & {
|
||||
name: string;
|
||||
id: number;
|
||||
parentId: number | null;
|
||||
}) | null;
|
||||
} & {
|
||||
name: string;
|
||||
category: string | null;
|
||||
status: string;
|
||||
id: number;
|
||||
categoryId: number | null;
|
||||
normalizedName: string;
|
||||
canonicalName: string | null;
|
||||
isActive: boolean;
|
||||
deletedAt: Date | null;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
ownerId: number;
|
||||
isPrivate: boolean;
|
||||
};
|
||||
} & {
|
||||
origin: string | null;
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
productId: number;
|
||||
quantity: import("@prisma/client/runtime/library").Decimal;
|
||||
unit: string;
|
||||
brand: string | null;
|
||||
receiptName: string | null;
|
||||
location: string | null;
|
||||
purchaseDate: Date | null;
|
||||
opened: boolean | null;
|
||||
suitableFor: string | null;
|
||||
bestBeforeDate: Date | null;
|
||||
comment: string | null;
|
||||
}>;
|
||||
remove(id: number): Promise<{
|
||||
origin: string | null;
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
productId: number;
|
||||
quantity: import("@prisma/client/runtime/library").Decimal;
|
||||
unit: string;
|
||||
brand: string | null;
|
||||
receiptName: string | null;
|
||||
location: string | null;
|
||||
purchaseDate: Date | null;
|
||||
opened: boolean | null;
|
||||
suitableFor: string | null;
|
||||
bestBeforeDate: Date | null;
|
||||
comment: string | null;
|
||||
}>;
|
||||
}
|
||||
-103
@@ -1,103 +0,0 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
return function (target, key) { decorator(target, key, paramIndex); }
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.InventoryController = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const create_inventory_dto_1 = require("./dto/create-inventory.dto");
|
||||
const update_inventory_dto_1 = require("./dto/update-inventory.dto");
|
||||
const inventory_service_1 = require("./inventory.service");
|
||||
const consume_inventory_dto_1 = require("./dto/consume-inventory.dto");
|
||||
let InventoryController = class InventoryController {
|
||||
constructor(inventoryService) {
|
||||
this.inventoryService = inventoryService;
|
||||
}
|
||||
consume(id, body) {
|
||||
return this.inventoryService.consume(id, body);
|
||||
}
|
||||
findConsumptionHistory(id) {
|
||||
return this.inventoryService.findConsumptionHistory(id);
|
||||
}
|
||||
findAll(location, sort) {
|
||||
return this.inventoryService.findAll({ location, sort });
|
||||
}
|
||||
findExpiring() {
|
||||
return this.inventoryService.findExpiring();
|
||||
}
|
||||
create(body) {
|
||||
return this.inventoryService.create(body);
|
||||
}
|
||||
update(id, body) {
|
||||
return this.inventoryService.update(id, body);
|
||||
}
|
||||
remove(id) {
|
||||
return this.inventoryService.remove(id);
|
||||
}
|
||||
};
|
||||
exports.InventoryController = InventoryController;
|
||||
__decorate([
|
||||
(0, common_1.Post)(':id/consume'),
|
||||
__param(0, (0, common_1.Param)('id', common_1.ParseIntPipe)),
|
||||
__param(1, (0, common_1.Body)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Number, consume_inventory_dto_1.ConsumeInventoryDto]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], InventoryController.prototype, "consume", null);
|
||||
__decorate([
|
||||
(0, common_1.Get)(':id/consumption-history'),
|
||||
__param(0, (0, common_1.Param)('id', common_1.ParseIntPipe)),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Number]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], InventoryController.prototype, "findConsumptionHistory", null);
|
||||
__decorate([
|
||||
(0, common_1.Get)(),
|
||||
__param(0, (0, common_1.Query)('location')),
|
||||
__param(1, (0, common_1.Query)('sort')),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [String, String]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], InventoryController.prototype, "findAll", null);
|
||||
__decorate([
|
||||
(0, common_1.Get)('expiring'),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", []),
|
||||
__metadata("design:returntype", void 0)
|
||||
], InventoryController.prototype, "findExpiring", null);
|
||||
__decorate([
|
||||
(0, common_1.Post)(),
|
||||
__param(0, (0, common_1.Body)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [create_inventory_dto_1.CreateInventoryDto]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], InventoryController.prototype, "create", null);
|
||||
__decorate([
|
||||
(0, common_1.Patch)(':id'),
|
||||
__param(0, (0, common_1.Param)('id', common_1.ParseIntPipe)),
|
||||
__param(1, (0, common_1.Body)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Number, update_inventory_dto_1.UpdateInventoryDto]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], InventoryController.prototype, "update", null);
|
||||
__decorate([
|
||||
(0, common_1.Delete)(':id'),
|
||||
__param(0, (0, common_1.Param)('id', common_1.ParseIntPipe)),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Number]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], InventoryController.prototype, "remove", null);
|
||||
exports.InventoryController = InventoryController = __decorate([
|
||||
(0, common_1.Controller)('inventory'),
|
||||
__metadata("design:paramtypes", [inventory_service_1.InventoryService])
|
||||
], InventoryController);
|
||||
//# sourceMappingURL=inventory.controller.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"inventory.controller.js","sourceRoot":"","sources":["../../src/inventory/inventory.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAUwB;AACxB,qEAAgE;AAChE,qEAAgE;AAChE,2DAAuD;AACvD,uEAAkE;AAG3D,IAAM,mBAAmB,GAAzB,MAAM,mBAAmB;IAC9B,YAA6B,gBAAkC;QAAlC,qBAAgB,GAAhB,gBAAgB,CAAkB;IAAG,CAAC;IAGpE,OAAO,CACsB,EAAU,EAC7B,IAAyB;QAElC,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IAC/C,CAAC;IAGH,sBAAsB,CAA4B,EAAU;QAC1D,OAAO,IAAI,CAAC,gBAAgB,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC;IAGD,OAAO,CACc,QAAiB,EACrB,IAAa;QAE5B,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;IAGD,YAAY;QACV,OAAO,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE,CAAC;IAC9C,CAAC;IAGD,MAAM,CAAS,IAAwB;QACrC,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC5C,CAAC;IAGD,MAAM,CACuB,EAAU,EAC7B,IAAwB;QAEhC,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IAChD,CAAC;IAGD,MAAM,CAA4B,EAAU;QAC1C,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC1C,CAAC;CACF,CAAA;AA9CY,kDAAmB;AAI/B;IADC,IAAA,aAAI,EAAC,aAAa,CAAC;IAEjB,WAAA,IAAA,cAAK,EAAC,IAAI,EAAE,qBAAY,CAAC,CAAA;IACzB,WAAA,IAAA,aAAI,GAAE,CAAA;;6CAAO,2CAAmB;;kDAGjC;AAGH;IADG,IAAA,YAAG,EAAC,yBAAyB,CAAC;IACT,WAAA,IAAA,cAAK,EAAC,IAAI,EAAE,qBAAY,CAAC,CAAA;;;;iEAE9C;AAGD;IADC,IAAA,YAAG,GAAE;IAEH,WAAA,IAAA,cAAK,EAAC,UAAU,CAAC,CAAA;IACjB,WAAA,IAAA,cAAK,EAAC,MAAM,CAAC,CAAA;;;;kDAGf;AAGD;IADC,IAAA,YAAG,EAAC,UAAU,CAAC;;;;uDAGf;AAGD;IADC,IAAA,aAAI,GAAE;IACC,WAAA,IAAA,aAAI,GAAE,CAAA;;qCAAO,yCAAkB;;iDAEtC;AAGD;IADC,IAAA,cAAK,EAAC,KAAK,CAAC;IAEV,WAAA,IAAA,cAAK,EAAC,IAAI,EAAE,qBAAY,CAAC,CAAA;IACzB,WAAA,IAAA,aAAI,GAAE,CAAA;;6CAAO,yCAAkB;;iDAGjC;AAGD;IADC,IAAA,eAAM,EAAC,KAAK,CAAC;IACN,WAAA,IAAA,cAAK,EAAC,IAAI,EAAE,qBAAY,CAAC,CAAA;;;;iDAEhC;8BA7CU,mBAAmB;IAD/B,IAAA,mBAAU,EAAC,WAAW,CAAC;qCAEyB,oCAAgB;GADpD,mBAAmB,CA8C/B"}
|
||||
@@ -1,2 +0,0 @@
|
||||
export declare class InventoryModule {
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user