Refactor code structure for improved readability and maintainability

This commit is contained in:
Nils-Johan Gynther
2026-05-07 11:57:54 +02:00
parent 943e449c97
commit 4affb03504
277 changed files with 0 additions and 12295 deletions
-12
View File
@@ -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[];
}
-79
View File
@@ -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
-1
View File
@@ -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"}
-2
View File
@@ -1,2 +0,0 @@
export declare class AiModule {
}
-23
View File
@@ -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
-1
View File
@@ -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"}
-34
View File
@@ -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;
}
-240
View File
@@ -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
File diff suppressed because one or more lines are too long
-2
View File
@@ -1,2 +0,0 @@
export declare class AppModule {
}
-75
View File
@@ -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
-1
View File
@@ -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
View File
@@ -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;
}>;
}
-57
View File
@@ -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
View File
@@ -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"}
-2
View File
@@ -1,2 +0,0 @@
export declare class AuthModule {
}
-40
View File
@@ -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
-1
View File
@@ -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"}
-24
View File
@@ -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;
}
-60
View File
@@ -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
View File
@@ -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"}
-2
View File
@@ -1,2 +0,0 @@
export declare const IS_PUBLIC_KEY = "isPublic";
export declare const Public: () => import("@nestjs/common").CustomDecorator<string>;
-8
View File
@@ -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
View File
@@ -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"}
-2
View File
@@ -1,2 +0,0 @@
export declare const ROLES_KEY = "roles";
export declare const Roles: (...roles: string[]) => import("@nestjs/common").CustomDecorator<string>;
-8
View File
@@ -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
View File
@@ -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"}
-4
View File
@@ -1,4 +0,0 @@
export declare class LoginDto {
username: string;
password: string;
}
-25
View File
@@ -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
View File
@@ -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
View File
@@ -1,5 +0,0 @@
export declare class RegisterDto {
username: string;
email: string;
password: string;
}
-30
View File
@@ -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
View File
@@ -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
View File
@@ -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 {};
-48
View File
@@ -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
View File
@@ -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"}
-21
View File
@@ -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 {};
-43
View File
@@ -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
View File
@@ -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"}
-4
View File
@@ -1,4 +0,0 @@
import { CanActivate, ExecutionContext } from '@nestjs/common';
export declare class PremiumOrAdminGuard implements CanActivate {
canActivate(context: ExecutionContext): boolean;
}
-24
View File
@@ -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
View File
@@ -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"}
-7
View File
@@ -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;
}
-39
View File
@@ -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
-1
View File
@@ -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"}
-11
View File
@@ -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[]>;
}
-46
View File
@@ -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
View File
@@ -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"}
-2
View File
@@ -1,2 +0,0 @@
export declare class CategoriesModule {
}
-25
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
-74
View File
@@ -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
View File
@@ -1 +0,0 @@
export declare function downloadAndOptimizeImage(sourceUrl: string, destDir: string): Promise<string>;
-64
View File
@@ -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
View File
@@ -1 +0,0 @@
{"version":3,"file":"download-image.js","sourceRoot":"","sources":["../../../src/common/utils/download-image.ts"],"names":[],"mappings":";;AAkBA,4DA2EC;AA7FD,yBAAyB;AACzB,6BAA6B;AAC7B,+BAA+B;AAC/B,+BAAoC;AAGpC,MAAM,iBAAiB,GAAG,0FAA0F,CAAC;AAY9G,KAAK,UAAU,wBAAwB,CAC5C,SAAiB,EACjB,OAAe;IAEf,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IAC7B,MAAM,kBAAkB,GAAG,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;IAGvE,IAAI,SAAc,CAAC;IACnB,IAAI,CAAC;QACH,SAAS,GAAG,IAAI,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACtC,CAAC;IAGD,IAAI,SAAS,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC;IAEpC,IAAI,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAGD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,MAAM,CAAC,CAAC;IAC7D,IAAI,QAAkB,CAAC;IACvB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE;YAC3C,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,OAAO,EAAE,EAAE,YAAY,EAAE,yCAAyC,EAAE;SACrE,CAAC,CAAC;IACL,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,0BAA0B,CAAC,CAAC;IACrE,CAAC;IAGD,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;IAC/D,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,yBAAyB,WAAW,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;IACjD,IAAI,WAAW,CAAC,UAAU,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAG7C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,IAAA,SAAM,GAAE,MAAM,CAAC;IACnC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAGhD,MAAO,KAAmD,CAAC,WAAW,CAAC;SACpE,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;QACjB,GAAG,EAAE,QAAQ;QACb,kBAAkB,EAAE,IAAI;KACzB,CAAC;SACD,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;SACrB,MAAM,CAAC,UAAU,CAAC,CAAC;IAGtB,OAAO,WAAW,QAAQ,EAAE,CAAC;AAC/B,CAAC"}
-1
View File
@@ -1 +0,0 @@
export declare function normalizeName(value: string): string;
-13
View File
@@ -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
View File
@@ -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
View File
@@ -1 +0,0 @@
export {};
-36
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -1 +0,0 @@
export {};
-56
View File
@@ -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
View File
@@ -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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"}
-14
View File
@@ -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;
-78
View File
@@ -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
View File
@@ -1 +0,0 @@
{"version":3,"file":"units.js","sourceRoot":"","sources":["../../../src/common/utils/units.ts"],"names":[],"mappings":"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"}
-8
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -1,2 +0,0 @@
export declare class HealthModule {
}
-24
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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"}
-4
View File
@@ -1,4 +0,0 @@
export declare class ConsumeInventoryDto {
amountUsed: number;
comment?: string;
}
-27
View File
@@ -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"}
-14
View File
@@ -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;
}
-73
View File
@@ -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"}
-13
View File
@@ -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;
}
-71
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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"}
-2
View File
@@ -1,2 +0,0 @@
export declare class InventoryModule {
}

Some files were not shown because too many files have changed in this diff Show More