├── 1.Intoduction to TS ├── Intro-ts.drawio ├── app.ts ├── dist │ ├── app.js │ └── app.js.map └── tsconfig.json ├── 2.AdvancedTypes ├── dist │ ├── advanced-types.js │ ├── advanced-types.js.map │ ├── api-interface-demo.js │ ├── api-interface-demo.js.map │ ├── app.js │ ├── app.js.map │ ├── interfaces-demo.js │ ├── interfaces-demo.js.map │ └── problem-solving │ │ ├── aggrate-elemnts.js │ │ ├── aggrate-elemnts.js.map │ │ ├── towns.js │ │ └── towns.js.map ├── src │ ├── advanced-types.ts │ ├── api-interface-demo.ts │ ├── app.ts │ ├── interfaces-demo.ts │ └── problem-solving │ │ ├── aggrate-elemnts.ts │ │ └── towns.ts └── tsconfig.json ├── 3.OOP ├── dist │ └── app.js ├── oop.drawio.pdf ├── src │ └── app.ts └── tsconfig.json ├── 4.DPAndGenerics ├── dist │ ├── dp.js │ ├── dp.js.map │ ├── generics.js │ └── generics.js.map ├── src │ ├── dp.ts │ └── generics.ts └── tsconfig.json ├── 5.NamespaceAndModules ├── modules-demo │ ├── dist │ │ ├── index.js │ │ ├── modul-a.js │ │ ├── types │ │ │ └── Person.js │ │ └── utils │ │ │ ├── math.js │ │ │ ├── person.js │ │ │ └── string.js │ ├── src │ │ ├── index.ts │ │ ├── modul-a.ts │ │ ├── types │ │ │ └── Person.ts │ │ └── utils │ │ │ ├── person.ts │ │ │ └── string.ts │ └── tsconfig.json ├── modules.drawio.svg ├── namespaces-demo │ ├── dist │ │ ├── main.d.ts │ │ ├── main.d.ts.map │ │ ├── main.js │ │ ├── student.d.ts │ │ ├── student.d.ts.map │ │ └── student.js │ ├── src │ │ ├── main.ts │ │ └── student.ts │ └── tsconfig.json ├── vite-skeleton │ ├── .gitignore │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── public │ │ └── vite.svg │ ├── src │ │ ├── main.ts │ │ ├── style.css │ │ ├── test.d.ts │ │ ├── typescript.svg │ │ └── vite-env.d.ts │ └── tsconfig.json └── webpack-skeleton │ ├── dist │ ├── bundle.js │ └── index.html │ ├── package-lock.json │ ├── package.json │ ├── src │ └── index.ts │ ├── tsconfig.json │ └── webpack.config.js ├── 6.Decorators ├── accessor-demo.js ├── accessor-demo.ts ├── class-demo.js ├── class-demo.ts ├── factory-demo.js ├── factory-demo.ts ├── method-demo.js ├── method-demo.ts ├── parameter-demo.js ├── parameter-demo.ts ├── property-demo.js ├── property-demo.ts └── tsconfig.json ├── 7.Workshop ├── .gitignore ├── index.html ├── package-lock.json ├── package.json ├── src │ ├── constants.ts │ ├── main.ts │ ├── router.ts │ ├── services │ │ ├── httpService.ts │ │ ├── postService.ts │ │ └── userService.ts │ ├── style.css │ ├── type │ │ ├── common.ts │ │ ├── post.ts │ │ ├── router.ts │ │ └── user.ts │ ├── utils │ │ ├── html.ts │ │ └── http.ts │ ├── views │ │ ├── post.ts │ │ └── user.ts │ └── vite-env.d.ts └── tsconfig.json ├── 8.ExamPrep ├── 1.Calculator │ ├── dist │ │ └── index.js │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── 2.LowestPricesInCity │ ├── dist │ │ └── index.js │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── 3.ClotheMagazine │ ├── dist │ │ ├── Cloth.js │ │ ├── Magazine.js │ │ └── index.js │ ├── src │ │ ├── Cloth.ts │ │ ├── Magazine.ts │ │ └── index.ts │ └── tsconfig.json └── Bonus │ ├── dist │ ├── index.js │ └── index.js.map │ ├── src │ └── index.ts │ └── tsconfig.json └── README.md /1.Intoduction to TS/Intro-ts.drawio: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /1.Intoduction to TS/app.ts: -------------------------------------------------------------------------------- 1 | // Strings 2 | // let str: string = "Hello"; 3 | // str = `Hello, ${123}`; 4 | // // str = true; // ivalid 5 | // console.log(str); 6 | 7 | // Numbers 8 | // let a: number = 11; 9 | // let floatingPoint: number = 5.5; 10 | // let hex: number = 7e4; 11 | // let binary: number = 1001101; 12 | // console.log(a); 13 | 14 | // Booleans 15 | // let hasAuth: boolean = true; 16 | // const isGreater: boolean = 5 > 7; 17 | // const hasTwo = [1, 2, 3, 4].some((e) => e === 2); 18 | // const isBool: boolean = 123; 19 | 20 | // console.log(isBool); 21 | 22 | // Symbols 23 | // let sym1 = Symbol("key"); 24 | // let sym2 = Symbol("key"); 25 | // console.log(sym1 === sym2); 26 | 27 | // Undefined 28 | // let user: Object | undefined; 29 | // let person: Object | null = null; 30 | 31 | // console.log({ user }); 32 | // console.log({ person }); 33 | 34 | // setTimeout(() => { 35 | // user = { name: "user123" }; 36 | // console.log({ user }); 37 | 38 | // person = { name: "Mitko" }; 39 | // console.log({ person }); 40 | // }, 3000); 41 | 42 | // Arrays 43 | // const arr1: number[] = [1, 2, 3, 4]; 44 | // const arr2: Array = [2, 3, 4, 5]; 45 | // const arr3: string[] = ["Hello", " its ", " me!"]; 46 | // const arr4: boolean[] = [true, true, false, true]; 47 | // const arr5: any[] = [12, "Google", true, { name: "person123" }]; 48 | // console.log(arr5); 49 | 50 | // // Tuples key value 51 | // let tuple1: [number, string] = [123, "Hi!"]; 52 | // let tuple2: [boolean, object] = [true, { name: "Mitko" }]; 53 | // let tupleObjKey: [string, object] = ["user", { name: "User123" }]; 54 | // console.log(tuple2); 55 | 56 | // Enum 57 | // M = 11, 58 | // T = "Hello", 59 | // W = "x123", 60 | // Th = "chetvurtuk", 61 | // F = "petuk", 62 | // enum DaysOfWorkWeek { 63 | // Monday = 1, 64 | // T, 65 | // W, 66 | // Th, 67 | // F, 68 | // } 69 | 70 | // const currentDay = 1; 71 | 72 | // if (currentDay === DaysOfWorkWeek.Monday) { 73 | // console.log("Is Monday"); 74 | // } 75 | 76 | // Any, Unknown -> "type safe" 77 | // let a: unknown; 78 | // a = 5; 79 | // a = { name: "Pesho" }; 80 | // a = true; 81 | // a = ["String"]; 82 | // console.log(a); 83 | 84 | // Void 85 | // function myPrint(input: string): void { 86 | // console.log(input); 87 | // // doesn't has return value! 88 | // } 89 | 90 | // function myPrint2(input: string): string { 91 | // return `[from print function]: ${input}`; 92 | // } 93 | 94 | // myPrint("Hello!"); 95 | // console.log(myPrint2("Hello!")); 96 | 97 | // Optional params 98 | // function optionalParams(param1?: number, param2?: string): void { 99 | // console.log({ param1, param2 }); 100 | // } 101 | // // from left to right -> 102 | // optionalParams(1); 103 | 104 | // Default arguments 105 | // function optionalParams2(param1 = 5, param2 = "Hi from default"): void { 106 | // console.log({ param1, param2 }); 107 | // } 108 | // // from left to right -> 109 | // optionalParams2(123, "hai!"); 110 | 111 | // // Return types in Functions 112 | // const getNum = (): number => 5; 113 | // const getNum2 = (): string => { 114 | // return "hi!"; 115 | // }; 116 | 117 | // const getNum3 = function (): boolean { 118 | // return true; 119 | // }; 120 | 121 | // function getNum4(): undefined { 122 | // return; 123 | // } 124 | 125 | // const getNum5: () => number = () => { 126 | // return 5; 127 | // }; 128 | 129 | // Never 130 | // let x = (): never => { 131 | // while (true) {} 132 | // }; 133 | // console.log(x); 134 | 135 | // Debugging 136 | function test() { 137 | let arr: number[] = [1, 2, 3, 4, 5]; 138 | arr.forEach((e) => { 139 | if (e === 2) { 140 | console.log("'e' is 2"); 141 | } 142 | console.log(e); 143 | }); 144 | } 145 | 146 | test(); 147 | -------------------------------------------------------------------------------- /1.Intoduction to TS/dist/app.js: -------------------------------------------------------------------------------- 1 | // Strings 2 | // let str: string = "Hello"; 3 | // str = `Hello, ${123}`; 4 | // // str = true; // ivalid 5 | // console.log(str); 6 | // Numbers 7 | // let a: number = 11; 8 | // let floatingPoint: number = 5.5; 9 | // let hex: number = 7e4; 10 | // let binary: number = 1001101; 11 | // console.log(a); 12 | // Booleans 13 | // let hasAuth: boolean = true; 14 | // const isGreater: boolean = 5 > 7; 15 | // const hasTwo = [1, 2, 3, 4].some((e) => e === 2); 16 | // const isBool: boolean = 123; 17 | // console.log(isBool); 18 | // Symbols 19 | // let sym1 = Symbol("key"); 20 | // let sym2 = Symbol("key"); 21 | // console.log(sym1 === sym2); 22 | // Undefined 23 | // let user: Object | undefined; 24 | // let person: Object | null = null; 25 | // console.log({ user }); 26 | // console.log({ person }); 27 | // setTimeout(() => { 28 | // user = { name: "user123" }; 29 | // console.log({ user }); 30 | // person = { name: "Mitko" }; 31 | // console.log({ person }); 32 | // }, 3000); 33 | // Arrays 34 | // const arr1: number[] = [1, 2, 3, 4]; 35 | // const arr2: Array = [2, 3, 4, 5]; 36 | // const arr3: string[] = ["Hello", " its ", " me!"]; 37 | // const arr4: boolean[] = [true, true, false, true]; 38 | // const arr5: any[] = [12, "Google", true, { name: "person123" }]; 39 | // console.log(arr5); 40 | // // Tuples key value 41 | // let tuple1: [number, string] = [123, "Hi!"]; 42 | // let tuple2: [boolean, object] = [true, { name: "Mitko" }]; 43 | // let tupleObjKey: [string, object] = ["user", { name: "User123" }]; 44 | // console.log(tuple2); 45 | // Enum 46 | // M = 11, 47 | // T = "Hello", 48 | // W = "x123", 49 | // Th = "chetvurtuk", 50 | // F = "petuk", 51 | // enum DaysOfWorkWeek { 52 | // Monday = 1, 53 | // T, 54 | // W, 55 | // Th, 56 | // F, 57 | // } 58 | // const currentDay = 1; 59 | // if (currentDay === DaysOfWorkWeek.Monday) { 60 | // console.log("Is Monday"); 61 | // } 62 | // Any, Unknown -> "type safe" 63 | // let a: unknown; 64 | // a = 5; 65 | // a = { name: "Pesho" }; 66 | // a = true; 67 | // a = ["String"]; 68 | // console.log(a); 69 | // Void 70 | // function myPrint(input: string): void { 71 | // console.log(input); 72 | // // doesn't has return value! 73 | // } 74 | // function myPrint2(input: string): string { 75 | // return `[from print function]: ${input}`; 76 | // } 77 | // myPrint("Hello!"); 78 | // console.log(myPrint2("Hello!")); 79 | // Optional params 80 | // function optionalParams(param1?: number, param2?: string): void { 81 | // console.log({ param1, param2 }); 82 | // } 83 | // // from left to right -> 84 | // optionalParams(1); 85 | // Default arguments 86 | // function optionalParams2(param1 = 5, param2 = "Hi from default"): void { 87 | // console.log({ param1, param2 }); 88 | // } 89 | // // from left to right -> 90 | // optionalParams2(123, "hai!"); 91 | // // Return types in Functions 92 | // const getNum = (): number => 5; 93 | // const getNum2 = (): string => { 94 | // return "hi!"; 95 | // }; 96 | // const getNum3 = function (): boolean { 97 | // return true; 98 | // }; 99 | // function getNum4(): undefined { 100 | // return; 101 | // } 102 | // const getNum5: () => number = () => { 103 | // return 5; 104 | // }; 105 | // Never 106 | // let x = (): never => { 107 | // while (true) {} 108 | // }; 109 | // console.log(x); 110 | // Debugging 111 | function test() { 112 | let arr = [1, 2, 3, 4, 5]; 113 | arr.forEach((e) => { 114 | if (e === 2) { 115 | console.log("'e' is 2"); 116 | } 117 | console.log(e); 118 | }); 119 | } 120 | test(); 121 | //# sourceMappingURL=app.js.map -------------------------------------------------------------------------------- /1.Intoduction to TS/dist/app.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"app.js","sourceRoot":"","sources":["../app.ts"],"names":[],"mappings":"AAAA,UAAU;AACV,6BAA6B;AAC7B,yBAAyB;AACzB,2BAA2B;AAC3B,oBAAoB;AAEpB,UAAU;AACV,sBAAsB;AACtB,mCAAmC;AACnC,yBAAyB;AACzB,gCAAgC;AAChC,kBAAkB;AAElB,WAAW;AACX,+BAA+B;AAC/B,oCAAoC;AACpC,oDAAoD;AACpD,+BAA+B;AAE/B,uBAAuB;AAEvB,UAAU;AACV,4BAA4B;AAC5B,4BAA4B;AAC5B,8BAA8B;AAE9B,YAAY;AACZ,gCAAgC;AAChC,oCAAoC;AAEpC,yBAAyB;AACzB,2BAA2B;AAE3B,qBAAqB;AACrB,gCAAgC;AAChC,2BAA2B;AAE3B,gCAAgC;AAChC,6BAA6B;AAC7B,YAAY;AAEZ,SAAS;AACT,uCAAuC;AACvC,4CAA4C;AAC5C,qDAAqD;AACrD,qDAAqD;AACrD,mEAAmE;AACnE,qBAAqB;AAErB,8BAA8B;AAC9B,+CAA+C;AAC/C,6DAA6D;AAC7D,qEAAqE;AACrE,uBAAuB;AAEvB,OAAO;AACP,YAAY;AACZ,iBAAiB;AACjB,gBAAgB;AAChB,uBAAuB;AACvB,iBAAiB;AACjB,wBAAwB;AACxB,gBAAgB;AAChB,OAAO;AACP,OAAO;AACP,QAAQ;AACR,OAAO;AACP,IAAI;AAEJ,wBAAwB;AAExB,8CAA8C;AAC9C,8BAA8B;AAC9B,IAAI;AAEJ,8BAA8B;AAC9B,kBAAkB;AAClB,SAAS;AACT,yBAAyB;AACzB,YAAY;AACZ,kBAAkB;AAClB,kBAAkB;AAElB,OAAO;AACP,0CAA0C;AAC1C,wBAAwB;AACxB,iCAAiC;AACjC,IAAI;AAEJ,6CAA6C;AAC7C,8CAA8C;AAC9C,IAAI;AAEJ,qBAAqB;AACrB,mCAAmC;AAEnC,kBAAkB;AAClB,oEAAoE;AACpE,qCAAqC;AACrC,IAAI;AACJ,4BAA4B;AAC5B,qBAAqB;AAErB,oBAAoB;AACpB,2EAA2E;AAC3E,qCAAqC;AACrC,IAAI;AACJ,4BAA4B;AAC5B,gCAAgC;AAEhC,+BAA+B;AAC/B,kCAAkC;AAClC,kCAAkC;AAClC,kBAAkB;AAClB,KAAK;AAEL,yCAAyC;AACzC,iBAAiB;AACjB,KAAK;AAEL,kCAAkC;AAClC,YAAY;AACZ,IAAI;AAEJ,wCAAwC;AACxC,cAAc;AACd,KAAK;AAEL,QAAQ;AACR,yBAAyB;AACzB,oBAAoB;AACpB,KAAK;AACL,kBAAkB;AAElB,YAAY;AACZ,SAAS,IAAI;IACX,IAAI,GAAG,GAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACpC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;QAChB,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACZ,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC1B,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,IAAI,EAAE,CAAC"} -------------------------------------------------------------------------------- /1.Intoduction to TS/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2022", 4 | "sourceMap": true, 5 | "outDir": "./dist" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /2.AdvancedTypes/dist/advanced-types.js: -------------------------------------------------------------------------------- 1 | // UNION TYPES 2 | // let x: string | undefined; 3 | // if (x?.length) { 4 | // console.log("Invoked code if is not undefined"); 5 | // } 6 | // setTimeout(() => { 7 | // x = "Test"; 8 | // console.log(x); 9 | // }, 3000); 10 | // const y: string | string[] = ["Test", "Test1", "Test123"]; 11 | // type Y2 = string | string[] | number | number[]; 12 | // const y2: Y2 = [123]; 13 | // let msg: string = ""; 14 | // msg = "Hello, I am message!"; 15 | // let person: object | null = null; 16 | // setTimeout(() => { 17 | // person = { name: "Gosho", city: "Pernik" }; 18 | // console.log(person); 19 | // }, 1000); 20 | // type Person = { 21 | // name: string; 22 | // city?: string; 23 | // age?: number; 24 | // }; 25 | // function toResetData(param: number | Person): void { 26 | // if (typeof param === "number") { 27 | // person = null; 28 | // } else { 29 | // person = param; 30 | // } 31 | // } 32 | // const x1: object = []; // {} , [] 33 | // const x2: Object = true; // * 34 | // toResetData({ name: "" }); 35 | // console.log(person); 36 | // INTERSECTION TYPES 37 | // type User = { 38 | // username: string; 39 | // email?: string; 40 | // createdAt?: number; 41 | // }; 42 | // const user: User = { 43 | // username: "petko123", 44 | // email: "petko123@gmail.com", 45 | // createdAt: 123213123, 46 | // }; 47 | // type Animal = { 48 | // furColor?: string; 49 | // legsNumber: number; 50 | // type: string; 51 | // }; 52 | // const animal: Animal = { legsNumber: 4, type: "mammal", furColor: "yellow" }; 53 | // type AnimalUserType = Animal & User; 54 | // type AnimalUserType = { 55 | // // Animal 56 | // furColor?: string; 57 | // legsNumber: number; 58 | // type: string; 59 | // // User 60 | // username: string; 61 | // email?: string; 62 | // createdAt?: number; 63 | // }; 64 | // const animalUser: AnimalUserType = { 65 | // type: "fish", 66 | // legsNumber: 0, 67 | // username: "fishman123", 68 | // }; 69 | // console.log(animalUser); 70 | // type Bird = { 71 | // featherColor: string; 72 | // }; 73 | // type Mammal = { 74 | // furColor: string; 75 | // }; 76 | // type MammalOrBird = Mammal | Bird; 77 | // const mammalOrBird: MammalOrBird = { featherColor: "golden" }; 78 | // console.log(mammalOrBird); 79 | // Literal Types 80 | // let apiCallStatus: "successful" | "failed"; 81 | // apiCallStatus = "successful"; 82 | // apiCallStatus = "failed"; 83 | // console.log(apiCallStatus); 84 | // let errorStatus: 200 | 302; 85 | // errorStatus = 200; 86 | // console.log({ errorStatus }); 87 | // Type Aliases 88 | // type Age = number | string; 89 | // type Person = { 90 | // name: string; 91 | // age: Age; 92 | // }; 93 | // const person: Person = { name: "mitko", age: 0 }; 94 | // const addPersonsAge = (age: Age) => { 95 | // person.age = age; 96 | // }; 97 | // addPersonsAge("123"); 98 | // console.log(person); 99 | // // "keyof" 100 | // type Point = { 101 | // x: number; 102 | // y: number; 103 | // }; 104 | // type PointKeyType = keyof Point; 105 | // const point = { x: 1000, y: -300 }; 106 | // // ["123", "Text", "Thanks"].forEach((key: string) => { 107 | // // // key => x | y 108 | // // console.log(point[key as keyof Point]); 109 | // // }); 110 | // type Colors = { red: string; blue: string }; 111 | // type ColorsKey = keyof Colors; 112 | // const color: Colors = { red: "cherven", blue: "sin" }; 113 | // Recursive Types 114 | // type TreeNode1 = { 115 | // left: TreeNode1; 116 | // right: TreeNode1; 117 | // value: number; 118 | // }; 119 | // interface TreeNode2 { 120 | // left: TreeNode2; 121 | // right: TreeNode2; 122 | // value: number; 123 | // } 124 | //# sourceMappingURL=advanced-types.js.map -------------------------------------------------------------------------------- /2.AdvancedTypes/dist/advanced-types.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"advanced-types.js","sourceRoot":"","sources":["../src/advanced-types.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,6BAA6B;AAE7B,mBAAmB;AACnB,qDAAqD;AACrD,IAAI;AAEJ,qBAAqB;AACrB,gBAAgB;AAChB,oBAAoB;AACpB,YAAY;AAEZ,6DAA6D;AAE7D,mDAAmD;AACnD,wBAAwB;AAExB,wBAAwB;AAExB,gCAAgC;AAEhC,oCAAoC;AAEpC,qBAAqB;AACrB,gDAAgD;AAChD,yBAAyB;AACzB,YAAY;AAEZ,kBAAkB;AAClB,kBAAkB;AAClB,mBAAmB;AACnB,kBAAkB;AAClB,KAAK;AAEL,uDAAuD;AACvD,qCAAqC;AACrC,qBAAqB;AACrB,aAAa;AACb,sBAAsB;AACtB,MAAM;AACN,IAAI;AAEJ,oCAAoC;AACpC,gCAAgC;AAEhC,6BAA6B;AAC7B,uBAAuB;AAEvB,qBAAqB;AACrB,gBAAgB;AAChB,sBAAsB;AACtB,oBAAoB;AACpB,wBAAwB;AACxB,KAAK;AACL,uBAAuB;AACvB,0BAA0B;AAC1B,iCAAiC;AACjC,0BAA0B;AAC1B,KAAK;AAEL,kBAAkB;AAClB,uBAAuB;AACvB,wBAAwB;AACxB,kBAAkB;AAClB,KAAK;AACL,gFAAgF;AAEhF,uCAAuC;AACvC,0BAA0B;AAC1B,cAAc;AACd,uBAAuB;AACvB,wBAAwB;AACxB,kBAAkB;AAClB,YAAY;AACZ,sBAAsB;AACtB,oBAAoB;AACpB,wBAAwB;AACxB,KAAK;AACL,uCAAuC;AACvC,kBAAkB;AAClB,mBAAmB;AACnB,4BAA4B;AAC5B,KAAK;AACL,2BAA2B;AAE3B,gBAAgB;AAChB,0BAA0B;AAC1B,KAAK;AAEL,kBAAkB;AAClB,sBAAsB;AACtB,KAAK;AAEL,qCAAqC;AAErC,iEAAiE;AACjE,6BAA6B;AAE7B,gBAAgB;AAChB,8CAA8C;AAC9C,gCAAgC;AAChC,4BAA4B;AAC5B,8BAA8B;AAE9B,8BAA8B;AAC9B,qBAAqB;AACrB,gCAAgC;AAEhC,eAAe;AACf,8BAA8B;AAE9B,kBAAkB;AAClB,kBAAkB;AAClB,cAAc;AACd,KAAK;AAEL,oDAAoD;AAEpD,wCAAwC;AACxC,sBAAsB;AACtB,KAAK;AAEL,wBAAwB;AACxB,uBAAuB;AAEvB,aAAa;AACb,iBAAiB;AACjB,eAAe;AACf,eAAe;AACf,KAAK;AAEL,mCAAmC;AACnC,sCAAsC;AAEtC,0DAA0D;AAC1D,0BAA0B;AAC1B,+CAA+C;AAC/C,SAAS;AAET,+CAA+C;AAC/C,iCAAiC;AACjC,yDAAyD;AAEzD,kBAAkB;AAClB,qBAAqB;AACrB,qBAAqB;AACrB,sBAAsB;AACtB,mBAAmB;AACnB,KAAK;AAEL,wBAAwB;AACxB,qBAAqB;AACrB,sBAAsB;AACtB,mBAAmB;AACnB,IAAI"} -------------------------------------------------------------------------------- /2.AdvancedTypes/dist/api-interface-demo.js: -------------------------------------------------------------------------------- 1 | const API_URL = "https://jsonplaceholder.typicode.com/users"; 2 | const getUsers = () => { 3 | fetch(API_URL, { method: "GET" }) 4 | .then((res) => res.json()) 5 | .then((users) => { 6 | users.forEach((user) => { 7 | console.log(user.username + " -> " + user.company.name); 8 | }); 9 | }) 10 | .catch((err) => console.log(`Err: ${err}`)); 11 | }; 12 | getUsers(); 13 | //# sourceMappingURL=api-interface-demo.js.map -------------------------------------------------------------------------------- /2.AdvancedTypes/dist/api-interface-demo.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"api-interface-demo.js","sourceRoot":"","sources":["../src/api-interface-demo.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAW,4CAA4C,CAAC;AAgCrE,MAAM,QAAQ,GAAG,GAAS,EAAE;IAC1B,KAAK,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;SAC9B,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;SACzB,IAAI,CAAC,CAAC,KAAa,EAAE,EAAE;QACtB,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YACrB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,GAAG,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,EAAE,CAAC,CAAC,CAAC;AAChD,CAAC,CAAC;AAEF,QAAQ,EAAE,CAAC"} -------------------------------------------------------------------------------- /2.AdvancedTypes/dist/app.js: -------------------------------------------------------------------------------- 1 | var WorkWeekDays; 2 | (function (WorkWeekDays) { 3 | WorkWeekDays[WorkWeekDays["Monday"] = 1] = "Monday"; 4 | WorkWeekDays[WorkWeekDays["Tuesday"] = 2] = "Tuesday"; 5 | WorkWeekDays[WorkWeekDays["Wedneday"] = 3] = "Wedneday"; 6 | WorkWeekDays[WorkWeekDays["Thursday"] = 4] = "Thursday"; 7 | WorkWeekDays[WorkWeekDays["Friday"] = 5] = "Friday"; 8 | })(WorkWeekDays || (WorkWeekDays = {})); 9 | console.log(WorkWeekDays["Monday"]); 10 | console.log(WorkWeekDays["1"]); 11 | console.log(WorkWeekDays.Monday); 12 | console.log(WorkWeekDays); 13 | // console.log(WorkWeekDays.Tuesday); 14 | // console.log(WorkWeekDays.Wedneday); 15 | // console.log(WorkWeekDays.Thursday); 16 | // console.log(WorkWeekDays.Friday); 17 | // type SimpleUser = { 18 | // id: number; 19 | // name: string; 20 | // username: string; 21 | // email: string; 22 | // address: string; 23 | // phone: string; 24 | // website: string; 25 | // company: string; 26 | // }; 27 | // type KeyOfSimpleUser = keyof SimpleUser; 28 | // const simpleUser = { 29 | // id: 1, 30 | // name: "Leanne Graham", 31 | // username: "Bret", 32 | // email: "Sincere@april.biz", 33 | // address: "asdasdasdas", 34 | // phone: "1-770-736-8031 x56442", 35 | // website: "hildegard.org", 36 | // company: "harness real-time e-markets", 37 | // }; 38 | // Object.keys(simpleUser).forEach((key: KeyOfSimpleUser) => { 39 | // console.log(simpleUser[key]); 40 | // }); 41 | //# sourceMappingURL=app.js.map -------------------------------------------------------------------------------- /2.AdvancedTypes/dist/app.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,IAAK,YAMJ;AAND,WAAK,YAAY;IACf,mDAAU,CAAA;IACV,qDAAO,CAAA;IACP,uDAAQ,CAAA;IACR,uDAAQ,CAAA;IACR,mDAAM,CAAA;AACR,CAAC,EANI,YAAY,KAAZ,YAAY,QAMhB;AAED,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;AACpC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/B,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;AACjC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;AAC1B,qCAAqC;AACrC,sCAAsC;AACtC,sCAAsC;AACtC,oCAAoC;AAEpC,sBAAsB;AACtB,gBAAgB;AAChB,kBAAkB;AAClB,sBAAsB;AACtB,mBAAmB;AACnB,qBAAqB;AACrB,mBAAmB;AACnB,qBAAqB;AACrB,qBAAqB;AACrB,KAAK;AAEL,2CAA2C;AAE3C,uBAAuB;AACvB,WAAW;AACX,2BAA2B;AAC3B,sBAAsB;AACtB,gCAAgC;AAChC,4BAA4B;AAC5B,oCAAoC;AACpC,8BAA8B;AAC9B,4CAA4C;AAC5C,KAAK;AAEL,8DAA8D;AAC9D,kCAAkC;AAClC,MAAM"} -------------------------------------------------------------------------------- /2.AdvancedTypes/dist/interfaces-demo.js: -------------------------------------------------------------------------------- 1 | // interface User { 2 | // githubToken: string; 3 | // } 4 | // interface Admin extends User { 5 | // specialRights: boolean; 6 | // // githubToken: string; 7 | // } 8 | // const user: Admin = { specialRights: true, githubToken: "kasjhdkashkdjsah" }; 9 | // type Admin2 = { 10 | // specialRights: boolean; 11 | // githubToken: string; 12 | // }; 13 | // class Person implements Admin2 { 14 | // specialRights = true; 15 | // githubToken = "kasjhdkashkdjsah"; 16 | // } 17 | // interface PersonDetails { 18 | // firstName: string; 19 | // address: string; 20 | // age: number; 21 | // } 22 | // class Person implements PersonDetails { 23 | // firstName = ""; 24 | // address = ""; 25 | // age = 0; 26 | // } 27 | // const person: PersonDetails = { 28 | // firstName: "", 29 | // address: "", 30 | // age: 0, 31 | // }; 32 | // interface A { 33 | // a: number; 34 | // } 35 | // interface B extends A { 36 | // b: number; 37 | // } 38 | // // a, b 39 | // type C = { 40 | // c: number; 41 | // }; 42 | // type D = { 43 | // d: number; 44 | // } & C; 45 | // // c, d 46 | // Delcaration merging 47 | // interface Animal { 48 | // name: string; 49 | // } 50 | // interface Animal { 51 | // speak: () => void; 52 | // } 53 | // const animal: Animal = { 54 | // name: "Gosho", 55 | // speak: () => { 56 | // console.log("mewww"); 57 | // }, 58 | // }; 59 | // interface GetNameFunction { 60 | // (param1: number, param2: string): string; 61 | // } 62 | // const getName: GetNameFunction = (param1: number, param2: string) => { 63 | // return `${param1} ${param2}`; 64 | // }; 65 | //# sourceMappingURL=interfaces-demo.js.map -------------------------------------------------------------------------------- /2.AdvancedTypes/dist/interfaces-demo.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"interfaces-demo.js","sourceRoot":"","sources":["../src/interfaces-demo.ts"],"names":[],"mappings":"AAAA,mBAAmB;AACnB,yBAAyB;AACzB,IAAI;AAEJ,iCAAiC;AACjC,4BAA4B;AAC5B,4BAA4B;AAC5B,IAAI;AAEJ,gFAAgF;AAEhF,kBAAkB;AAClB,4BAA4B;AAC5B,yBAAyB;AACzB,KAAK;AAEL,mCAAmC;AACnC,0BAA0B;AAC1B,sCAAsC;AACtC,IAAI;AAEJ,4BAA4B;AAC5B,uBAAuB;AACvB,qBAAqB;AACrB,iBAAiB;AACjB,IAAI;AAEJ,0CAA0C;AAC1C,oBAAoB;AACpB,kBAAkB;AAClB,aAAa;AACb,IAAI;AAEJ,kCAAkC;AAClC,mBAAmB;AACnB,iBAAiB;AACjB,YAAY;AACZ,KAAK;AAEL,gBAAgB;AAChB,eAAe;AACf,IAAI;AAEJ,0BAA0B;AAC1B,eAAe;AACf,IAAI;AACJ,UAAU;AAEV,aAAa;AACb,eAAe;AACf,KAAK;AAEL,aAAa;AACb,eAAe;AACf,SAAS;AAET,UAAU;AAEV,sBAAsB;AACtB,qBAAqB;AACrB,kBAAkB;AAClB,IAAI;AAEJ,qBAAqB;AACrB,uBAAuB;AACvB,IAAI;AAEJ,2BAA2B;AAC3B,mBAAmB;AACnB,mBAAmB;AACnB,4BAA4B;AAC5B,OAAO;AACP,KAAK;AAEL,8BAA8B;AAC9B,8CAA8C;AAC9C,IAAI;AAEJ,yEAAyE;AACzE,kCAAkC;AAClC,KAAK"} -------------------------------------------------------------------------------- /2.AdvancedTypes/dist/problem-solving/aggrate-elemnts.js: -------------------------------------------------------------------------------- 1 | const sumNumbers = (numbers, inversed = false) => { 2 | let sum = 0; 3 | numbers.forEach((num) => { 4 | const numToSum = inversed ? 1 / num : num; 5 | sum += numToSum; 6 | // if (inversed) { 7 | // sum += 1 / num; 8 | // } else { 9 | // sum += num; 10 | // } 11 | }); 12 | return sum; 13 | }; 14 | const concatNumbers = (numbers) => { 15 | return numbers.join(""); 16 | }; 17 | const aggregateElements = (numbers) => { 18 | // sum 19 | const sum = sumNumbers(numbers); 20 | // sum inversed 21 | const sumInversed = sumNumbers(numbers, true); 22 | // concat 23 | const concatedNums = concatNumbers(numbers); 24 | // Output 25 | console.log(sum); 26 | console.log(sumInversed); 27 | console.log(concatedNums); 28 | }; 29 | // Input: [1, 2, 3] 30 | // Output: 31 | // 6 32 | // 1.8333333333333333 33 | // 123 34 | // aggregateElements([1, 2, 3]); 35 | // Input: [2, 4, 8, 16] 36 | // Output: 37 | // 30 38 | // 0.9375 39 | // 24816 40 | aggregateElements([2, 4, 8, 16]); 41 | //# sourceMappingURL=aggrate-elemnts.js.map -------------------------------------------------------------------------------- /2.AdvancedTypes/dist/problem-solving/aggrate-elemnts.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"aggrate-elemnts.js","sourceRoot":"","sources":["../../src/problem-solving/aggrate-elemnts.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,GAAG,CAAC,OAAiB,EAAE,QAAQ,GAAG,KAAK,EAAU,EAAE;IACjE,IAAI,GAAG,GAAW,CAAC,CAAC;IAEpB,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QACtB,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAC1C,GAAG,IAAI,QAAQ,CAAC;QAChB,kBAAkB;QAClB,oBAAoB;QACpB,WAAW;QACX,gBAAgB;QAChB,IAAI;IACN,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,OAAiB,EAAU,EAAE;IAClD,OAAO,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC1B,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,OAAiB,EAAQ,EAAE;IACpD,MAAM;IACN,MAAM,GAAG,GAAW,UAAU,CAAC,OAAO,CAAC,CAAC;IAExC,eAAe;IACf,MAAM,WAAW,GAAW,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAEtD,SAAS;IACT,MAAM,YAAY,GAAW,aAAa,CAAC,OAAO,CAAC,CAAC;IAEpD,SAAS;IACT,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjB,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACzB,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;AAC5B,CAAC,CAAC;AACF,mBAAmB;AACnB,UAAU;AACV,KAAK;AACL,sBAAsB;AACtB,OAAO;AACP,gCAAgC;AAEhC,uBAAuB;AACvB,UAAU;AACV,OAAO;AACP,WAAW;AACX,UAAU;AACV,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC"} -------------------------------------------------------------------------------- /2.AdvancedTypes/dist/problem-solving/towns.js: -------------------------------------------------------------------------------- 1 | // Input: 2 | // ["Sofia | 42.696552 | 23.32601", "Beijing | 39.913818 | 116.363625"]; 3 | const solve = (tableRows) => { 4 | // 5 | return []; 6 | }; 7 | //# sourceMappingURL=towns.js.map -------------------------------------------------------------------------------- /2.AdvancedTypes/dist/problem-solving/towns.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"towns.js","sourceRoot":"","sources":["../../src/problem-solving/towns.ts"],"names":[],"mappings":"AAAA,SAAS;AACT,yEAAyE;AAYzE,MAAM,KAAK,GAAG,CAAC,SAAmB,EAAU,EAAE;IAC5C,EAAE;IACF,OAAO,EAAE,CAAC;AACZ,CAAC,CAAC"} -------------------------------------------------------------------------------- /2.AdvancedTypes/src/advanced-types.ts: -------------------------------------------------------------------------------- 1 | // UNION TYPES 2 | // let x: string | undefined; 3 | 4 | // if (x?.length) { 5 | // console.log("Invoked code if is not undefined"); 6 | // } 7 | 8 | // setTimeout(() => { 9 | // x = "Test"; 10 | // console.log(x); 11 | // }, 3000); 12 | 13 | // const y: string | string[] = ["Test", "Test1", "Test123"]; 14 | 15 | // type Y2 = string | string[] | number | number[]; 16 | // const y2: Y2 = [123]; 17 | 18 | // let msg: string = ""; 19 | 20 | // msg = "Hello, I am message!"; 21 | 22 | // let person: object | null = null; 23 | 24 | // setTimeout(() => { 25 | // person = { name: "Gosho", city: "Pernik" }; 26 | // console.log(person); 27 | // }, 1000); 28 | 29 | // type Person = { 30 | // name: string; 31 | // city?: string; 32 | // age?: number; 33 | // }; 34 | 35 | // function toResetData(param: number | Person): void { 36 | // if (typeof param === "number") { 37 | // person = null; 38 | // } else { 39 | // person = param; 40 | // } 41 | // } 42 | 43 | // const x1: object = []; // {} , [] 44 | // const x2: Object = true; // * 45 | 46 | // toResetData({ name: "" }); 47 | // console.log(person); 48 | 49 | // INTERSECTION TYPES 50 | // type User = { 51 | // username: string; 52 | // email?: string; 53 | // createdAt?: number; 54 | // }; 55 | // const user: User = { 56 | // username: "petko123", 57 | // email: "petko123@gmail.com", 58 | // createdAt: 123213123, 59 | // }; 60 | 61 | // type Animal = { 62 | // furColor?: string; 63 | // legsNumber: number; 64 | // type: string; 65 | // }; 66 | // const animal: Animal = { legsNumber: 4, type: "mammal", furColor: "yellow" }; 67 | 68 | // type AnimalUserType = Animal & User; 69 | // type AnimalUserType = { 70 | // // Animal 71 | // furColor?: string; 72 | // legsNumber: number; 73 | // type: string; 74 | // // User 75 | // username: string; 76 | // email?: string; 77 | // createdAt?: number; 78 | // }; 79 | // const animalUser: AnimalUserType = { 80 | // type: "fish", 81 | // legsNumber: 0, 82 | // username: "fishman123", 83 | // }; 84 | // console.log(animalUser); 85 | 86 | // type Bird = { 87 | // featherColor: string; 88 | // }; 89 | 90 | // type Mammal = { 91 | // furColor: string; 92 | // }; 93 | 94 | // type MammalOrBird = Mammal | Bird; 95 | 96 | // const mammalOrBird: MammalOrBird = { featherColor: "golden" }; 97 | // console.log(mammalOrBird); 98 | 99 | // Literal Types 100 | // let apiCallStatus: "successful" | "failed"; 101 | // apiCallStatus = "successful"; 102 | // apiCallStatus = "failed"; 103 | // console.log(apiCallStatus); 104 | 105 | // let errorStatus: 200 | 302; 106 | // errorStatus = 200; 107 | // console.log({ errorStatus }); 108 | 109 | // Type Aliases 110 | // type Age = number | string; 111 | 112 | // type Person = { 113 | // name: string; 114 | // age: Age; 115 | // }; 116 | 117 | // const person: Person = { name: "mitko", age: 0 }; 118 | 119 | // const addPersonsAge = (age: Age) => { 120 | // person.age = age; 121 | // }; 122 | 123 | // addPersonsAge("123"); 124 | // console.log(person); 125 | 126 | // // "keyof" 127 | // type Point = { 128 | // x: number; 129 | // y: number; 130 | // }; 131 | 132 | // type PointKeyType = keyof Point; 133 | // const point = { x: 1000, y: -300 }; 134 | 135 | // // ["123", "Text", "Thanks"].forEach((key: string) => { 136 | // // // key => x | y 137 | // // console.log(point[key as keyof Point]); 138 | // // }); 139 | 140 | // type Colors = { red: string; blue: string }; 141 | // type ColorsKey = keyof Colors; 142 | // const color: Colors = { red: "cherven", blue: "sin" }; 143 | 144 | // Recursive Types 145 | // type TreeNode1 = { 146 | // left: TreeNode1; 147 | // right: TreeNode1; 148 | // value: number; 149 | // }; 150 | 151 | // interface TreeNode2 { 152 | // left: TreeNode2; 153 | // right: TreeNode2; 154 | // value: number; 155 | // } 156 | -------------------------------------------------------------------------------- /2.AdvancedTypes/src/api-interface-demo.ts: -------------------------------------------------------------------------------- 1 | const API_URL: string = "https://jsonplaceholder.typicode.com/users"; 2 | 3 | type Geo = { 4 | lat: string; 5 | lng: string; 6 | }; 7 | 8 | type Address = { 9 | street: string; 10 | suite: string; 11 | city: string; 12 | zipcode: string; 13 | geo: Geo; 14 | }; 15 | 16 | type Company = { 17 | name: string; 18 | catchPhrase: string; 19 | bs: string; 20 | }; 21 | 22 | interface User { 23 | id: number; 24 | name: string; 25 | username: string; 26 | email: string; 27 | address: Address; 28 | phone: string; 29 | website: string; 30 | company: Company; 31 | } 32 | 33 | const getUsers = (): void => { 34 | fetch(API_URL, { method: "GET" }) 35 | .then((res) => res.json()) 36 | .then((users: User[]) => { 37 | users.forEach((user) => { 38 | console.log(user.username + " -> " + user.company.name); 39 | }); 40 | }) 41 | .catch((err) => console.log(`Err: ${err}`)); 42 | }; 43 | 44 | getUsers(); 45 | -------------------------------------------------------------------------------- /2.AdvancedTypes/src/app.ts: -------------------------------------------------------------------------------- 1 | enum WorkWeekDays { 2 | Monday = 1, 3 | Tuesday, 4 | Wedneday, 5 | Thursday, 6 | Friday, 7 | } 8 | 9 | console.log(WorkWeekDays["Monday"]); 10 | console.log(WorkWeekDays["1"]); 11 | console.log(WorkWeekDays.Monday); 12 | // console.log(WorkWeekDays.Tuesday); 13 | // console.log(WorkWeekDays.Wedneday); 14 | // console.log(WorkWeekDays.Thursday); 15 | // console.log(WorkWeekDays.Friday); 16 | 17 | // type SimpleUser = { 18 | // id: number; 19 | // name: string; 20 | // username: string; 21 | // email: string; 22 | // address: string; 23 | // phone: string; 24 | // website: string; 25 | // company: string; 26 | // }; 27 | 28 | // type KeyOfSimpleUser = keyof SimpleUser; 29 | 30 | // const simpleUser = { 31 | // id: 1, 32 | // name: "Leanne Graham", 33 | // username: "Bret", 34 | // email: "Sincere@april.biz", 35 | // address: "asdasdasdas", 36 | // phone: "1-770-736-8031 x56442", 37 | // website: "hildegard.org", 38 | // company: "harness real-time e-markets", 39 | // }; 40 | 41 | // Object.keys(simpleUser).forEach((key: KeyOfSimpleUser) => { 42 | // console.log(simpleUser[key]); 43 | // }); 44 | -------------------------------------------------------------------------------- /2.AdvancedTypes/src/interfaces-demo.ts: -------------------------------------------------------------------------------- 1 | // interface User { 2 | // githubToken: string; 3 | // } 4 | 5 | // interface Admin extends User { 6 | // specialRights: boolean; 7 | // // githubToken: string; 8 | // } 9 | 10 | // const user: Admin = { specialRights: true, githubToken: "kasjhdkashkdjsah" }; 11 | 12 | // type Admin2 = { 13 | // specialRights: boolean; 14 | // githubToken: string; 15 | // }; 16 | 17 | // class Person implements Admin2 { 18 | // specialRights = true; 19 | // githubToken = "kasjhdkashkdjsah"; 20 | // } 21 | 22 | // interface PersonDetails { 23 | // firstName: string; 24 | // address: string; 25 | // age: number; 26 | // } 27 | 28 | // class Person implements PersonDetails { 29 | // firstName = ""; 30 | // address = ""; 31 | // age = 0; 32 | // } 33 | 34 | // const person: PersonDetails = { 35 | // firstName: "", 36 | // address: "", 37 | // age: 0, 38 | // }; 39 | 40 | // interface A { 41 | // a: number; 42 | // } 43 | 44 | // interface B extends A { 45 | // b: number; 46 | // } 47 | // // a, b 48 | 49 | // type C = { 50 | // c: number; 51 | // }; 52 | 53 | // type D = { 54 | // d: number; 55 | // } & C; 56 | 57 | // // c, d 58 | 59 | // Delcaration merging 60 | // interface Animal { 61 | // name: string; 62 | // } 63 | 64 | // interface Animal { 65 | // speak: () => void; 66 | // } 67 | 68 | // const animal: Animal = { 69 | // name: "Gosho", 70 | // speak: () => { 71 | // console.log("mewww"); 72 | // }, 73 | // }; 74 | 75 | // interface GetNameFunction { 76 | // (param1: number, param2: string): string; 77 | // } 78 | 79 | // const getName: GetNameFunction = (param1: number, param2: string) => { 80 | // return `${param1} ${param2}`; 81 | // }; 82 | -------------------------------------------------------------------------------- /2.AdvancedTypes/src/problem-solving/aggrate-elemnts.ts: -------------------------------------------------------------------------------- 1 | const sumNumbers = (numbers: number[], inversed = false): number => { 2 | let sum: number = 0; 3 | 4 | numbers.forEach((num) => { 5 | const numToSum = inversed ? 1 / num : num; 6 | sum += numToSum; 7 | // if (inversed) { 8 | // sum += 1 / num; 9 | // } else { 10 | // sum += num; 11 | // } 12 | }); 13 | 14 | return sum; 15 | }; 16 | 17 | const concatNumbers = (numbers: number[]): string => { 18 | return numbers.join(""); 19 | }; 20 | 21 | const aggregateElements = (numbers: number[]): void => { 22 | // sum 23 | const sum: number = sumNumbers(numbers); 24 | 25 | // sum inversed 26 | const sumInversed: number = sumNumbers(numbers, true); 27 | 28 | // concat 29 | const concatedNums: string = concatNumbers(numbers); 30 | 31 | // Output 32 | console.log(sum); 33 | console.log(sumInversed); 34 | console.log(concatedNums); 35 | }; 36 | // Input: [1, 2, 3] 37 | // Output: 38 | // 6 39 | // 1.8333333333333333 40 | // 123 41 | // aggregateElements([1, 2, 3]); 42 | 43 | // Input: [2, 4, 8, 16] 44 | // Output: 45 | // 30 46 | // 0.9375 47 | // 24816 48 | aggregateElements([2, 4, 8, 16]); 49 | -------------------------------------------------------------------------------- /2.AdvancedTypes/src/problem-solving/towns.ts: -------------------------------------------------------------------------------- 1 | // Input: 2 | // ["Sofia | 42.696552 | 23.32601", "Beijing | 39.913818 | 116.363625"]; 3 | 4 | // Output: 5 | // [{ town: 'Sofia', latitude: '42.70', longitude: '23.33' } 6 | // { town: 'Beijing', latitude: '39.91', longitude: '116.36'}] 7 | 8 | type Town = { 9 | town: string; 10 | latitude: string; 11 | longtitute: string; 12 | }; 13 | 14 | const solve = (tableRows: string[]): Town[] => { 15 | // 16 | return []; 17 | }; 18 | -------------------------------------------------------------------------------- /2.AdvancedTypes/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2015", 4 | "rootDir": "./src", 5 | "outDir": "./dist", 6 | "sourceMap": true 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /3.OOP/dist/app.js: -------------------------------------------------------------------------------- 1 | // // PROCEDURAL PROGRAMMING 2 | // let baseSalary = 30000; 3 | // const overtime = 10; 4 | // const employees: { name: string; age: number }[] = [ 5 | // { name: "Gosho", age: 19 }, 6 | // { name: "Maria", age: 21 }, 7 | // { name: "Svilen", age: 19 }, 8 | // { name: "Kiril", age: 54 }, 9 | // { name: "Gergana", age: 29 }, 10 | // ]; 11 | // function getWage(salary: number, overtimeInHr: number): number { 12 | // return salary + (salary / 120) * overtimeInHr; 13 | // } 14 | // const wage = getWage(baseSalary, overtime); 15 | // console.log("wage ", wage); 16 | // function getAvgAgeForTheCompany(employees: { name: string; age: number }[]) { 17 | // let sumAge = 0; 18 | // employees.forEach((e) => { 19 | // sumAge += e.age; 20 | // }); 21 | // baseSalary = 0; 22 | // return sumAge / employees.length; 23 | // } 24 | // const avgAge = getAvgAgeForTheCompany(employees); 25 | // console.log({ avgAge }); 26 | // // OOP like -> encapsulated 27 | // const employee = { 28 | // baseSalary: 30000, 29 | // overtime: 10, 30 | // getWage: function () { 31 | // // Uncle bob -> function without parameters is the best! 32 | // return this.baseSalary + this.overtime; 33 | // }, 34 | // }; 35 | // employee.baseSalary = 40000; 36 | // employee.overtime = 12; 37 | // console.log(employee.getWage()); 38 | // // Encapsulation 39 | // class Person { 40 | // name: string; 41 | // constructor(name: string) { 42 | // this.name = name; 43 | // } 44 | // getNameInCapitalLetters() { 45 | // return this.name.toUpperCase(); 46 | // } 47 | // } 48 | // const p = new Person("Bobi"); 49 | // console.log(p.getNameInCapitalLetters()); 50 | // Abstraction 51 | // class Car { 52 | // make: string; 53 | // model: string; 54 | // color: string; 55 | // constructor(make: string, model: string, color: string) { 56 | // this.make = make; 57 | // this.model = model; 58 | // this.color = color; 59 | // } 60 | // getDetails() { 61 | // return `This car is made in ${this.make} and it is model ${this.model} in ${this.color} color!`; 62 | // } 63 | // } 64 | // const bmwCar = new Car("Germany", "BMW", "red"); 65 | // console.log(bmwCar.getDetails()); 66 | // class Car { 67 | // private horsePowers: number; 68 | // private engine: string; 69 | // constructor(horsePowers: number, engine: string) { 70 | // this.engine = engine; 71 | // this.horsePowers = horsePowers; 72 | // } 73 | // private getCoeffForDiseal() { 74 | // return this.horsePowers * 1.5; 75 | // } 76 | // private getCoeffForGas() { 77 | // return this.horsePowers * 23; 78 | // } 79 | // public getCoeff() { 80 | // if (this.engine === "diesel") { 81 | // return this.getCoeffForDiseal(); 82 | // } 83 | // return this.getCoeffForGas(); 84 | // } 85 | // } 86 | // const car1 = new Car(133, "diesel"); 87 | // console.log(car1.getCoeff()); 88 | // // Inheritance 89 | // class Mammal { 90 | // move() { 91 | // console.log("The Mammal is Moving!"); 92 | // } 93 | // speak() { 94 | // console.log("The Mammal is Speaking!"); 95 | // } 96 | // } 97 | // class Dog extends Mammal { 98 | // constructor() { 99 | // super(); 100 | // } 101 | // move() { 102 | // console.log("The Dog is moving"); 103 | // } 104 | // } 105 | // class Cat extends Mammal { 106 | // constructor() { 107 | // super(); 108 | // } 109 | // } 110 | // class Mouse extends Mammal { 111 | // constructor() { 112 | // super(); 113 | // } 114 | // } 115 | // const d = new Dog(); 116 | // class MyHTMLElement { 117 | // click() { 118 | // console.log("click"); 119 | // } 120 | // focus() { 121 | // console.log("focus"); 122 | // } 123 | // } 124 | // class SelectBox extends MyHTMLElement {} 125 | // const selectBox = new SelectBox(); 126 | // selectBox.click(); 127 | // class CheckBox extends MyHTMLElement {} 128 | // const checkBox = new CheckBox(); 129 | // checkBox.focus(); 130 | // // Polymorphism 131 | // interface Animal { 132 | // move: () => void; 133 | // } 134 | // class Lion implements Animal { 135 | // move() { 136 | // console.log("Moving by walking on the ground!"); 137 | // } 138 | // } 139 | // class Bird implements Animal { 140 | // move() { 141 | // console.log("Moving by flying in the sky!"); 142 | // } 143 | // } 144 | // class Fish implements Animal { 145 | // move() { 146 | // console.log("Moving by swimming in the ocean!"); 147 | // } 148 | // } 149 | // const lion = new Lion(); 150 | // const fish = new Fish(); 151 | // const bird = new Bird(); 152 | // lion.move(); 153 | // fish.move(); 154 | // bird.move(); 155 | // function renderText() { 156 | // console.log("renderText called!"); 157 | // } 158 | // function renderCheckbox() { 159 | // console.log("renderCheckbox called!"); 160 | // } 161 | // function renderSelect() { 162 | // console.log("renderSelect called!"); 163 | // } 164 | // function getRenderer(elementName: string) { 165 | // switch (elementName) { 166 | // case "text": 167 | // return renderText(); 168 | // case "checkbox": 169 | // return renderCheckbox(); 170 | // case "select": 171 | // return renderSelect(); 172 | // default: 173 | // break; 174 | // } 175 | // } 176 | // getRenderer("select"); 177 | // interface MyHTMLElement { 178 | // render: () => void; 179 | // } 180 | // class TextBox implements MyHTMLElement { 181 | // render() { 182 | // console.log("Textbox render!"); 183 | // } 184 | // } 185 | // class Select implements MyHTMLElement { 186 | // render() { 187 | // console.log("Select render!"); 188 | // } 189 | // } 190 | /** SOLID */ 191 | // Single responsibility 192 | // class Stundent { 193 | // id: number; 194 | // firstName: string; 195 | // lastName: string; 196 | // email: string; 197 | // constructor() {} 198 | // sendEmail() { 199 | // // sends an email 200 | // } 201 | // enrol() { 202 | // // to enrol student in a course 203 | // } 204 | // saveInDb() { 205 | // // save the current student record in the DataBase 206 | // } 207 | // } 208 | // class EmailService { 209 | // // email functionality 210 | // } 211 | // class Student { 212 | // // details for the student: id, marks, names etc 213 | // } 214 | // class EnrollmentService { 215 | // // enrollment functionlity 216 | // } 217 | // Repository Pattern 218 | // class StudentRepository { 219 | // // CRUD => Create, Read, Update, Delete 220 | // // communication with DB 221 | // // create() { 222 | // // // logic 223 | // // // valid 224 | // // // db.insert() 225 | // // } 226 | // } 227 | // Open-Closed Principle 228 | // class Car { 229 | // protected color: string; 230 | // constructor(color: string) { 231 | // this.color = color; 232 | // } 233 | // getMsgWithColor(): void { 234 | // console.log("This car is in color: " + this.color); 235 | // } 236 | // } 237 | // class VW extends Car { 238 | // private serialNumber: string; 239 | // constructor(color: string, serialNumber: string) { 240 | // super(color); 241 | // this.serialNumber = serialNumber; 242 | // } 243 | // getSNDetails() { 244 | // console.log(this.color + " - " + this.serialNumber); 245 | // } 246 | // } 247 | // const myVW = new VW("red", "j2h3g4jh32gjh4"); 248 | // myVW.getMsgWithColor(); 249 | // Interface seggregation 250 | // interface Company { 251 | // name: string; 252 | // catchPhrase: string; 253 | // bs: string; 254 | // } 255 | // interface Geo { 256 | // lat: string; 257 | // lng: string; 258 | // } 259 | // interface Address { 260 | // street: string; 261 | // suite: string; 262 | // city: string; 263 | // zipcode: string; 264 | // geo: Geo; 265 | // } 266 | // interface UserFromDB { 267 | // address: Address; 268 | // company: Company; 269 | // details: UserDetails; 270 | // } 271 | // interface UserDetails { 272 | // id: number; 273 | // name: string; 274 | // username: string; 275 | // email: string; 276 | // phone?: string; 277 | // website?: string; 278 | // } 279 | // class PersonUser implements UserDetails { 280 | // id: number; 281 | // name: string; 282 | // username: string; 283 | // email: string; 284 | // } 285 | // Dependency Inversion (Principle) -> Dependency Injection (Pattern) 286 | class Wallet { 287 | balance; 288 | constructor(balance) { 289 | this.balance = balance; 290 | } 291 | } 292 | class Course { 293 | courses; 294 | constructor(courses) { 295 | this.courses = courses; 296 | } 297 | } 298 | // BAD PRACTICE! 299 | // class User { 300 | // wallet: Wallet; 301 | // username: string; 302 | // course: Course; 303 | // // DON'T DO THAT -> BAD PRACTICE 304 | // constructor(username: string, balance: number, courses: string[]) { 305 | // this.username = username; 306 | // this.wallet = new Wallet(balance); 307 | // this.course = new Course(courses); 308 | // } 309 | // } 310 | // const userPesho = new User("pesho123", 3000, ["JS", "Python"]); 311 | // console.log("balance: ", userPesho.username, userPesho.wallet.balance); 312 | // console.log("courses", userPesho.course.courses); 313 | // console.log("----------------------"); 314 | // const userMaria = new User("maria123", 4000, ["NodeJS", "SQL", "C++"]); 315 | // console.log("balance: ", userMaria.username, userMaria.wallet.balance); 316 | // console.log("courses", userMaria.course.courses); 317 | // // GOOD PRACTICE 318 | // class User { 319 | // wallet: Wallet; 320 | // username: string; 321 | // course: Course; 322 | // // INJECTED! 323 | // constructor(username: string, wallet: Wallet, course: Course) { 324 | // this.username = username; 325 | // this.wallet = wallet; 326 | // this.course = course; 327 | // } 328 | // } 329 | // const walletIvan = new Wallet(4000); 330 | // const coursesIvan = new Course(["C#", "JS"]); 331 | // const userIvan = new User("ivan123", walletIvan, coursesIvan); 332 | // console.log("balance: ", userIvan.username, userIvan.wallet.balance); 333 | // console.log("courses", userIvan.course.courses); 334 | // // Static member 335 | // class Car { 336 | // static countOfFunctionInvoked: number = 0; 337 | // move() { 338 | // Car.countOfFunctionInvoked++; 339 | // } 340 | // } 341 | // const myCar1 = new Car(); 342 | // const myCar2 = new Car(); 343 | // console.log("count", Car.countOfFunctionInvoked); 344 | // myCar1.move(); 345 | // myCar1.move(); 346 | // myCar1.move(); 347 | // console.log("count", Car.countOfFunctionInvoked); 348 | // myCar2.move(); 349 | // myCar2.move(); 350 | // console.log("count", Car.countOfFunctionInvoked); 351 | // Getters and setters 352 | // class Person { 353 | // private _name: string; 354 | // constructor(name: string) { 355 | // this._name = name; 356 | // } 357 | // get name(): string { 358 | // // logic 359 | // return this._name.toLowerCase(); 360 | // } 361 | // set name(newName: string) { 362 | // if (newName.length <= 3) { 363 | // throw new Error("New name is less than 4 chars!"); 364 | // } 365 | // this._name = newName; 366 | // } 367 | // } 368 | // const p = new Person("Pesho"); 369 | // p.name = "Poppy"; 370 | // console.log(p.name); 371 | // // Access modifiers 372 | // class Creature { 373 | // private name: string; 374 | // public age: number; 375 | // protected color: string; 376 | // constructor(name: string, age: number, color: string) { 377 | // this.name = name; 378 | // this.age = age; 379 | // this.color = color; 380 | // } 381 | // } 382 | // class AnotherCreature extends Creature { 383 | // readonly id = 123; 384 | // constructor(name: string, age: number, color: string) { 385 | // super(name, age, color); // new Creature 386 | // } 387 | // getColor() { 388 | // return this.color; 389 | // } 390 | // } 391 | // const creature = new Creature("create A", 1230, "grey"); 392 | // const anotherCreature = new AnotherCreature("Another Creature", 2500, "black"); 393 | // Abstract class 394 | class Color { 395 | hash; 396 | constructor(hash) { } 397 | fetchColorFromAPi() { 398 | console.log("fetch!"); 399 | } 400 | } 401 | class Shape extends Color { 402 | } 403 | const s = new Shape("kajshdkjash"); 404 | s.fetchColorFromAPi(); 405 | -------------------------------------------------------------------------------- /3.OOP/oop.drawio.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tsvetis/TypeScript-Apr-2024/06a2d6f1117c2eb4deb97647703a1be2cdaf4025/3.OOP/oop.drawio.pdf -------------------------------------------------------------------------------- /3.OOP/src/app.ts: -------------------------------------------------------------------------------- 1 | // // PROCEDURAL PROGRAMMING 2 | // let baseSalary = 30000; 3 | // const overtime = 10; 4 | // const employees: { name: string; age: number }[] = [ 5 | // { name: "Gosho", age: 19 }, 6 | // { name: "Maria", age: 21 }, 7 | // { name: "Svilen", age: 19 }, 8 | // { name: "Kiril", age: 54 }, 9 | // { name: "Gergana", age: 29 }, 10 | // ]; 11 | 12 | // function getWage(salary: number, overtimeInHr: number): number { 13 | // return salary + (salary / 120) * overtimeInHr; 14 | // } 15 | 16 | // const wage = getWage(baseSalary, overtime); 17 | // console.log("wage ", wage); 18 | 19 | // function getAvgAgeForTheCompany(employees: { name: string; age: number }[]) { 20 | // let sumAge = 0; 21 | // employees.forEach((e) => { 22 | // sumAge += e.age; 23 | // }); 24 | // baseSalary = 0; 25 | // return sumAge / employees.length; 26 | // } 27 | 28 | // const avgAge = getAvgAgeForTheCompany(employees); 29 | // console.log({ avgAge }); 30 | 31 | // // OOP like -> encapsulated 32 | // const employee = { 33 | // baseSalary: 30000, 34 | // overtime: 10, 35 | // getWage: function () { 36 | // // Uncle bob -> function without parameters is the best! 37 | // return this.baseSalary + this.overtime; 38 | // }, 39 | // }; 40 | 41 | // employee.baseSalary = 40000; 42 | // employee.overtime = 12; 43 | // console.log(employee.getWage()); 44 | 45 | // // Encapsulation 46 | // class Person { 47 | // name: string; 48 | 49 | // constructor(name: string) { 50 | // this.name = name; 51 | // } 52 | 53 | // getNameInCapitalLetters() { 54 | // return this.name.toUpperCase(); 55 | // } 56 | // } 57 | 58 | // const p = new Person("Bobi"); 59 | // console.log(p.getNameInCapitalLetters()); 60 | 61 | // Abstraction 62 | // class Car { 63 | // make: string; 64 | // model: string; 65 | // color: string; 66 | 67 | // constructor(make: string, model: string, color: string) { 68 | // this.make = make; 69 | // this.model = model; 70 | // this.color = color; 71 | // } 72 | 73 | // getDetails() { 74 | // return `This car is made in ${this.make} and it is model ${this.model} in ${this.color} color!`; 75 | // } 76 | // } 77 | // const bmwCar = new Car("Germany", "BMW", "red"); 78 | // console.log(bmwCar.getDetails()); 79 | 80 | // class Car { 81 | // private horsePowers: number; 82 | // private engine: string; 83 | 84 | // constructor(horsePowers: number, engine: string) { 85 | // this.engine = engine; 86 | // this.horsePowers = horsePowers; 87 | // } 88 | 89 | // private getCoeffForDiseal() { 90 | // return this.horsePowers * 1.5; 91 | // } 92 | 93 | // private getCoeffForGas() { 94 | // return this.horsePowers * 23; 95 | // } 96 | 97 | // public getCoeff() { 98 | // if (this.engine === "diesel") { 99 | // return this.getCoeffForDiseal(); 100 | // } 101 | 102 | // return this.getCoeffForGas(); 103 | // } 104 | // } 105 | 106 | // const car1 = new Car(133, "diesel"); 107 | // console.log(car1.getCoeff()); 108 | 109 | // // Inheritance 110 | // class Mammal { 111 | // move() { 112 | // console.log("The Mammal is Moving!"); 113 | // } 114 | 115 | // speak() { 116 | // console.log("The Mammal is Speaking!"); 117 | // } 118 | // } 119 | 120 | // class Dog extends Mammal { 121 | // constructor() { 122 | // super(); 123 | // } 124 | 125 | // move() { 126 | // console.log("The Dog is moving"); 127 | // } 128 | // } 129 | 130 | // class Cat extends Mammal { 131 | // constructor() { 132 | // super(); 133 | // } 134 | // } 135 | 136 | // class Mouse extends Mammal { 137 | // constructor() { 138 | // super(); 139 | // } 140 | // } 141 | 142 | // const d = new Dog(); 143 | 144 | // class MyHTMLElement { 145 | // click() { 146 | // console.log("click"); 147 | // } 148 | // focus() { 149 | // console.log("focus"); 150 | // } 151 | // } 152 | 153 | // class SelectBox extends MyHTMLElement {} 154 | // const selectBox = new SelectBox(); 155 | // selectBox.click(); 156 | 157 | // class CheckBox extends MyHTMLElement {} 158 | // const checkBox = new CheckBox(); 159 | // checkBox.focus(); 160 | 161 | // // Polymorphism 162 | 163 | // interface Animal { 164 | // move: () => void; 165 | // } 166 | 167 | // class Lion implements Animal { 168 | // move() { 169 | // console.log("Moving by walking on the ground!"); 170 | // } 171 | // } 172 | 173 | // class Bird implements Animal { 174 | // move() { 175 | // console.log("Moving by flying in the sky!"); 176 | // } 177 | // } 178 | 179 | // class Fish implements Animal { 180 | // move() { 181 | // console.log("Moving by swimming in the ocean!"); 182 | // } 183 | // } 184 | 185 | // const lion = new Lion(); 186 | // const fish = new Fish(); 187 | // const bird = new Bird(); 188 | // lion.move(); 189 | // fish.move(); 190 | // bird.move(); 191 | 192 | // function renderText() { 193 | // console.log("renderText called!"); 194 | // } 195 | // function renderCheckbox() { 196 | // console.log("renderCheckbox called!"); 197 | // } 198 | // function renderSelect() { 199 | // console.log("renderSelect called!"); 200 | // } 201 | 202 | // function getRenderer(elementName: string) { 203 | // switch (elementName) { 204 | // case "text": 205 | // return renderText(); 206 | // case "checkbox": 207 | // return renderCheckbox(); 208 | // case "select": 209 | // return renderSelect(); 210 | // default: 211 | // break; 212 | // } 213 | // } 214 | 215 | // getRenderer("select"); 216 | 217 | // interface MyHTMLElement { 218 | // render: () => void; 219 | // } 220 | 221 | // class TextBox implements MyHTMLElement { 222 | // render() { 223 | // console.log("Textbox render!"); 224 | // } 225 | // } 226 | 227 | // class Select implements MyHTMLElement { 228 | // render() { 229 | // console.log("Select render!"); 230 | // } 231 | // } 232 | 233 | /** SOLID */ 234 | 235 | // Single responsibility 236 | // class Stundent { 237 | // id: number; 238 | // firstName: string; 239 | // lastName: string; 240 | // email: string; 241 | 242 | // constructor() {} 243 | 244 | // sendEmail() { 245 | // // sends an email 246 | // } 247 | 248 | // enrol() { 249 | // // to enrol student in a course 250 | // } 251 | 252 | // saveInDb() { 253 | // // save the current student record in the DataBase 254 | // } 255 | // } 256 | 257 | // class EmailService { 258 | // // email functionality 259 | // } 260 | 261 | // class Student { 262 | // // details for the student: id, marks, names etc 263 | // } 264 | 265 | // class EnrollmentService { 266 | // // enrollment functionlity 267 | // } 268 | 269 | // Repository Pattern 270 | // class StudentRepository { 271 | // // CRUD => Create, Read, Update, Delete 272 | // // communication with DB 273 | // // create() { 274 | // // // logic 275 | // // // valid 276 | // // // db.insert() 277 | // // } 278 | // } 279 | 280 | // Open-Closed Principle 281 | // class Car { 282 | // protected color: string; 283 | 284 | // constructor(color: string) { 285 | // this.color = color; 286 | // } 287 | 288 | // getMsgWithColor(): void { 289 | // console.log("This car is in color: " + this.color); 290 | // } 291 | // } 292 | 293 | // class VW extends Car { 294 | // private serialNumber: string; 295 | 296 | // constructor(color: string, serialNumber: string) { 297 | // super(color); 298 | // this.serialNumber = serialNumber; 299 | // } 300 | 301 | // getSNDetails() { 302 | // console.log(this.color + " - " + this.serialNumber); 303 | // } 304 | // } 305 | 306 | // const myVW = new VW("red", "j2h3g4jh32gjh4"); 307 | // myVW.getMsgWithColor(); 308 | 309 | // Interface seggregation 310 | // interface Company { 311 | // name: string; 312 | // catchPhrase: string; 313 | // bs: string; 314 | // } 315 | 316 | // interface Geo { 317 | // lat: string; 318 | // lng: string; 319 | // } 320 | 321 | // interface Address { 322 | // street: string; 323 | // suite: string; 324 | // city: string; 325 | // zipcode: string; 326 | // geo: Geo; 327 | // } 328 | 329 | // interface UserFromDB { 330 | // address: Address; 331 | // company: Company; 332 | // details: UserDetails; 333 | // } 334 | 335 | // interface UserDetails { 336 | // id: number; 337 | // name: string; 338 | // username: string; 339 | // email: string; 340 | // phone?: string; 341 | // website?: string; 342 | // } 343 | 344 | // class PersonUser implements UserDetails { 345 | // id: number; 346 | // name: string; 347 | // username: string; 348 | // email: string; 349 | // } 350 | 351 | // Dependency Inversion (Principle) -> Dependency Injection (Pattern) 352 | class Wallet { 353 | balance: number; 354 | 355 | constructor(balance: number) { 356 | this.balance = balance; 357 | } 358 | } 359 | 360 | class Course { 361 | courses: string[]; 362 | 363 | constructor(courses: string[]) { 364 | this.courses = courses; 365 | } 366 | } 367 | 368 | // BAD PRACTICE! 369 | // class User { 370 | // wallet: Wallet; 371 | // username: string; 372 | // course: Course; 373 | // // DON'T DO THAT -> BAD PRACTICE 374 | // constructor(username: string, balance: number, courses: string[]) { 375 | // this.username = username; 376 | // this.wallet = new Wallet(balance); 377 | // this.course = new Course(courses); 378 | // } 379 | // } 380 | 381 | // const userPesho = new User("pesho123", 3000, ["JS", "Python"]); 382 | // console.log("balance: ", userPesho.username, userPesho.wallet.balance); 383 | // console.log("courses", userPesho.course.courses); 384 | // console.log("----------------------"); 385 | // const userMaria = new User("maria123", 4000, ["NodeJS", "SQL", "C++"]); 386 | // console.log("balance: ", userMaria.username, userMaria.wallet.balance); 387 | // console.log("courses", userMaria.course.courses); 388 | 389 | // // GOOD PRACTICE 390 | // class User { 391 | // wallet: Wallet; 392 | // username: string; 393 | // course: Course; 394 | 395 | // // INJECTED! 396 | // constructor(username: string, wallet: Wallet, course: Course) { 397 | // this.username = username; 398 | // this.wallet = wallet; 399 | // this.course = course; 400 | // } 401 | // } 402 | 403 | // const walletIvan = new Wallet(4000); 404 | // const coursesIvan = new Course(["C#", "JS"]); 405 | // const userIvan = new User("ivan123", walletIvan, coursesIvan); 406 | // console.log("balance: ", userIvan.username, userIvan.wallet.balance); 407 | // console.log("courses", userIvan.course.courses); 408 | 409 | // // Static member 410 | // class Car { 411 | // static countOfFunctionInvoked: number = 0; 412 | 413 | // move() { 414 | // Car.countOfFunctionInvoked++; 415 | // } 416 | // } 417 | 418 | // const myCar1 = new Car(); 419 | // const myCar2 = new Car(); 420 | // console.log("count", Car.countOfFunctionInvoked); 421 | // myCar1.move(); 422 | // myCar1.move(); 423 | // myCar1.move(); 424 | // console.log("count", Car.countOfFunctionInvoked); 425 | // myCar2.move(); 426 | // myCar2.move(); 427 | // console.log("count", Car.countOfFunctionInvoked); 428 | 429 | // Getters and setters 430 | // class Person { 431 | // private _name: string; 432 | 433 | // constructor(name: string) { 434 | // this._name = name; 435 | // } 436 | 437 | // get name(): string { 438 | // // logic 439 | // return this._name.toLowerCase(); 440 | // } 441 | 442 | // set name(newName: string) { 443 | // if (newName.length <= 3) { 444 | // throw new Error("New name is less than 4 chars!"); 445 | // } 446 | // this._name = newName; 447 | // } 448 | // } 449 | // const p = new Person("Pesho"); 450 | // p.name = "Poppy"; 451 | // console.log(p.name); 452 | 453 | // // Access modifiers 454 | // class Creature { 455 | // private name: string; 456 | // public age: number; 457 | // protected color: string; 458 | 459 | // constructor(name: string, age: number, color: string) { 460 | // this.name = name; 461 | // this.age = age; 462 | // this.color = color; 463 | // } 464 | // } 465 | 466 | // class AnotherCreature extends Creature { 467 | // readonly id = 123; 468 | 469 | // constructor(name: string, age: number, color: string) { 470 | // super(name, age, color); // new Creature 471 | // } 472 | 473 | // getColor() { 474 | // return this.color; 475 | // } 476 | // } 477 | 478 | // const creature = new Creature("create A", 1230, "grey"); 479 | // const anotherCreature = new AnotherCreature("Another Creature", 2500, "black"); 480 | 481 | // Abstract class 482 | abstract class Color { 483 | hash: string; 484 | 485 | constructor(hash: string) {} 486 | 487 | fetchColorFromAPi() { 488 | console.log("fetch!"); 489 | } 490 | } 491 | 492 | class Shape extends Color {} 493 | 494 | const s = new Shape("kajshdkjash"); 495 | s.fetchColorFromAPi(); 496 | -------------------------------------------------------------------------------- /3.OOP/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2022", 4 | "outDir": "./dist", 5 | "rootDir": "./src" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /4.DPAndGenerics/dist/dp.js: -------------------------------------------------------------------------------- 1 | // Singleton Pattern - Anti pattern 2 | // class Singleton { 3 | // private static instance: Singleton | null = null; 4 | class API { 5 | fetchData() { 6 | return { 7 | data: { 8 | name: "Johnny", 9 | age: 25, 10 | social: { 11 | email: "johnny25@gmail.com", 12 | }, 13 | }, 14 | }; 15 | } 16 | } 17 | class Converter { 18 | apiData; 19 | constructor(apiData) { 20 | this.apiData = apiData; 21 | } 22 | get name() { 23 | return this.apiData.fetchData().data.name; 24 | } 25 | get age() { 26 | return this.apiData.fetchData().data.age; 27 | } 28 | get email() { 29 | return this.apiData.fetchData().data.social.email; 30 | } 31 | } 32 | // Client 33 | function displayData({ name, age, email }) { 34 | console.log({ name, age, email }); 35 | } 36 | const api = new API(); 37 | const adaptedData = new Converter(api); 38 | displayData(adaptedData); 39 | //# sourceMappingURL=dp.js.map -------------------------------------------------------------------------------- /4.DPAndGenerics/dist/dp.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"dp.js","sourceRoot":"","sources":["../src/dp.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,oBAAoB;AACpB,sDAAsD;AA2HtD,MAAM,GAAG;IACP,SAAS;QACP,OAAO;YACL,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,GAAG,EAAE,EAAE;gBACP,MAAM,EAAE;oBACN,KAAK,EAAE,oBAAoB;iBAC5B;aACF;SACF,CAAC;IACJ,CAAC;CACF;AAQD,MAAM,SAAS;IACL,OAAO,CAAM;IAErB,YAAY,OAAY;QACtB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;IAC5C,CAAC;IAED,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;IAC3C,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;IACpD,CAAC;CACF;AAED,SAAS;AACT,SAAS,WAAW,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAiB;IACtD,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;AACtB,MAAM,WAAW,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;AACvC,WAAW,CAAC,WAAW,CAAC,CAAC"} -------------------------------------------------------------------------------- /4.DPAndGenerics/dist/generics.js: -------------------------------------------------------------------------------- 1 | // const getParamInfoNumber = (param: number): string => { 2 | // return `This is your param: ${param} and it is typeof ${typeof param}.`; 3 | // }; 4 | // const getParamInfoStr = (param: string): string => { 5 | // return `This is your param: ${param} and it is typeof ${typeof param}.`; 6 | // }; 7 | // const getParamInfoObj = (param: object): string => { 8 | // return `This is your param: ${param} and it is typeof ${typeof param}.`; 9 | // }; 10 | // const getParamInfo = (param: number | string | object): string => { 11 | // return `This is your param: ${param} and it is typeof ${typeof param}.`; 12 | // }; 13 | // function expression 14 | // const getParamInfo = (param: T): string => { 15 | // return `This is your param: ${param} and it is typeof ${typeof param}.`; 16 | // }; 17 | // const getParamInfo = function (param: T): string { 18 | // return `This is your param: ${param} and it is typeof ${typeof param}.`; 19 | // }; 20 | // // Function declaration 21 | // function getParamInfo(param: T): string { 22 | // return `This is your param: ${param} and it is typeof ${typeof param}.`; 23 | // } 24 | // const paramNumber = getParamInfo(123); 25 | // console.log(paramNumber); 26 | // const paramStr = getParamInfo("xyz123"); 27 | // console.log(paramStr); 28 | // const paramObj = getParamInfo({ name: "Pesho", age: 123 }); 29 | // console.log(paramObj); 30 | // const paramBool = getParamInfo(true); 31 | // console.log(paramBool); 32 | // interface UserData { 33 | // name: string; 34 | // age: number; 35 | // id: T; 36 | // } 37 | // const test = getParamInfo>({ 38 | // name: "Pesho", 39 | // age: 25, 40 | // id: 1, 41 | // }); 42 | // const test2 = getParamInfo>({ 43 | // name: "Pesho", 44 | // age: 25, 45 | // id: "xyz", 46 | // }); 47 | // const attachId = (obj: T) => { 48 | // const id = Math.round(Math.random() * 1000); 49 | // return { ...obj, id }; 50 | // }; 51 | // type PersonType = { 52 | // name: string; 53 | // address: string; 54 | // age: number; 55 | // }; 56 | // const person: PersonType = { 57 | // name: "Mitko", 58 | // address: "Sofia, Bulgaria", 59 | // age: 23, 60 | // }; 61 | // const personWithId = attachId(person); 62 | // console.log(personWithId); 63 | // type AnimalType = { 64 | // furColor: string; 65 | // legsCount: number; 66 | // type: string; 67 | // }; 68 | // const animal: AnimalType = { 69 | // furColor: "green", 70 | // legsCount: 4, 71 | // type: "mammal", 72 | // }; 73 | // const animalWithId = attachId(animal); 74 | // console.log(animalWithId); 75 | // interface DocumentObject { 76 | // id: number; 77 | // name: string; 78 | // data: T; 79 | // } 80 | // type SomeType = { name: string; age: number; address: string }; 81 | // const doc1: DocumentObject = { 82 | // id: 1, 83 | // name: "person", 84 | // data: { 85 | // name: "Pesho", 86 | // age: 12, 87 | // address: "Tokyo, Japan", 88 | // }, 89 | // }; 90 | // const doc2: DocumentObject = { 91 | // id: 2, 92 | // name: "something", 93 | // data: true, 94 | // }; 95 | // const doc3: DocumentObject = { 96 | // id: 3, 97 | // name: "some strings", 98 | // data: ["a", "b", "c"], 99 | // }; 100 | // const takeLast = (array: T[]): T => { 101 | // return array.pop(); 102 | // }; 103 | // const lastNum = takeLast([1, 2, 3, 4, 5]); 104 | // console.log(lastNum); 105 | // const lastBool = takeLast([true, false, false, true]); 106 | // console.log(lastBool); 107 | // const lastStr = takeLast(["a", "b", "c", "d"]); 108 | // console.log(lastStr); 109 | // const randomObj = { a: "1", b: "2", c: "3" }; 110 | // const tuples = Object.entries(randomObj); 111 | // console.log(tuples); 112 | // const makeTuples = (a: T, b: V): (T | V)[] => { 113 | // return [a, b]; 114 | // }; 115 | // const tuple1 = makeTuples("Hello", 123); 116 | // const tuple2 = makeTuples(123, "ABC"); 117 | // const tuple3 = makeTuples(true, "Alphabet"); 118 | // console.log(tuple1); 119 | // interface GenericConstructor { 120 | // (arg1: T, arg2: V): [T, V]; 121 | // } 122 | // const simpleFn: GenericConstructor = ( 123 | // arg1: T, 124 | // arg2: V 125 | // ) => { 126 | // return [arg1, arg2]; 127 | // }; 128 | // console.log(simpleFn("Hello", "World")); 129 | // class Colletion { 130 | // data: T[]; 131 | // constructor(...params: T[]) { 132 | // this.data = params; 133 | // } 134 | // addElemnt(el: T) { 135 | // this.data.push(el); 136 | // } 137 | // removeElement(el: T) { 138 | // const index = this.data.indexOf(el); 139 | // if (index > -1) { 140 | // this.data.splice(index, 1); 141 | // } 142 | // } 143 | // } 144 | // const numCollection = new Colletion(1, 2, 3, 4); 145 | // numCollection.addElemnt(55); 146 | // numCollection.removeElement(2); 147 | // console.log(numCollection.data); 148 | // const strCollection = new Colletion("a", "b", "c", "d"); 149 | // strCollection.addElemnt("Pikachu"); 150 | // strCollection.removeElement("b"); 151 | // console.log(strCollection.data); 152 | // class UserTest { 153 | // first: F; 154 | // second: S; 155 | // constructor(f: F, s: S) { 156 | // this.first = f; 157 | // this.second = s; 158 | // } 159 | // showBoth() { 160 | // return `First: ${this.first}, Second: ${this.second}`; 161 | // } 162 | // } 163 | // const test1 = new UserTest(123, "Pokemon"); 164 | // console.log(test1.showBoth()); 165 | // const test2 = new UserTest(true, { name: "Kiril" }); 166 | // console.log(test2.showBoth()); 167 | const map1 = new Map(); 168 | map1.set("a", 1); 169 | map1.set("b", 2); 170 | map1.set("c", 3); 171 | console.log(map1.get("a")); 172 | //# sourceMappingURL=generics.js.map -------------------------------------------------------------------------------- /4.DPAndGenerics/dist/generics.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"generics.js","sourceRoot":"","sources":["../src/generics.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,6EAA6E;AAC7E,KAAK;AAEL,uDAAuD;AACvD,6EAA6E;AAC7E,KAAK;AAEL,uDAAuD;AACvD,6EAA6E;AAC7E,KAAK;AAEL,sEAAsE;AACtE,6EAA6E;AAC7E,KAAK;AAEL,sBAAsB;AACtB,kDAAkD;AAClD,6EAA6E;AAC7E,KAAK;AACL,wDAAwD;AACxD,6EAA6E;AAC7E,KAAK;AAEL,0BAA0B;AAC1B,+CAA+C;AAC/C,6EAA6E;AAC7E,IAAI;AAEJ,yCAAyC;AACzC,4BAA4B;AAE5B,2CAA2C;AAC3C,yBAAyB;AAEzB,8DAA8D;AAC9D,yBAAyB;AAEzB,wCAAwC;AACxC,0BAA0B;AAE1B,0BAA0B;AAC1B,kBAAkB;AAClB,iBAAiB;AACjB,WAAW;AACX,IAAI;AAEJ,gDAAgD;AAChD,mBAAmB;AACnB,aAAa;AACb,WAAW;AACX,MAAM;AAEN,iDAAiD;AACjD,mBAAmB;AACnB,aAAa;AACb,eAAe;AACf,MAAM;AAEN,oCAAoC;AACpC,iDAAiD;AACjD,2BAA2B;AAC3B,KAAK;AAEL,sBAAsB;AACtB,kBAAkB;AAClB,qBAAqB;AACrB,iBAAiB;AACjB,KAAK;AAEL,+BAA+B;AAC/B,mBAAmB;AACnB,gCAAgC;AAChC,aAAa;AACb,KAAK;AAEL,qDAAqD;AACrD,6BAA6B;AAE7B,sBAAsB;AACtB,sBAAsB;AACtB,uBAAuB;AACvB,kBAAkB;AAClB,KAAK;AAEL,+BAA+B;AAC/B,uBAAuB;AACvB,kBAAkB;AAClB,oBAAoB;AACpB,KAAK;AAEL,qDAAqD;AACrD,6BAA6B;AAE7B,gCAAgC;AAChC,gBAAgB;AAChB,kBAAkB;AAClB,aAAa;AACb,IAAI;AAEJ,kEAAkE;AAElE,2CAA2C;AAC3C,WAAW;AACX,oBAAoB;AACpB,YAAY;AACZ,qBAAqB;AACrB,eAAe;AACf,+BAA+B;AAC/B,OAAO;AACP,KAAK;AAEL,0CAA0C;AAC1C,WAAW;AACX,uBAAuB;AACvB,gBAAgB;AAChB,KAAK;AAEL,2CAA2C;AAC3C,WAAW;AACX,0BAA0B;AAC1B,2BAA2B;AAC3B,KAAK;AAEL,2CAA2C;AAC3C,wBAAwB;AACxB,KAAK;AAEL,qDAAqD;AACrD,wBAAwB;AACxB,kEAAkE;AAClE,yBAAyB;AACzB,0DAA0D;AAC1D,wBAAwB;AAExB,gDAAgD;AAChD,4CAA4C;AAC5C,uBAAuB;AAEvB,wDAAwD;AACxD,mBAAmB;AACnB,KAAK;AAEL,2CAA2C;AAC3C,yCAAyC;AACzC,+CAA+C;AAC/C,uBAAuB;AAEvB,uCAAuC;AACvC,gCAAgC;AAChC,IAAI;AAEJ,+DAA+D;AAC/D,aAAa;AACb,YAAY;AACZ,SAAS;AACT,yBAAyB;AACzB,KAAK;AAEL,2CAA2C;AAE3C,uBAAuB;AACvB,eAAe;AAEf,kCAAkC;AAClC,0BAA0B;AAC1B,MAAM;AAEN,uBAAuB;AACvB,0BAA0B;AAC1B,MAAM;AAEN,2BAA2B;AAC3B,2CAA2C;AAE3C,wBAAwB;AACxB,oCAAoC;AACpC,QAAQ;AACR,MAAM;AACN,IAAI;AAEJ,mDAAmD;AACnD,+BAA+B;AAC/B,kCAAkC;AAClC,mCAAmC;AAEnC,2DAA2D;AAC3D,sCAAsC;AACtC,oCAAoC;AACpC,mCAAmC;AAEnC,yBAAyB;AACzB,cAAc;AACd,eAAe;AAEf,8BAA8B;AAC9B,sBAAsB;AACtB,uBAAuB;AACvB,MAAM;AAEN,iBAAiB;AACjB,6DAA6D;AAC7D,MAAM;AACN,IAAI;AAEJ,8CAA8C;AAC9C,iCAAiC;AAEjC,uDAAuD;AACvD,iCAAiC;AAEjC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;AAEvB,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AACjB,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AACjB,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AAEjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC"} -------------------------------------------------------------------------------- /4.DPAndGenerics/src/dp.ts: -------------------------------------------------------------------------------- 1 | // Singleton Pattern - Anti pattern 2 | // class Singleton { 3 | // private static instance: Singleton | null = null; 4 | 5 | // private constructor() {} 6 | 7 | // public static getInstance(): Singleton { 8 | // if (this.instance === null) { 9 | // this.instance = new Singleton(); 10 | // } 11 | 12 | // return this.instance; 13 | // } 14 | // } 15 | 16 | // const instance1 = Singleton.getInstance(); 17 | // const instance2 = Singleton.getInstance(); 18 | // const a = { name: "Pesho" }; 19 | // const b = { name: "Pesho" }; 20 | // console.log(instance1 === instance2); 21 | 22 | // Factory Pattern 23 | // interface Car { 24 | // model: string; 25 | // drive: () => void; 26 | // } 27 | 28 | // class Tesla implements Car { 29 | // model = "Tesla"; 30 | // drive() { 31 | // console.log(`You are drving ${this.model}!`); 32 | // } 33 | // } 34 | 35 | // class BMW implements Car { 36 | // model = "BMW"; 37 | // drive() { 38 | // console.log(`You are drving ${this.model}!`); 39 | // } 40 | // } 41 | 42 | // class CarFactory { 43 | // createCar(type: string): Car { 44 | // if (type === "Tesla") { 45 | // return new Tesla(); 46 | // } else if (type === "BMW") { 47 | // return new BMW(); 48 | // } else { 49 | // throw new Error("Car type not supported!"); 50 | // } 51 | // } 52 | // } 53 | 54 | // const carFactory = new CarFactory(); 55 | // const myTesla = carFactory.createCar("Tesla"); 56 | // myTesla.drive(); 57 | 58 | // const myBMW = carFactory.createCar("BMW"); 59 | // myBMW.drive(); 60 | 61 | // const myVW = carFactory.createCar("VW"); 62 | // myVW.drive(); 63 | 64 | // // Strategy Pattern 65 | // interface DeliveryStrategy { 66 | // calcCost(weight: number, distance: number): number; 67 | // } 68 | 69 | // class EcontStrategy implements DeliveryStrategy { 70 | // calcCost(weight: number, distance: number): number { 71 | // // custom logic for econt 72 | // return (weight * distance) / 100; 73 | // } 74 | // } 75 | // class SpeedyStrategy implements DeliveryStrategy { 76 | // calcCost(weight: number, distance: number): number { 77 | // // custom logic for speedy 78 | // return weight * distance - 100; 79 | // } 80 | // } 81 | // class FedExStrategy implements DeliveryStrategy { 82 | // calcCost(weight: number, distance: number): number { 83 | // // custom logic for fedex 84 | // return weight * distance * distance; 85 | // } 86 | // } 87 | 88 | // class DeliveryCalcCost { 89 | // private deliveryStrategy: DeliveryStrategy; 90 | 91 | // constructor(deliveryStrategy: DeliveryStrategy) { 92 | // this.deliveryStrategy = deliveryStrategy; 93 | // } 94 | 95 | // calculateCost(weight: number, distance: number): number { 96 | // return this.deliveryStrategy.calcCost(weight, distance); 97 | // } 98 | // } 99 | 100 | // const econtDelivery = new EcontStrategy(); 101 | // const speedyDelivery = new SpeedyStrategy(); 102 | // const fedexDelivery = new FedExStrategy(); 103 | 104 | // // econt 105 | // const calcEcont = new DeliveryCalcCost(econtDelivery); 106 | // const costEcont = calcEcont.calculateCost(10, 100); 107 | // // speed 108 | // const calcSpeedy = new DeliveryCalcCost(speedyDelivery); 109 | // const costSpeedy = calcSpeedy.calculateCost(10, 100); 110 | // // fedex 111 | // const calcFedex = new DeliveryCalcCost(fedexDelivery); 112 | // const costFedex = calcFedex.calculateCost(10, 100); 113 | 114 | // console.log({ 115 | // costEcont, 116 | // costSpeedy, 117 | // costFedex, 118 | // }); 119 | 120 | // Adapter pattern 121 | 122 | interface APIType { 123 | data: { name: string; age: number; social: { email: string } }; 124 | } 125 | 126 | class API { 127 | fetchData(): APIType { 128 | return { 129 | data: { 130 | name: "Johnny", 131 | age: 25, 132 | social: { 133 | email: "johnny25@gmail.com", 134 | }, 135 | }, 136 | }; 137 | } 138 | } 139 | 140 | interface JustifiedData { 141 | name: string; 142 | age: number; 143 | email: string; 144 | } 145 | 146 | class Converter implements JustifiedData { 147 | private apiData: API; 148 | 149 | constructor(apiData: API) { 150 | this.apiData = apiData; 151 | } 152 | 153 | get name(): string { 154 | return this.apiData.fetchData().data.name; 155 | } 156 | 157 | get age(): number { 158 | return this.apiData.fetchData().data.age; 159 | } 160 | 161 | get email(): string { 162 | return this.apiData.fetchData().data.social.email; 163 | } 164 | } 165 | 166 | // Client 167 | function displayData({ name, age, email }: JustifiedData) { 168 | console.log({ name, age, email }); 169 | } 170 | 171 | const api = new API(); 172 | const adaptedData = new Converter(api); 173 | displayData(adaptedData); 174 | -------------------------------------------------------------------------------- /4.DPAndGenerics/src/generics.ts: -------------------------------------------------------------------------------- 1 | // const getParamInfoNumber = (param: number): string => { 2 | // return `This is your param: ${param} and it is typeof ${typeof param}.`; 3 | // }; 4 | 5 | // const getParamInfoStr = (param: string): string => { 6 | // return `This is your param: ${param} and it is typeof ${typeof param}.`; 7 | // }; 8 | 9 | // const getParamInfoObj = (param: object): string => { 10 | // return `This is your param: ${param} and it is typeof ${typeof param}.`; 11 | // }; 12 | 13 | // const getParamInfo = (param: number | string | object): string => { 14 | // return `This is your param: ${param} and it is typeof ${typeof param}.`; 15 | // }; 16 | 17 | // function expression 18 | // const getParamInfo = (param: T): string => { 19 | // return `This is your param: ${param} and it is typeof ${typeof param}.`; 20 | // }; 21 | // const getParamInfo = function (param: T): string { 22 | // return `This is your param: ${param} and it is typeof ${typeof param}.`; 23 | // }; 24 | 25 | // // Function declaration 26 | // function getParamInfo(param: T): string { 27 | // return `This is your param: ${param} and it is typeof ${typeof param}.`; 28 | // } 29 | 30 | // const paramNumber = getParamInfo(123); 31 | // console.log(paramNumber); 32 | 33 | // const paramStr = getParamInfo("xyz123"); 34 | // console.log(paramStr); 35 | 36 | // const paramObj = getParamInfo({ name: "Pesho", age: 123 }); 37 | // console.log(paramObj); 38 | 39 | // const paramBool = getParamInfo(true); 40 | // console.log(paramBool); 41 | 42 | // interface UserData { 43 | // name: string; 44 | // age: number; 45 | // id: T; 46 | // } 47 | 48 | // const test = getParamInfo>({ 49 | // name: "Pesho", 50 | // age: 25, 51 | // id: 1, 52 | // }); 53 | 54 | // const test2 = getParamInfo>({ 55 | // name: "Pesho", 56 | // age: 25, 57 | // id: "xyz", 58 | // }); 59 | 60 | // const attachId = (obj: T) => { 61 | // const id = Math.round(Math.random() * 1000); 62 | // return { ...obj, id }; 63 | // }; 64 | 65 | // type PersonType = { 66 | // name: string; 67 | // address: string; 68 | // age: number; 69 | // }; 70 | 71 | // const person: PersonType = { 72 | // name: "Mitko", 73 | // address: "Sofia, Bulgaria", 74 | // age: 23, 75 | // }; 76 | 77 | // const personWithId = attachId(person); 78 | // console.log(personWithId); 79 | 80 | // type AnimalType = { 81 | // furColor: string; 82 | // legsCount: number; 83 | // type: string; 84 | // }; 85 | 86 | // const animal: AnimalType = { 87 | // furColor: "green", 88 | // legsCount: 4, 89 | // type: "mammal", 90 | // }; 91 | 92 | // const animalWithId = attachId(animal); 93 | // console.log(animalWithId); 94 | 95 | // interface DocumentObject { 96 | // id: number; 97 | // name: string; 98 | // data: T; 99 | // } 100 | 101 | // type SomeType = { name: string; age: number; address: string }; 102 | 103 | // const doc1: DocumentObject = { 104 | // id: 1, 105 | // name: "person", 106 | // data: { 107 | // name: "Pesho", 108 | // age: 12, 109 | // address: "Tokyo, Japan", 110 | // }, 111 | // }; 112 | 113 | // const doc2: DocumentObject = { 114 | // id: 2, 115 | // name: "something", 116 | // data: true, 117 | // }; 118 | 119 | // const doc3: DocumentObject = { 120 | // id: 3, 121 | // name: "some strings", 122 | // data: ["a", "b", "c"], 123 | // }; 124 | 125 | // const takeLast = (array: T[]): T => { 126 | // return array.pop(); 127 | // }; 128 | 129 | // const lastNum = takeLast([1, 2, 3, 4, 5]); 130 | // console.log(lastNum); 131 | // const lastBool = takeLast([true, false, false, true]); 132 | // console.log(lastBool); 133 | // const lastStr = takeLast(["a", "b", "c", "d"]); 134 | // console.log(lastStr); 135 | 136 | // const randomObj = { a: "1", b: "2", c: "3" }; 137 | // const tuples = Object.entries(randomObj); 138 | // console.log(tuples); 139 | 140 | // const makeTuples = (a: T, b: V): (T | V)[] => { 141 | // return [a, b]; 142 | // }; 143 | 144 | // const tuple1 = makeTuples("Hello", 123); 145 | // const tuple2 = makeTuples(123, "ABC"); 146 | // const tuple3 = makeTuples(true, "Alphabet"); 147 | // console.log(tuple1); 148 | 149 | // interface GenericConstructor { 150 | // (arg1: T, arg2: V): [T, V]; 151 | // } 152 | 153 | // const simpleFn: GenericConstructor = ( 154 | // arg1: T, 155 | // arg2: V 156 | // ) => { 157 | // return [arg1, arg2]; 158 | // }; 159 | 160 | // console.log(simpleFn("Hello", "World")); 161 | 162 | // class Colletion { 163 | // data: T[]; 164 | 165 | // constructor(...params: T[]) { 166 | // this.data = params; 167 | // } 168 | 169 | // addElemnt(el: T) { 170 | // this.data.push(el); 171 | // } 172 | 173 | // removeElement(el: T) { 174 | // const index = this.data.indexOf(el); 175 | 176 | // if (index > -1) { 177 | // this.data.splice(index, 1); 178 | // } 179 | // } 180 | // } 181 | 182 | // const numCollection = new Colletion(1, 2, 3, 4); 183 | // numCollection.addElemnt(55); 184 | // numCollection.removeElement(2); 185 | // console.log(numCollection.data); 186 | 187 | // const strCollection = new Colletion("a", "b", "c", "d"); 188 | // strCollection.addElemnt("Pikachu"); 189 | // strCollection.removeElement("b"); 190 | // console.log(strCollection.data); 191 | 192 | // class UserTest { 193 | // first: F; 194 | // second: S; 195 | 196 | // constructor(f: F, s: S) { 197 | // this.first = f; 198 | // this.second = s; 199 | // } 200 | 201 | // showBoth() { 202 | // return `First: ${this.first}, Second: ${this.second}`; 203 | // } 204 | // } 205 | 206 | // const test1 = new UserTest(123, "Pokemon"); 207 | // console.log(test1.showBoth()); 208 | 209 | // const test2 = new UserTest(true, { name: "Kiril" }); 210 | // console.log(test2.showBoth()); 211 | 212 | const map1 = new Map(); 213 | 214 | map1.set("a", 1); 215 | map1.set("b", 2); 216 | map1.set("c", 3); 217 | 218 | console.log(map1.get("a")); 219 | -------------------------------------------------------------------------------- /4.DPAndGenerics/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2022", 4 | "outDir": "./dist", 5 | "rootDir": "./src", 6 | "sourceMap": true 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/modules-demo/dist/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const string_1 = require("./utils/string"); 4 | const person_1 = require("./utils/person"); 5 | const modalA = require("./modul-a"); 6 | console.log(modalA.a); 7 | console.log(modalA.getSomeRandomString()); 8 | class Person { 9 | name; 10 | id; 11 | age; 12 | constructor(name, age) { 13 | this.id = (0, person_1.getRandomUniqueId)(); 14 | this.name = (0, string_1.capitalizeFirstLetter)(name); 15 | this.age = age; 16 | } 17 | } 18 | const nikiPerson = new Person("niki", 21); 19 | const petyaPerson = new Person("petya", 19); 20 | const goshoPerson = new Person("gosho", 32); 21 | // console.log(nikiPerson.name, " - ", nikiPerson.id); 22 | // console.log(petyaPerson.name, " - ", petyaPerson.id); 23 | // console.log(goshoPerson.name, " - ", goshoPerson.id); 24 | const avgAge = (0, person_1.getAvgAge)([nikiPerson, petyaPerson, goshoPerson]); 25 | // console.log({ avgAge }); 26 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/modules-demo/dist/modul-a.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | // export const a = 5; 3 | Object.defineProperty(exports, "__esModule", { value: true }); 4 | exports.getSomeRandomString = exports.a = void 0; 5 | // export function test() { 6 | // return "test123"; 7 | // } 8 | // export const test2 = () => "test12345"; 9 | const a = 5; 10 | exports.a = a; 11 | function test() { 12 | return "test123"; 13 | } 14 | exports.getSomeRandomString = test; 15 | // export default function test() { 16 | // return "test123"; 17 | // } 18 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/modules-demo/dist/types/Person.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/modules-demo/dist/utils/math.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/modules-demo/dist/utils/person.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.getAvgAge = exports.getRandomUniqueId = void 0; 4 | const getRandomUniqueId = () => { 5 | return `USER-ID-${Math.floor(Math.random() * 10000)}`; 6 | }; 7 | exports.getRandomUniqueId = getRandomUniqueId; 8 | const getAvgAge = (persons) => { 9 | let sum = 0; 10 | persons.forEach((person) => { 11 | sum += person.age; 12 | }); 13 | const avg = sum / persons.length; 14 | return avg; 15 | }; 16 | exports.getAvgAge = getAvgAge; 17 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/modules-demo/dist/utils/string.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.capitalizeFirstLetter = void 0; 4 | const capitalizeFirstLetter = (input) => { 5 | const firstLetter = input.charAt(0).toUpperCase(); 6 | const theRestLetters = input.slice(1); 7 | return `${firstLetter}${theRestLetters}`; 8 | }; 9 | exports.capitalizeFirstLetter = capitalizeFirstLetter; 10 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/modules-demo/src/index.ts: -------------------------------------------------------------------------------- 1 | import { capitalizeFirstLetter } from "./utils/string"; 2 | import { getAvgAge, getRandomUniqueId } from "./utils/person"; 3 | import { PersonType } from "./types/Person"; 4 | import { getSomeRandomString } from "./modul-a"; 5 | 6 | console.log(getSomeRandomString()); 7 | 8 | class Person implements PersonType { 9 | name: string; 10 | id: string; 11 | age: number; 12 | 13 | constructor(name: string, age: number) { 14 | this.id = getRandomUniqueId(); 15 | this.name = capitalizeFirstLetter(name); 16 | this.age = age; 17 | } 18 | } 19 | 20 | const nikiPerson = new Person("niki", 21); 21 | const petyaPerson = new Person("petya", 19); 22 | const goshoPerson = new Person("gosho", 32); 23 | // console.log(nikiPerson.name, " - ", nikiPerson.id); 24 | // console.log(petyaPerson.name, " - ", petyaPerson.id); 25 | // console.log(goshoPerson.name, " - ", goshoPerson.id); 26 | 27 | const avgAge = getAvgAge([nikiPerson, petyaPerson, goshoPerson]); 28 | // console.log({ avgAge }); 29 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/modules-demo/src/modul-a.ts: -------------------------------------------------------------------------------- 1 | // export const a = 5; 2 | 3 | // export function test() { 4 | // return "test123"; 5 | // } 6 | 7 | // export const test2 = () => "test12345"; 8 | 9 | const a = 5; 10 | 11 | function test() { 12 | return "test123"; 13 | } 14 | 15 | export { a, test as getSomeRandomString }; 16 | 17 | // export default function test() { 18 | // return "test123"; 19 | // } 20 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/modules-demo/src/types/Person.ts: -------------------------------------------------------------------------------- 1 | export interface PersonType { 2 | name: string; 3 | id: string; 4 | age: number; 5 | } 6 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/modules-demo/src/utils/person.ts: -------------------------------------------------------------------------------- 1 | import { PersonType } from "../types/Person"; 2 | 3 | export const getRandomUniqueId = (): string => { 4 | return `USER-ID-${Math.floor(Math.random() * 10000)}`; 5 | }; 6 | 7 | export const getAvgAge = (persons: PersonType[]): number => { 8 | let sum = 0; 9 | 10 | persons.forEach((person) => { 11 | sum += person.age; 12 | }); 13 | 14 | const avg = sum / persons.length; 15 | return avg; 16 | }; 17 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/modules-demo/src/utils/string.ts: -------------------------------------------------------------------------------- 1 | export const capitalizeFirstLetter = (input: string): string => { 2 | const firstLetter = input.charAt(0).toUpperCase(); 3 | const theRestLetters = input.slice(1); 4 | 5 | return `${firstLetter}${theRestLetters}`; 6 | }; 7 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/modules-demo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2022", 4 | "module": "commonjs", 5 | "rootDir": "./src", 6 | "outDir": "./dist", 7 | "strict": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/namespaces-demo/dist/main.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace AnimalGroup { 2 | interface MammalType { 3 | legsCount: number; 4 | animalType: string; 5 | furColor?: string; 6 | } 7 | class Mammal implements MammalType { 8 | legsCount: number; 9 | animalType: string; 10 | furColor: string; 11 | constructor(type: string, furColor: string); 12 | getDetail(): string; 13 | } 14 | } 15 | declare const m2: AnimalGroup.Mammal; 16 | declare namespace People { 17 | class Person { 18 | name: string; 19 | constructor(name: string); 20 | } 21 | } 22 | declare const p: People.Person; 23 | declare namespace Shop { 24 | namespace TechShop { 25 | class Game { 26 | constructor(); 27 | } 28 | } 29 | } 30 | declare const game: shop.Game; 31 | import shop = Shop.TechShop; 32 | declare const g2: shop.Game; 33 | //# sourceMappingURL=main.d.ts.map -------------------------------------------------------------------------------- /5.NamespaceAndModules/namespaces-demo/dist/main.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,kBAAU,WAAW,CAAC;IACpB,UAAiB,UAAU;QACzB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB;IAED,MAAa,MAAO,YAAW,UAAU;QACvC,SAAS,SAAK;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;oBAEL,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;QAK1C,SAAS;KAGV;CACF;AAID,QAAA,MAAM,EAAE,oBAA6C,CAAC;AAGtD,kBAAU,MAAM,CAAC;IACf,MAAa,MAAM;QACjB,IAAI,EAAE,MAAM,CAAC;oBAED,IAAI,EAAE,MAAM;KAGzB;CACF;AAED,QAAA,MAAM,CAAC,eAA8B,CAAC;AAGtC,kBAAU,IAAI,CAAC;IACb,UAAiB,QAAQ,CAAC;QACxB,MAAa,IAAI;;SAEhB;KACF;CACF;AAED,QAAA,MAAM,IAAI,WAA2B,CAAC;AAEtC,OAAO,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC;AAC5B,QAAA,MAAM,EAAE,WAAkB,CAAC"} -------------------------------------------------------------------------------- /5.NamespaceAndModules/namespaces-demo/dist/main.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var AnimalGroup; 3 | (function (AnimalGroup) { 4 | class Mammal { 5 | legsCount = 4; 6 | animalType; 7 | furColor; 8 | constructor(type, furColor) { 9 | this.animalType = type; 10 | this.furColor = furColor; 11 | } 12 | getDetail() { 13 | return `This mammal is ${this.animalType} and it's fur is in ${this.furColor} color.`; 14 | } 15 | } 16 | AnimalGroup.Mammal = Mammal; 17 | })(AnimalGroup || (AnimalGroup = {})); 18 | // const m1 = new Mammal("dog", "brown"); 19 | // console.log(m1.getDetail()); 20 | const m2 = new AnimalGroup.Mammal("dolphine", "none"); 21 | // console.log(m2.getDetail()); 22 | var People; 23 | (function (People) { 24 | class Person { 25 | name; 26 | constructor(name) { 27 | this.name = name; 28 | } 29 | } 30 | People.Person = Person; 31 | })(People || (People = {})); 32 | const p = new People.Person("Hristo"); 33 | // console.log(p.name); 34 | var Shop; 35 | (function (Shop) { 36 | let TechShop; 37 | (function (TechShop) { 38 | class Game { 39 | constructor() { } 40 | } 41 | TechShop.Game = Game; 42 | })(TechShop = Shop.TechShop || (Shop.TechShop = {})); 43 | })(Shop || (Shop = {})); 44 | const game = new Shop.TechShop.Game(); 45 | var shop = Shop.TechShop; // ALIAS 46 | const g2 = new shop.Game(); 47 | // /// 48 | // const ivanchoStudent = new StudentGroup.Student([3, 6, 4, 5], "math"); 49 | // console.log(ivanchoStudent); 50 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/namespaces-demo/dist/student.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace StudentGroup { 2 | class Student { 3 | marks: number[]; 4 | favouriteSubject: string; 5 | constructor(marks: number[], favouriteSubject: string); 6 | } 7 | } 8 | //# sourceMappingURL=student.d.ts.map -------------------------------------------------------------------------------- /5.NamespaceAndModules/namespaces-demo/dist/student.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"student.d.ts","sourceRoot":"","sources":["../src/student.ts"],"names":[],"mappings":"AAAA,kBAAU,YAAY,CAAC;IACrB,MAAa,OAAO;QAClB,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,gBAAgB,EAAE,MAAM,CAAC;oBAEb,KAAK,EAAE,MAAM,EAAE,EAAE,gBAAgB,EAAE,MAAM;KAItD;CACF"} -------------------------------------------------------------------------------- /5.NamespaceAndModules/namespaces-demo/dist/student.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var StudentGroup; 3 | (function (StudentGroup) { 4 | class Student { 5 | marks; 6 | favouriteSubject; 7 | constructor(marks, favouriteSubject) { 8 | this.marks = marks; 9 | this.favouriteSubject = favouriteSubject; 10 | } 11 | } 12 | StudentGroup.Student = Student; 13 | })(StudentGroup || (StudentGroup = {})); 14 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/namespaces-demo/src/main.ts: -------------------------------------------------------------------------------- 1 | namespace AnimalGroup { 2 | export interface MammalType { 3 | legsCount: number; 4 | animalType: string; 5 | furColor?: string; 6 | } 7 | 8 | export class Mammal implements MammalType { 9 | legsCount = 4; 10 | animalType: string; 11 | furColor: string; 12 | 13 | constructor(type: string, furColor: string) { 14 | this.animalType = type; 15 | this.furColor = furColor; 16 | } 17 | 18 | getDetail() { 19 | return `This mammal is ${this.animalType} and it's fur is in ${this.furColor} color.`; 20 | } 21 | } 22 | } 23 | 24 | // const m1 = new Mammal("dog", "brown"); 25 | // console.log(m1.getDetail()); 26 | const m2 = new AnimalGroup.Mammal("dolphine", "none"); 27 | // console.log(m2.getDetail()); 28 | 29 | namespace People { 30 | export class Person { 31 | name: string; 32 | 33 | constructor(name: string) { 34 | this.name = name; 35 | } 36 | } 37 | } 38 | 39 | const p = new People.Person("Hristo"); 40 | // console.log(p.name); 41 | 42 | namespace Shop { 43 | export namespace TechShop { 44 | export class Game { 45 | constructor() {} 46 | } 47 | } 48 | } 49 | 50 | const game = new Shop.TechShop.Game(); 51 | 52 | import shop = Shop.TechShop; // ALIAS 53 | const g2 = new shop.Game(); 54 | 55 | // /// 56 | // const ivanchoStudent = new StudentGroup.Student([3, 6, 4, 5], "math"); 57 | // console.log(ivanchoStudent); 58 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/namespaces-demo/src/student.ts: -------------------------------------------------------------------------------- 1 | namespace StudentGroup { 2 | export class Student { 3 | marks: number[]; 4 | favouriteSubject: string; 5 | 6 | constructor(marks: number[], favouriteSubject: string) { 7 | this.marks = marks; 8 | this.favouriteSubject = favouriteSubject; 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/namespaces-demo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2022", 4 | "module": "CommonJS", 5 | "strict": true, 6 | "declaration": true, 7 | "declarationMap": true, 8 | "rootDir": "./src", 9 | "outDir": "./dist" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/vite-skeleton/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/vite-skeleton/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/vite-skeleton/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite-skeleton", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc && vite build", 9 | "preview": "vite preview" 10 | }, 11 | "devDependencies": { 12 | "typescript": "^5.2.2", 13 | "vite": "^5.2.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/vite-skeleton/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/vite-skeleton/src/main.ts: -------------------------------------------------------------------------------- 1 | import "./style.css"; 2 | import typescriptLogo from "./typescript.svg"; 3 | import viteLogo from "/vite.svg"; 4 | 5 | /// 6 | 7 | document.querySelector("#app")!.innerHTML = ` 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |

Vite + TypeScript

16 |
17 | 18 |
19 |

20 | Click on the Vite and TypeScript logos to learn more 21 |

22 |
23 | `; 24 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/vite-skeleton/src/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | 6 | color-scheme: light dark; 7 | color: rgba(255, 255, 255, 0.87); 8 | background-color: #242424; 9 | 10 | font-synthesis: none; 11 | text-rendering: optimizeLegibility; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | } 15 | 16 | a { 17 | font-weight: 500; 18 | color: #646cff; 19 | text-decoration: inherit; 20 | } 21 | a:hover { 22 | color: #535bf2; 23 | } 24 | 25 | body { 26 | margin: 0; 27 | display: flex; 28 | place-items: center; 29 | min-width: 320px; 30 | min-height: 100vh; 31 | } 32 | 33 | h1 { 34 | font-size: 3.2em; 35 | line-height: 1.1; 36 | } 37 | 38 | #app { 39 | max-width: 1280px; 40 | margin: 0 auto; 41 | padding: 2rem; 42 | text-align: center; 43 | } 44 | 45 | .logo { 46 | height: 6em; 47 | padding: 1.5em; 48 | will-change: filter; 49 | transition: filter 300ms; 50 | } 51 | .logo:hover { 52 | filter: drop-shadow(0 0 2em #646cffaa); 53 | } 54 | .logo.vanilla:hover { 55 | filter: drop-shadow(0 0 2em #3178c6aa); 56 | } 57 | 58 | .card { 59 | padding: 2em; 60 | } 61 | 62 | .read-the-docs { 63 | color: #888; 64 | } 65 | 66 | button { 67 | border-radius: 8px; 68 | border: 1px solid transparent; 69 | padding: 0.6em 1.2em; 70 | font-size: 1em; 71 | font-weight: 500; 72 | font-family: inherit; 73 | background-color: #1a1a1a; 74 | cursor: pointer; 75 | transition: border-color 0.25s; 76 | } 77 | button:hover { 78 | border-color: #646cff; 79 | } 80 | button:focus, 81 | button:focus-visible { 82 | outline: 4px auto -webkit-focus-ring-color; 83 | } 84 | 85 | @media (prefers-color-scheme: light) { 86 | :root { 87 | color: #213547; 88 | background-color: #ffffff; 89 | } 90 | a:hover { 91 | color: #747bff; 92 | } 93 | button { 94 | background-color: #f9f9f9; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/vite-skeleton/src/test.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | namespace Animal { 3 | export class Person { 4 | name: string = "Kiril"; 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/vite-skeleton/src/typescript.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/vite-skeleton/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/vite-skeleton/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true 21 | }, 22 | "include": ["src"] 23 | } 24 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/webpack-skeleton/dist/bundle.js: -------------------------------------------------------------------------------- 1 | (()=>{"use strict";console.log(123);const o=new class{name;constructor(o){this.name=o}}("Mitko");console.log(o.name)})(); -------------------------------------------------------------------------------- /5.NamespaceAndModules/webpack-skeleton/dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Webpack, hi! 7 | 8 | 9 | 10 |

Hello, webpack!

11 |

Hello TYPESCRIPT!

12 | 13 | 14 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/webpack-skeleton/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-skeleton", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "webpack --mode production", 8 | "dev": "webpack-dev-server --mode development" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "ts-loader": "^9.5.1", 15 | "typescript": "^5.4.5", 16 | "webpack": "^5.91.0", 17 | "webpack-cli": "^5.1.4", 18 | "webpack-dev-server": "^5.0.4" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/webpack-skeleton/src/index.ts: -------------------------------------------------------------------------------- 1 | class Person { 2 | name: string; 3 | constructor(name: string) { 4 | this.name = name; 5 | } 6 | } 7 | 8 | const p = new Person("Mitko"); 9 | console.log(p.name); 10 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/webpack-skeleton/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2022", 4 | "module": "ES6", 5 | "strict": true, 6 | "sourceMap": true 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /5.NamespaceAndModules/webpack-skeleton/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | 3 | module.exports = { 4 | entry: path.resolve(__dirname, "src/index.ts"), // Your entry TypeScript file 5 | devServer: { 6 | static: path.resolve(__dirname, "dist"), 7 | port: 3000, 8 | hot: true, 9 | open: true, 10 | compress: true, 11 | }, 12 | resolve: { 13 | extensions: [".ts", ".js"], 14 | }, 15 | output: { 16 | filename: "bundle.js", 17 | path: path.resolve(__dirname, "dist"), 18 | }, 19 | module: { 20 | rules: [ 21 | { 22 | test: /\.ts$/, 23 | use: "ts-loader", 24 | include: [path.resolve(__dirname, "src")], 25 | }, 26 | ], 27 | }, 28 | }; 29 | -------------------------------------------------------------------------------- /6.Decorators/accessor-demo.js: -------------------------------------------------------------------------------- 1 | var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { 2 | function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } 3 | var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; 4 | var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; 5 | var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); 6 | var _, done = false; 7 | for (var i = decorators.length - 1; i >= 0; i--) { 8 | var context = {}; 9 | for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; 10 | for (var p in contextIn.access) context.access[p] = contextIn.access[p]; 11 | context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; 12 | var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); 13 | if (kind === "accessor") { 14 | if (result === void 0) continue; 15 | if (result === null || typeof result !== "object") throw new TypeError("Object expected"); 16 | if (_ = accept(result.get)) descriptor.get = _; 17 | if (_ = accept(result.set)) descriptor.set = _; 18 | if (_ = accept(result.init)) initializers.unshift(_); 19 | } 20 | else if (_ = accept(result)) { 21 | if (kind === "field") initializers.unshift(_); 22 | else descriptor[key] = _; 23 | } 24 | } 25 | if (target) Object.defineProperty(target, contextIn.name, descriptor); 26 | done = true; 27 | }; 28 | var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) { 29 | var useValue = arguments.length > 2; 30 | for (var i = 0; i < initializers.length; i++) { 31 | value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); 32 | } 33 | return useValue ? value : void 0; 34 | }; 35 | let Person = (() => { 36 | let _project_decorators; 37 | let _project_initializers = []; 38 | let _project_extraInitializers = []; 39 | return class Person { 40 | static { 41 | const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0; 42 | _project_decorators = [watchChanges]; 43 | __esDecorate(this, null, _project_decorators, { kind: "accessor", name: "project", static: false, private: false, access: { has: obj => "project" in obj, get: obj => obj.project, set: (obj, value) => { obj.project = value; } }, metadata: _metadata }, _project_initializers, _project_extraInitializers); 44 | if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); 45 | } 46 | #project_accessor_storage = __runInitializers(this, _project_initializers, "Simple Project"); 47 | get project() { return this.#project_accessor_storage; } 48 | set project(value) { this.#project_accessor_storage = value; } 49 | constructor() { 50 | __runInitializers(this, _project_extraInitializers); 51 | } 52 | }; 53 | })(); 54 | const person = new Person(); 55 | console.log(person.project); 56 | person.project = "More complex project!"; 57 | function watchChanges(accessor, context) { 58 | return { 59 | get: function () { 60 | // console.log("get: ", this); 61 | return accessor.get.call(this); 62 | }, 63 | set: function (value) { 64 | // console.log("this", this); 65 | // console.log("value", value); 66 | console.log(`The property "${context.name.toString()}" has been set to "${value}"`); 67 | accessor.set.call(this, value); 68 | }, 69 | }; 70 | } 71 | -------------------------------------------------------------------------------- /6.Decorators/accessor-demo.ts: -------------------------------------------------------------------------------- 1 | class Person { 2 | @watchChanges 3 | // auto-accessor -> autogenerates getter and setter for our class protype 4 | accessor project: string = "Simple Project"; 5 | } 6 | 7 | const person = new Person(); 8 | console.log(person.project); 9 | person.project = "More complex project!"; 10 | 11 | type Accessor = { 12 | get: (this: T) => V; 13 | set: (this: T, value: V) => void; 14 | }; 15 | 16 | function watchChanges( 17 | accessor: Accessor, 18 | context: ClassAccessorDecoratorContext 19 | ) { 20 | return { 21 | get: function (this: T) { 22 | // console.log("get: ", this); 23 | return accessor.get.call(this); 24 | }, 25 | set: function (this: T, value: V) { 26 | // console.log("this", this); 27 | // console.log("value", value); 28 | console.log( 29 | `The property "${context.name.toString()}" has been set to "${value}"` 30 | ); 31 | accessor.set.call(this, value); 32 | }, 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /6.Decorators/class-demo.js: -------------------------------------------------------------------------------- 1 | var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { 2 | function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } 3 | var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; 4 | var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; 5 | var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); 6 | var _, done = false; 7 | for (var i = decorators.length - 1; i >= 0; i--) { 8 | var context = {}; 9 | for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; 10 | for (var p in contextIn.access) context.access[p] = contextIn.access[p]; 11 | context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; 12 | var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); 13 | if (kind === "accessor") { 14 | if (result === void 0) continue; 15 | if (result === null || typeof result !== "object") throw new TypeError("Object expected"); 16 | if (_ = accept(result.get)) descriptor.get = _; 17 | if (_ = accept(result.set)) descriptor.set = _; 18 | if (_ = accept(result.init)) initializers.unshift(_); 19 | } 20 | else if (_ = accept(result)) { 21 | if (kind === "field") initializers.unshift(_); 22 | else descriptor[key] = _; 23 | } 24 | } 25 | if (target) Object.defineProperty(target, contextIn.name, descriptor); 26 | done = true; 27 | }; 28 | var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) { 29 | var useValue = arguments.length > 2; 30 | for (var i = 0; i < initializers.length; i++) { 31 | value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); 32 | } 33 | return useValue ? value : void 0; 34 | }; 35 | let Manager = (() => { 36 | let _classDecorators = [withEmployementDatePrototype, withEmployementDate, printData]; 37 | let _classDescriptor; 38 | let _classExtraInitializers = []; 39 | let _classThis; 40 | var Manager = class { 41 | static { _classThis = this; } 42 | static { 43 | const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0; 44 | __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); 45 | Manager = _classThis = _classDescriptor.value; 46 | if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); 47 | __runInitializers(_classThis, _classExtraInitializers); 48 | } 49 | task = "Simple Task"; 50 | project = "Simple Project"; 51 | constructor() { 52 | console.log("Manager class has been initted!"); 53 | } 54 | }; 55 | return Manager = _classThis; 56 | })(); 57 | const manager = new Manager(); 58 | console.log(manager); 59 | console.log(manager.constructor.prototype); 60 | function withEmployementDatePrototype(value, context) { 61 | console.log("3. withEmployementDatePrototype invoked!"); 62 | value.prototype.employmentDate = new Date().toISOString(); 63 | } 64 | function withEmployementDate(baseClass, context) { 65 | console.log("2. withEmployementDate invoked!"); 66 | return class extends baseClass { 67 | employmentDate = new Date().toISOString(); 68 | constructor(...args) { 69 | super(...args); 70 | console.log(`Added employementDate property to the ${baseClass.name} class!`); 71 | } 72 | }; 73 | } 74 | function printData(value, context) { 75 | console.log("1. printData invoked!"); 76 | context.addInitializer(() => { 77 | console.log(`Class with name ${context.name} has been initialized!`); 78 | }); 79 | } 80 | -------------------------------------------------------------------------------- /6.Decorators/class-demo.ts: -------------------------------------------------------------------------------- 1 | @withEmployementDatePrototype 2 | @withEmployementDate 3 | @printData 4 | class Manager { 5 | task: string = "Simple Task"; 6 | project: string = "Simple Project"; 7 | 8 | constructor() { 9 | console.log("Manager class has been initted!"); 10 | } 11 | } 12 | 13 | const manager = new Manager(); 14 | console.log(manager); 15 | console.log(manager.constructor.prototype); 16 | 17 | function withEmployementDatePrototype( 18 | value: Function, 19 | context: ClassDecoratorContext 20 | ) { 21 | console.log("3. withEmployementDatePrototype invoked!"); 22 | value.prototype.employmentDate = new Date().toISOString(); 23 | } 24 | 25 | type Args = { new (...args: any[]): {} }; 26 | 27 | function withEmployementDate( 28 | baseClass: T, 29 | context: ClassDecoratorContext 30 | ) { 31 | console.log("2. withEmployementDate invoked!"); 32 | 33 | return class extends baseClass { 34 | employmentDate = new Date().toISOString(); 35 | 36 | constructor(...args: any[]) { 37 | super(...args); 38 | 39 | console.log( 40 | `Added employementDate property to the ${baseClass.name} class!` 41 | ); 42 | } 43 | }; 44 | } 45 | 46 | function printData(value: Function, context: ClassDecoratorContext) { 47 | console.log("1. printData invoked!"); 48 | 49 | context.addInitializer(() => { 50 | console.log(`Class with name ${context.name} has been initialized!`); 51 | }); 52 | } 53 | -------------------------------------------------------------------------------- /6.Decorators/factory-demo.js: -------------------------------------------------------------------------------- 1 | var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { 2 | function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } 3 | var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; 4 | var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; 5 | var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); 6 | var _, done = false; 7 | for (var i = decorators.length - 1; i >= 0; i--) { 8 | var context = {}; 9 | for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; 10 | for (var p in contextIn.access) context.access[p] = contextIn.access[p]; 11 | context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; 12 | var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); 13 | if (kind === "accessor") { 14 | if (result === void 0) continue; 15 | if (result === null || typeof result !== "object") throw new TypeError("Object expected"); 16 | if (_ = accept(result.get)) descriptor.get = _; 17 | if (_ = accept(result.set)) descriptor.set = _; 18 | if (_ = accept(result.init)) initializers.unshift(_); 19 | } 20 | else if (_ = accept(result)) { 21 | if (kind === "field") initializers.unshift(_); 22 | else descriptor[key] = _; 23 | } 24 | } 25 | if (target) Object.defineProperty(target, contextIn.name, descriptor); 26 | done = true; 27 | }; 28 | var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) { 29 | var useValue = arguments.length > 2; 30 | for (var i = 0; i < initializers.length; i++) { 31 | value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); 32 | } 33 | return useValue ? value : void 0; 34 | }; 35 | let Employee = (() => { 36 | let _tasks_decorators; 37 | let _tasks_initializers = []; 38 | let _tasks_extraInitializers = []; 39 | let _extraTasks_decorators; 40 | let _extraTasks_initializers = []; 41 | let _extraTasks_extraInitializers = []; 42 | return class Employee { 43 | static { 44 | const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0; 45 | _tasks_decorators = [withTask({ name: "Task - 1", level: "mediun" })]; 46 | _extraTasks_decorators = [withComplicatedTask()]; 47 | __esDecorate(null, null, _tasks_decorators, { kind: "field", name: "tasks", static: false, private: false, access: { has: obj => "tasks" in obj, get: obj => obj.tasks, set: (obj, value) => { obj.tasks = value; } }, metadata: _metadata }, _tasks_initializers, _tasks_extraInitializers); 48 | __esDecorate(null, null, _extraTasks_decorators, { kind: "field", name: "extraTasks", static: false, private: false, access: { has: obj => "extraTasks" in obj, get: obj => obj.extraTasks, set: (obj, value) => { obj.extraTasks = value; } }, metadata: _metadata }, _extraTasks_initializers, _extraTasks_extraInitializers); 49 | if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); 50 | } 51 | tasks = __runInitializers(this, _tasks_initializers, []); 52 | extraTasks = (__runInitializers(this, _tasks_extraInitializers), __runInitializers(this, _extraTasks_initializers, [])); 53 | constructor() { 54 | __runInitializers(this, _extraTasks_extraInitializers); 55 | } 56 | }; 57 | })(); 58 | const employee = new Employee(); 59 | console.log(employee); 60 | // Decorator's scope 61 | function withTask(inputTask) { 62 | // Filed's scp[e] 63 | return function (target, context) { 64 | return function (fieldValue) { 65 | fieldValue.push(inputTask); 66 | return fieldValue; 67 | }; 68 | }; 69 | } 70 | function withComplicatedTask() { 71 | // logic 72 | return withTask({ name: "Task - 0", level: "hard" }); 73 | } 74 | -------------------------------------------------------------------------------- /6.Decorators/factory-demo.ts: -------------------------------------------------------------------------------- 1 | type Level = "low" | "mediun" | "hard"; 2 | 3 | interface Task { 4 | name: string; 5 | level: Level; 6 | } 7 | 8 | class Employee { 9 | @withTask({ name: "Task - 1", level: "mediun" }) 10 | tasks: Task[] = []; 11 | 12 | @withComplicatedTask() 13 | extraTasks: Task[] = []; 14 | } 15 | const employee = new Employee(); 16 | console.log(employee); 17 | 18 | // Decorator's scope 19 | function withTask(inputTask: Task) { 20 | // Filed's scp[e] 21 | return function ( 22 | target: undefined, 23 | context: ClassFieldDecoratorContext 24 | ) { 25 | return function (fieldValue: V) { 26 | fieldValue.push(inputTask); 27 | return fieldValue; 28 | }; 29 | }; 30 | } 31 | 32 | function withComplicatedTask() { 33 | // logic 34 | // based on input -> different decorators can be returned 35 | return withTask({ name: "Task - 0", level: "hard" }); 36 | } 37 | -------------------------------------------------------------------------------- /6.Decorators/method-demo.js: -------------------------------------------------------------------------------- 1 | var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) { 2 | var useValue = arguments.length > 2; 3 | for (var i = 0; i < initializers.length; i++) { 4 | value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); 5 | } 6 | return useValue ? value : void 0; 7 | }; 8 | var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { 9 | function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } 10 | var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; 11 | var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; 12 | var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); 13 | var _, done = false; 14 | for (var i = decorators.length - 1; i >= 0; i--) { 15 | var context = {}; 16 | for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; 17 | for (var p in contextIn.access) context.access[p] = contextIn.access[p]; 18 | context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; 19 | var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); 20 | if (kind === "accessor") { 21 | if (result === void 0) continue; 22 | if (result === null || typeof result !== "object") throw new TypeError("Object expected"); 23 | if (_ = accept(result.get)) descriptor.get = _; 24 | if (_ = accept(result.set)) descriptor.set = _; 25 | if (_ = accept(result.init)) initializers.unshift(_); 26 | } 27 | else if (_ = accept(result)) { 28 | if (kind === "field") initializers.unshift(_); 29 | else descriptor[key] = _; 30 | } 31 | } 32 | if (target) Object.defineProperty(target, contextIn.name, descriptor); 33 | done = true; 34 | }; 35 | let Project = (() => { 36 | let _instanceExtraInitializers = []; 37 | let _writeTest_decorators; 38 | let _fixBugInProduction_decorators; 39 | return class Project { 40 | static { 41 | const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0; 42 | _writeTest_decorators = [withBudget(10)]; 43 | _fixBugInProduction_decorators = [withBudget(300)]; 44 | __esDecorate(this, null, _writeTest_decorators, { kind: "method", name: "writeTest", static: false, private: false, access: { has: obj => "writeTest" in obj, get: obj => obj.writeTest }, metadata: _metadata }, null, _instanceExtraInitializers); 45 | __esDecorate(this, null, _fixBugInProduction_decorators, { kind: "method", name: "fixBugInProduction", static: false, private: false, access: { has: obj => "fixBugInProduction" in obj, get: obj => obj.fixBugInProduction }, metadata: _metadata }, null, _instanceExtraInitializers); 46 | if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); 47 | } 48 | budget = (__runInitializers(this, _instanceExtraInitializers), 900); 49 | writeTest() { 50 | console.log("Tests are important!"); 51 | } 52 | fixBugInProduction() { 53 | console.log("Fixing bugs in production is expensive!"); 54 | } 55 | }; 56 | })(); 57 | const project = new Project(); 58 | project.writeTest(); 59 | project.fixBugInProduction(); 60 | project.fixBugInProduction(); 61 | project.writeTest(); 62 | project.fixBugInProduction(); 63 | console.log(project.budget); 64 | // DECORATOR's scope 65 | function withBudget(actionBudget) { 66 | // Connect between CLASS and FUNCTION 67 | return function (target, context) { 68 | // FUNCTION's scope => fixBugInProduction/writeTest 69 | return function (...args) { 70 | const instance = this; // T -> our decorate class 71 | if (instance.budget > actionBudget) { 72 | instance.budget -= actionBudget; 73 | target.apply(instance, args); // calls our method 74 | } 75 | else { 76 | console.log(`Insufficient funds for ${context.name.toString()} operation. Required: ${actionBudget}!`); 77 | } 78 | }; 79 | }; 80 | } 81 | -------------------------------------------------------------------------------- /6.Decorators/method-demo.ts: -------------------------------------------------------------------------------- 1 | class Project { 2 | budget: number = 900; 3 | 4 | @withBudget(10) 5 | writeTest() { 6 | console.log("Tests are important!"); 7 | } 8 | 9 | @withBudget(300) 10 | fixBugInProduction() { 11 | console.log("Fixing bugs in production is expensive!"); 12 | } 13 | } 14 | 15 | const project = new Project(); 16 | project.writeTest(); 17 | project.fixBugInProduction(); 18 | project.fixBugInProduction(); 19 | project.writeTest(); 20 | project.fixBugInProduction(); 21 | console.log(project.budget); 22 | 23 | type WithBudget = { 24 | budget: number; 25 | }; 26 | 27 | // DECORATOR's scope 28 | function withBudget(actionBudget: number) { 29 | // Connect between CLASS and FUNCTION 30 | return function (target: Function, context: ClassMethodDecoratorContext) { 31 | // FUNCTION's scope => fixBugInProduction/writeTest 32 | return function (...args: any) { 33 | const instance = this as T; // T -> our decorate class 34 | 35 | if (instance.budget > actionBudget) { 36 | instance.budget -= actionBudget; 37 | target.apply(instance, args); // calls our method 38 | } else { 39 | console.log( 40 | `Insufficient funds for ${context.name.toString()} operation. Required: ${actionBudget}!` 41 | ); 42 | } 43 | }; 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /6.Decorators/parameter-demo.js: -------------------------------------------------------------------------------- 1 | var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) { 2 | var useValue = arguments.length > 2; 3 | for (var i = 0; i < initializers.length; i++) { 4 | value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); 5 | } 6 | return useValue ? value : void 0; 7 | }; 8 | var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { 9 | function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } 10 | var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; 11 | var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; 12 | var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); 13 | var _, done = false; 14 | for (var i = decorators.length - 1; i >= 0; i--) { 15 | var context = {}; 16 | for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; 17 | for (var p in contextIn.access) context.access[p] = contextIn.access[p]; 18 | context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; 19 | var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); 20 | if (kind === "accessor") { 21 | if (result === void 0) continue; 22 | if (result === null || typeof result !== "object") throw new TypeError("Object expected"); 23 | if (_ = accept(result.get)) descriptor.get = _; 24 | if (_ = accept(result.set)) descriptor.set = _; 25 | if (_ = accept(result.init)) initializers.unshift(_); 26 | } 27 | else if (_ = accept(result)) { 28 | if (kind === "field") initializers.unshift(_); 29 | else descriptor[key] = _; 30 | } 31 | } 32 | if (target) Object.defineProperty(target, contextIn.name, descriptor); 33 | done = true; 34 | }; 35 | let Animal = (() => { 36 | let _instanceExtraInitializers = []; 37 | let _eat_decorators; 38 | return class Animal { 39 | static { 40 | const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0; 41 | _eat_decorators = [validateParams]; 42 | __esDecorate(this, null, _eat_decorators, { kind: "method", name: "eat", static: false, private: false, access: { has: obj => "eat" in obj, get: obj => obj.eat }, metadata: _metadata }, null, _instanceExtraInitializers); 43 | if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); 44 | } 45 | eat(arg1, arg2) { 46 | console.log(`Received params: ${arg1}, ${arg2}`); 47 | } 48 | constructor() { 49 | __runInitializers(this, _instanceExtraInitializers); 50 | } 51 | }; 52 | })(); 53 | // Decorator's scope 54 | function validateParams(target, context) { 55 | // Function's scope 56 | return function (...args) { 57 | for (let i = 0; i < args.length; i++) { 58 | const currentArg = args[i]; 59 | if (currentArg === undefined || currentArg === null) { 60 | throw new Error(`Parameter at index ${i} is invalid! Parameter: ${currentArg}`); 61 | } 62 | } 63 | if (args.length < 2) { 64 | throw new Error(`Parameters must be 2!`); 65 | } 66 | target.apply(this, args); 67 | }; 68 | } 69 | const animal = new Animal(); 70 | animal.eat("Veggie", 123); // ['Veggie'] 71 | -------------------------------------------------------------------------------- /6.Decorators/parameter-demo.ts: -------------------------------------------------------------------------------- 1 | class Animal { 2 | @validateParams 3 | eat(arg1?: string, arg2?: number) { 4 | console.log(`Received params: ${arg1}, ${arg2}`); 5 | } 6 | } 7 | 8 | // Decorator's scope 9 | function validateParams( 10 | target: Function, 11 | context: ClassMethodDecoratorContext 12 | ) { 13 | // Function's scope 14 | return function (...args: any) { 15 | for (let i = 0; i < args.length; i++) { 16 | const currentArg = args[i]; 17 | 18 | if (currentArg === undefined || currentArg === null) { 19 | throw new Error( 20 | `Parameter at index ${i} is invalid! Parameter: ${currentArg}` 21 | ); 22 | } 23 | } 24 | 25 | if (args.length < 2) { 26 | throw new Error(`Parameters must be 2!`); 27 | } 28 | 29 | target.apply(this, args); 30 | }; 31 | } 32 | 33 | const animal = new Animal(); 34 | animal.eat("Veggie", 123); // ['Veggie'] 35 | -------------------------------------------------------------------------------- /6.Decorators/property-demo.js: -------------------------------------------------------------------------------- 1 | // type Task = { 2 | // name: string; 3 | // level: "low" | "medium" | "hard"; 4 | // }; 5 | // class Employee { 6 | // @withMoreTasks 7 | // tasks: Task[] = []; 8 | // } 9 | // const employee1 = new Employee(); 10 | // console.log(employee1); 11 | // const employee2 = new Employee(); 12 | // console.log(employee2); 13 | // // Decorator scope 14 | // function withMoreTasks( 15 | // target: undefined, 16 | // context: ClassFieldDecoratorContext 17 | // ) { 18 | // // Property scope 19 | // return function (fieldValue: V) { 20 | // // API call -> async 21 | // fieldValue.push({ name: "Do your homework!", level: "medium" }); 22 | // fieldValue.push({ name: "Go to work!", level: "low" }); 23 | // fieldValue.push({ name: "Go to the GYM!", level: "hard" }); 24 | // return fieldValue; 25 | // }; 26 | // } 27 | -------------------------------------------------------------------------------- /6.Decorators/property-demo.ts: -------------------------------------------------------------------------------- 1 | // type Task = { 2 | // name: string; 3 | // level: "low" | "medium" | "hard"; 4 | // }; 5 | 6 | // class Employee { 7 | // @withMoreTasks 8 | // tasks: Task[] = []; 9 | // } 10 | 11 | // const employee1 = new Employee(); 12 | // console.log(employee1); 13 | 14 | // const employee2 = new Employee(); 15 | // console.log(employee2); 16 | 17 | // // Decorator scope 18 | // function withMoreTasks( 19 | // target: undefined, 20 | // context: ClassFieldDecoratorContext 21 | // ) { 22 | // // Property scope 23 | // return function (fieldValue: V) { 24 | // // API call -> async 25 | // fieldValue.push({ name: "Do your homework!", level: "medium" }); 26 | // fieldValue.push({ name: "Go to work!", level: "low" }); 27 | // fieldValue.push({ name: "Go to the GYM!", level: "hard" }); 28 | 29 | // return fieldValue; 30 | // }; 31 | // } 32 | -------------------------------------------------------------------------------- /6.Decorators/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /** Decorators Stage 2 */ 4 | // "target": "ES5", 5 | // "experimentalDecorators": true, 6 | // "emitDecoratorMetadata": true 7 | 8 | /** Decorators Stage 3 - TypeScript version 5 and above */ 9 | "target": "ES2022" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /7.Workshop/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /7.Workshop/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Workshop 8 | 9 | 10 |
11 | 15 | 16 |
17 |
18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /7.Workshop/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "7-workshop", 3 | "version": "0.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "7-workshop", 9 | "version": "0.0.0", 10 | "devDependencies": { 11 | "typescript": "^5.2.2", 12 | "vite": "^5.2.0" 13 | } 14 | }, 15 | "node_modules/@esbuild/aix-ppc64": { 16 | "version": "0.20.2", 17 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", 18 | "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", 19 | "cpu": [ 20 | "ppc64" 21 | ], 22 | "dev": true, 23 | "optional": true, 24 | "os": [ 25 | "aix" 26 | ], 27 | "engines": { 28 | "node": ">=12" 29 | } 30 | }, 31 | "node_modules/@esbuild/android-arm": { 32 | "version": "0.20.2", 33 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", 34 | "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", 35 | "cpu": [ 36 | "arm" 37 | ], 38 | "dev": true, 39 | "optional": true, 40 | "os": [ 41 | "android" 42 | ], 43 | "engines": { 44 | "node": ">=12" 45 | } 46 | }, 47 | "node_modules/@esbuild/android-arm64": { 48 | "version": "0.20.2", 49 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", 50 | "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", 51 | "cpu": [ 52 | "arm64" 53 | ], 54 | "dev": true, 55 | "optional": true, 56 | "os": [ 57 | "android" 58 | ], 59 | "engines": { 60 | "node": ">=12" 61 | } 62 | }, 63 | "node_modules/@esbuild/android-x64": { 64 | "version": "0.20.2", 65 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", 66 | "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", 67 | "cpu": [ 68 | "x64" 69 | ], 70 | "dev": true, 71 | "optional": true, 72 | "os": [ 73 | "android" 74 | ], 75 | "engines": { 76 | "node": ">=12" 77 | } 78 | }, 79 | "node_modules/@esbuild/darwin-arm64": { 80 | "version": "0.20.2", 81 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", 82 | "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", 83 | "cpu": [ 84 | "arm64" 85 | ], 86 | "dev": true, 87 | "optional": true, 88 | "os": [ 89 | "darwin" 90 | ], 91 | "engines": { 92 | "node": ">=12" 93 | } 94 | }, 95 | "node_modules/@esbuild/darwin-x64": { 96 | "version": "0.20.2", 97 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", 98 | "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", 99 | "cpu": [ 100 | "x64" 101 | ], 102 | "dev": true, 103 | "optional": true, 104 | "os": [ 105 | "darwin" 106 | ], 107 | "engines": { 108 | "node": ">=12" 109 | } 110 | }, 111 | "node_modules/@esbuild/freebsd-arm64": { 112 | "version": "0.20.2", 113 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", 114 | "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", 115 | "cpu": [ 116 | "arm64" 117 | ], 118 | "dev": true, 119 | "optional": true, 120 | "os": [ 121 | "freebsd" 122 | ], 123 | "engines": { 124 | "node": ">=12" 125 | } 126 | }, 127 | "node_modules/@esbuild/freebsd-x64": { 128 | "version": "0.20.2", 129 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", 130 | "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", 131 | "cpu": [ 132 | "x64" 133 | ], 134 | "dev": true, 135 | "optional": true, 136 | "os": [ 137 | "freebsd" 138 | ], 139 | "engines": { 140 | "node": ">=12" 141 | } 142 | }, 143 | "node_modules/@esbuild/linux-arm": { 144 | "version": "0.20.2", 145 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", 146 | "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", 147 | "cpu": [ 148 | "arm" 149 | ], 150 | "dev": true, 151 | "optional": true, 152 | "os": [ 153 | "linux" 154 | ], 155 | "engines": { 156 | "node": ">=12" 157 | } 158 | }, 159 | "node_modules/@esbuild/linux-arm64": { 160 | "version": "0.20.2", 161 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", 162 | "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", 163 | "cpu": [ 164 | "arm64" 165 | ], 166 | "dev": true, 167 | "optional": true, 168 | "os": [ 169 | "linux" 170 | ], 171 | "engines": { 172 | "node": ">=12" 173 | } 174 | }, 175 | "node_modules/@esbuild/linux-ia32": { 176 | "version": "0.20.2", 177 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", 178 | "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", 179 | "cpu": [ 180 | "ia32" 181 | ], 182 | "dev": true, 183 | "optional": true, 184 | "os": [ 185 | "linux" 186 | ], 187 | "engines": { 188 | "node": ">=12" 189 | } 190 | }, 191 | "node_modules/@esbuild/linux-loong64": { 192 | "version": "0.20.2", 193 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", 194 | "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", 195 | "cpu": [ 196 | "loong64" 197 | ], 198 | "dev": true, 199 | "optional": true, 200 | "os": [ 201 | "linux" 202 | ], 203 | "engines": { 204 | "node": ">=12" 205 | } 206 | }, 207 | "node_modules/@esbuild/linux-mips64el": { 208 | "version": "0.20.2", 209 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", 210 | "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", 211 | "cpu": [ 212 | "mips64el" 213 | ], 214 | "dev": true, 215 | "optional": true, 216 | "os": [ 217 | "linux" 218 | ], 219 | "engines": { 220 | "node": ">=12" 221 | } 222 | }, 223 | "node_modules/@esbuild/linux-ppc64": { 224 | "version": "0.20.2", 225 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", 226 | "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", 227 | "cpu": [ 228 | "ppc64" 229 | ], 230 | "dev": true, 231 | "optional": true, 232 | "os": [ 233 | "linux" 234 | ], 235 | "engines": { 236 | "node": ">=12" 237 | } 238 | }, 239 | "node_modules/@esbuild/linux-riscv64": { 240 | "version": "0.20.2", 241 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", 242 | "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", 243 | "cpu": [ 244 | "riscv64" 245 | ], 246 | "dev": true, 247 | "optional": true, 248 | "os": [ 249 | "linux" 250 | ], 251 | "engines": { 252 | "node": ">=12" 253 | } 254 | }, 255 | "node_modules/@esbuild/linux-s390x": { 256 | "version": "0.20.2", 257 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", 258 | "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", 259 | "cpu": [ 260 | "s390x" 261 | ], 262 | "dev": true, 263 | "optional": true, 264 | "os": [ 265 | "linux" 266 | ], 267 | "engines": { 268 | "node": ">=12" 269 | } 270 | }, 271 | "node_modules/@esbuild/linux-x64": { 272 | "version": "0.20.2", 273 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", 274 | "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", 275 | "cpu": [ 276 | "x64" 277 | ], 278 | "dev": true, 279 | "optional": true, 280 | "os": [ 281 | "linux" 282 | ], 283 | "engines": { 284 | "node": ">=12" 285 | } 286 | }, 287 | "node_modules/@esbuild/netbsd-x64": { 288 | "version": "0.20.2", 289 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", 290 | "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", 291 | "cpu": [ 292 | "x64" 293 | ], 294 | "dev": true, 295 | "optional": true, 296 | "os": [ 297 | "netbsd" 298 | ], 299 | "engines": { 300 | "node": ">=12" 301 | } 302 | }, 303 | "node_modules/@esbuild/openbsd-x64": { 304 | "version": "0.20.2", 305 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", 306 | "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", 307 | "cpu": [ 308 | "x64" 309 | ], 310 | "dev": true, 311 | "optional": true, 312 | "os": [ 313 | "openbsd" 314 | ], 315 | "engines": { 316 | "node": ">=12" 317 | } 318 | }, 319 | "node_modules/@esbuild/sunos-x64": { 320 | "version": "0.20.2", 321 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", 322 | "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", 323 | "cpu": [ 324 | "x64" 325 | ], 326 | "dev": true, 327 | "optional": true, 328 | "os": [ 329 | "sunos" 330 | ], 331 | "engines": { 332 | "node": ">=12" 333 | } 334 | }, 335 | "node_modules/@esbuild/win32-arm64": { 336 | "version": "0.20.2", 337 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", 338 | "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", 339 | "cpu": [ 340 | "arm64" 341 | ], 342 | "dev": true, 343 | "optional": true, 344 | "os": [ 345 | "win32" 346 | ], 347 | "engines": { 348 | "node": ">=12" 349 | } 350 | }, 351 | "node_modules/@esbuild/win32-ia32": { 352 | "version": "0.20.2", 353 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", 354 | "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", 355 | "cpu": [ 356 | "ia32" 357 | ], 358 | "dev": true, 359 | "optional": true, 360 | "os": [ 361 | "win32" 362 | ], 363 | "engines": { 364 | "node": ">=12" 365 | } 366 | }, 367 | "node_modules/@esbuild/win32-x64": { 368 | "version": "0.20.2", 369 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", 370 | "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", 371 | "cpu": [ 372 | "x64" 373 | ], 374 | "dev": true, 375 | "optional": true, 376 | "os": [ 377 | "win32" 378 | ], 379 | "engines": { 380 | "node": ">=12" 381 | } 382 | }, 383 | "node_modules/@rollup/rollup-android-arm-eabi": { 384 | "version": "4.16.2", 385 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.16.2.tgz", 386 | "integrity": "sha512-VGodkwtEuZ+ENPz/CpDSl091koMv8ao5jHVMbG1vNK+sbx/48/wVzP84M5xSfDAC69mAKKoEkSo+ym9bXYRK9w==", 387 | "cpu": [ 388 | "arm" 389 | ], 390 | "dev": true, 391 | "optional": true, 392 | "os": [ 393 | "android" 394 | ] 395 | }, 396 | "node_modules/@rollup/rollup-android-arm64": { 397 | "version": "4.16.2", 398 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.16.2.tgz", 399 | "integrity": "sha512-5/W1xyIdc7jw6c/f1KEtg1vYDBWnWCsLiipK41NiaWGLG93eH2edgE6EgQJ3AGiPERhiOLUqlDSfjRK08C9xFg==", 400 | "cpu": [ 401 | "arm64" 402 | ], 403 | "dev": true, 404 | "optional": true, 405 | "os": [ 406 | "android" 407 | ] 408 | }, 409 | "node_modules/@rollup/rollup-darwin-arm64": { 410 | "version": "4.16.2", 411 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.16.2.tgz", 412 | "integrity": "sha512-vOAKMqZSTbPfyPVu1jBiy+YniIQd3MG7LUnqV0dA6Q5tyhdqYtxacTHP1+S/ksKl6qCtMG1qQ0grcIgk/19JEA==", 413 | "cpu": [ 414 | "arm64" 415 | ], 416 | "dev": true, 417 | "optional": true, 418 | "os": [ 419 | "darwin" 420 | ] 421 | }, 422 | "node_modules/@rollup/rollup-darwin-x64": { 423 | "version": "4.16.2", 424 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.16.2.tgz", 425 | "integrity": "sha512-aIJVRUS3Dnj6MqocBMrcXlatKm64O3ITeQAdAxVSE9swyhNyV1dwnRgw7IGKIkDQofatd8UqMSyUxuFEa42EcA==", 426 | "cpu": [ 427 | "x64" 428 | ], 429 | "dev": true, 430 | "optional": true, 431 | "os": [ 432 | "darwin" 433 | ] 434 | }, 435 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": { 436 | "version": "4.16.2", 437 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.16.2.tgz", 438 | "integrity": "sha512-/bjfUiXwy3P5vYr6/ezv//Yle2Y0ak3a+Av/BKoi76nFryjWCkki8AuVoPR7ZU/ckcvAWFo77OnFK14B9B5JsA==", 439 | "cpu": [ 440 | "arm" 441 | ], 442 | "dev": true, 443 | "optional": true, 444 | "os": [ 445 | "linux" 446 | ] 447 | }, 448 | "node_modules/@rollup/rollup-linux-arm-musleabihf": { 449 | "version": "4.16.2", 450 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.16.2.tgz", 451 | "integrity": "sha512-S24b+tJHwpq2TNRz9T+r71FjMvyBBApY8EkYxz8Cwi/rhH6h+lu/iDUxyc9PuHf9UvyeBFYkWWcrDahai/NCGw==", 452 | "cpu": [ 453 | "arm" 454 | ], 455 | "dev": true, 456 | "optional": true, 457 | "os": [ 458 | "linux" 459 | ] 460 | }, 461 | "node_modules/@rollup/rollup-linux-arm64-gnu": { 462 | "version": "4.16.2", 463 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.16.2.tgz", 464 | "integrity": "sha512-UN7VAXLyeyGbCQWiOtQN7BqmjTDw1ON2Oos4lfk0YR7yNhFEJWZiwGtvj9Ay4lsT/ueT04sh80Sg2MlWVVZ+Ug==", 465 | "cpu": [ 466 | "arm64" 467 | ], 468 | "dev": true, 469 | "optional": true, 470 | "os": [ 471 | "linux" 472 | ] 473 | }, 474 | "node_modules/@rollup/rollup-linux-arm64-musl": { 475 | "version": "4.16.2", 476 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.16.2.tgz", 477 | "integrity": "sha512-ZBKvz3+rIhQjusKMccuJiPsStCrPOtejCHxTe+yWp3tNnuPWtyCh9QLGPKz6bFNFbwbw28E2T6zDgzJZ05F1JQ==", 478 | "cpu": [ 479 | "arm64" 480 | ], 481 | "dev": true, 482 | "optional": true, 483 | "os": [ 484 | "linux" 485 | ] 486 | }, 487 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { 488 | "version": "4.16.2", 489 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.16.2.tgz", 490 | "integrity": "sha512-LjMMFiVBRL3wOe095vHAekL4b7nQqf4KZEpdMWd3/W+nIy5o9q/8tlVKiqMbfieDypNXLsxM9fexOxd9Qcklyg==", 491 | "cpu": [ 492 | "ppc64" 493 | ], 494 | "dev": true, 495 | "optional": true, 496 | "os": [ 497 | "linux" 498 | ] 499 | }, 500 | "node_modules/@rollup/rollup-linux-riscv64-gnu": { 501 | "version": "4.16.2", 502 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.16.2.tgz", 503 | "integrity": "sha512-ohkPt0lKoCU0s4B6twro2aft+QROPdUiWwOjPNTzwTsBK5w+2+iT9kySdtOdq0gzWJAdiqsV4NFtXOwGZmIsHA==", 504 | "cpu": [ 505 | "riscv64" 506 | ], 507 | "dev": true, 508 | "optional": true, 509 | "os": [ 510 | "linux" 511 | ] 512 | }, 513 | "node_modules/@rollup/rollup-linux-s390x-gnu": { 514 | "version": "4.16.2", 515 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.16.2.tgz", 516 | "integrity": "sha512-jm2lvLc+/gqXfndlpDw05jKvsl/HKYxUEAt1h5UXcMFVpO4vGpoWmJVUfKDtTqSaHcCNw1his1XjkgR9aort3w==", 517 | "cpu": [ 518 | "s390x" 519 | ], 520 | "dev": true, 521 | "optional": true, 522 | "os": [ 523 | "linux" 524 | ] 525 | }, 526 | "node_modules/@rollup/rollup-linux-x64-gnu": { 527 | "version": "4.16.2", 528 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.16.2.tgz", 529 | "integrity": "sha512-oc5/SlITI/Vj/qL4UM+lXN7MERpiy1HEOnrE+SegXwzf7WP9bzmZd6+MDljCEZTdSY84CpvUv9Rq7bCaftn1+g==", 530 | "cpu": [ 531 | "x64" 532 | ], 533 | "dev": true, 534 | "optional": true, 535 | "os": [ 536 | "linux" 537 | ] 538 | }, 539 | "node_modules/@rollup/rollup-linux-x64-musl": { 540 | "version": "4.16.2", 541 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.16.2.tgz", 542 | "integrity": "sha512-/2VWEBG6mKbS2itm7hzPwhIPaxfZh/KLWrYg20pCRLHhNFtF+epLgcBtwy3m07bl/k86Q3PFRAf2cX+VbZbwzQ==", 543 | "cpu": [ 544 | "x64" 545 | ], 546 | "dev": true, 547 | "optional": true, 548 | "os": [ 549 | "linux" 550 | ] 551 | }, 552 | "node_modules/@rollup/rollup-win32-arm64-msvc": { 553 | "version": "4.16.2", 554 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.16.2.tgz", 555 | "integrity": "sha512-Wg7ANh7+hSilF0lG3e/0Oy8GtfTIfEk1327Bw8juZOMOoKmJLs3R+a4JDa/4cHJp2Gs7QfCDTepXXcyFD0ubBg==", 556 | "cpu": [ 557 | "arm64" 558 | ], 559 | "dev": true, 560 | "optional": true, 561 | "os": [ 562 | "win32" 563 | ] 564 | }, 565 | "node_modules/@rollup/rollup-win32-ia32-msvc": { 566 | "version": "4.16.2", 567 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.16.2.tgz", 568 | "integrity": "sha512-J/jCDKVMWp0Y2ELnTjpQFYUCUWv1Jr+LdFrJVZtdqGyjDo0PHPa7pCamjHvJel6zBFM3doFFqAr7cmXYWBAbfw==", 569 | "cpu": [ 570 | "ia32" 571 | ], 572 | "dev": true, 573 | "optional": true, 574 | "os": [ 575 | "win32" 576 | ] 577 | }, 578 | "node_modules/@rollup/rollup-win32-x64-msvc": { 579 | "version": "4.16.2", 580 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.16.2.tgz", 581 | "integrity": "sha512-3nIf+SJMs2ZzrCh+SKNqgLVV9hS/UY0UjT1YU8XQYFGLiUfmHYJ/5trOU1XSvmHjV5gTF/K3DjrWxtyzKKcAHA==", 582 | "cpu": [ 583 | "x64" 584 | ], 585 | "dev": true, 586 | "optional": true, 587 | "os": [ 588 | "win32" 589 | ] 590 | }, 591 | "node_modules/@types/estree": { 592 | "version": "1.0.5", 593 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", 594 | "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", 595 | "dev": true 596 | }, 597 | "node_modules/esbuild": { 598 | "version": "0.20.2", 599 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", 600 | "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", 601 | "dev": true, 602 | "hasInstallScript": true, 603 | "bin": { 604 | "esbuild": "bin/esbuild" 605 | }, 606 | "engines": { 607 | "node": ">=12" 608 | }, 609 | "optionalDependencies": { 610 | "@esbuild/aix-ppc64": "0.20.2", 611 | "@esbuild/android-arm": "0.20.2", 612 | "@esbuild/android-arm64": "0.20.2", 613 | "@esbuild/android-x64": "0.20.2", 614 | "@esbuild/darwin-arm64": "0.20.2", 615 | "@esbuild/darwin-x64": "0.20.2", 616 | "@esbuild/freebsd-arm64": "0.20.2", 617 | "@esbuild/freebsd-x64": "0.20.2", 618 | "@esbuild/linux-arm": "0.20.2", 619 | "@esbuild/linux-arm64": "0.20.2", 620 | "@esbuild/linux-ia32": "0.20.2", 621 | "@esbuild/linux-loong64": "0.20.2", 622 | "@esbuild/linux-mips64el": "0.20.2", 623 | "@esbuild/linux-ppc64": "0.20.2", 624 | "@esbuild/linux-riscv64": "0.20.2", 625 | "@esbuild/linux-s390x": "0.20.2", 626 | "@esbuild/linux-x64": "0.20.2", 627 | "@esbuild/netbsd-x64": "0.20.2", 628 | "@esbuild/openbsd-x64": "0.20.2", 629 | "@esbuild/sunos-x64": "0.20.2", 630 | "@esbuild/win32-arm64": "0.20.2", 631 | "@esbuild/win32-ia32": "0.20.2", 632 | "@esbuild/win32-x64": "0.20.2" 633 | } 634 | }, 635 | "node_modules/fsevents": { 636 | "version": "2.3.3", 637 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 638 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 639 | "dev": true, 640 | "hasInstallScript": true, 641 | "optional": true, 642 | "os": [ 643 | "darwin" 644 | ], 645 | "engines": { 646 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 647 | } 648 | }, 649 | "node_modules/nanoid": { 650 | "version": "3.3.7", 651 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", 652 | "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", 653 | "dev": true, 654 | "funding": [ 655 | { 656 | "type": "github", 657 | "url": "https://github.com/sponsors/ai" 658 | } 659 | ], 660 | "bin": { 661 | "nanoid": "bin/nanoid.cjs" 662 | }, 663 | "engines": { 664 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 665 | } 666 | }, 667 | "node_modules/picocolors": { 668 | "version": "1.0.0", 669 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 670 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", 671 | "dev": true 672 | }, 673 | "node_modules/postcss": { 674 | "version": "8.4.38", 675 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", 676 | "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", 677 | "dev": true, 678 | "funding": [ 679 | { 680 | "type": "opencollective", 681 | "url": "https://opencollective.com/postcss/" 682 | }, 683 | { 684 | "type": "tidelift", 685 | "url": "https://tidelift.com/funding/github/npm/postcss" 686 | }, 687 | { 688 | "type": "github", 689 | "url": "https://github.com/sponsors/ai" 690 | } 691 | ], 692 | "dependencies": { 693 | "nanoid": "^3.3.7", 694 | "picocolors": "^1.0.0", 695 | "source-map-js": "^1.2.0" 696 | }, 697 | "engines": { 698 | "node": "^10 || ^12 || >=14" 699 | } 700 | }, 701 | "node_modules/rollup": { 702 | "version": "4.16.2", 703 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.16.2.tgz", 704 | "integrity": "sha512-sxDP0+pya/Yi5ZtptF4p3avI+uWCIf/OdrfdH2Gbv1kWddLKk0U7WE3PmQokhi5JrektxsK3sK8s4hzAmjqahw==", 705 | "dev": true, 706 | "dependencies": { 707 | "@types/estree": "1.0.5" 708 | }, 709 | "bin": { 710 | "rollup": "dist/bin/rollup" 711 | }, 712 | "engines": { 713 | "node": ">=18.0.0", 714 | "npm": ">=8.0.0" 715 | }, 716 | "optionalDependencies": { 717 | "@rollup/rollup-android-arm-eabi": "4.16.2", 718 | "@rollup/rollup-android-arm64": "4.16.2", 719 | "@rollup/rollup-darwin-arm64": "4.16.2", 720 | "@rollup/rollup-darwin-x64": "4.16.2", 721 | "@rollup/rollup-linux-arm-gnueabihf": "4.16.2", 722 | "@rollup/rollup-linux-arm-musleabihf": "4.16.2", 723 | "@rollup/rollup-linux-arm64-gnu": "4.16.2", 724 | "@rollup/rollup-linux-arm64-musl": "4.16.2", 725 | "@rollup/rollup-linux-powerpc64le-gnu": "4.16.2", 726 | "@rollup/rollup-linux-riscv64-gnu": "4.16.2", 727 | "@rollup/rollup-linux-s390x-gnu": "4.16.2", 728 | "@rollup/rollup-linux-x64-gnu": "4.16.2", 729 | "@rollup/rollup-linux-x64-musl": "4.16.2", 730 | "@rollup/rollup-win32-arm64-msvc": "4.16.2", 731 | "@rollup/rollup-win32-ia32-msvc": "4.16.2", 732 | "@rollup/rollup-win32-x64-msvc": "4.16.2", 733 | "fsevents": "~2.3.2" 734 | } 735 | }, 736 | "node_modules/source-map-js": { 737 | "version": "1.2.0", 738 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", 739 | "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", 740 | "dev": true, 741 | "engines": { 742 | "node": ">=0.10.0" 743 | } 744 | }, 745 | "node_modules/typescript": { 746 | "version": "5.4.5", 747 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", 748 | "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", 749 | "dev": true, 750 | "bin": { 751 | "tsc": "bin/tsc", 752 | "tsserver": "bin/tsserver" 753 | }, 754 | "engines": { 755 | "node": ">=14.17" 756 | } 757 | }, 758 | "node_modules/vite": { 759 | "version": "5.2.10", 760 | "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.10.tgz", 761 | "integrity": "sha512-PAzgUZbP7msvQvqdSD+ErD5qGnSFiGOoWmV5yAKUEI0kdhjbH6nMWVyZQC/hSc4aXwc0oJ9aEdIiF9Oje0JFCw==", 762 | "dev": true, 763 | "dependencies": { 764 | "esbuild": "^0.20.1", 765 | "postcss": "^8.4.38", 766 | "rollup": "^4.13.0" 767 | }, 768 | "bin": { 769 | "vite": "bin/vite.js" 770 | }, 771 | "engines": { 772 | "node": "^18.0.0 || >=20.0.0" 773 | }, 774 | "funding": { 775 | "url": "https://github.com/vitejs/vite?sponsor=1" 776 | }, 777 | "optionalDependencies": { 778 | "fsevents": "~2.3.3" 779 | }, 780 | "peerDependencies": { 781 | "@types/node": "^18.0.0 || >=20.0.0", 782 | "less": "*", 783 | "lightningcss": "^1.21.0", 784 | "sass": "*", 785 | "stylus": "*", 786 | "sugarss": "*", 787 | "terser": "^5.4.0" 788 | }, 789 | "peerDependenciesMeta": { 790 | "@types/node": { 791 | "optional": true 792 | }, 793 | "less": { 794 | "optional": true 795 | }, 796 | "lightningcss": { 797 | "optional": true 798 | }, 799 | "sass": { 800 | "optional": true 801 | }, 802 | "stylus": { 803 | "optional": true 804 | }, 805 | "sugarss": { 806 | "optional": true 807 | }, 808 | "terser": { 809 | "optional": true 810 | } 811 | } 812 | } 813 | } 814 | } 815 | -------------------------------------------------------------------------------- /7.Workshop/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "7-workshop", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc && vite build", 9 | "preview": "vite preview" 10 | }, 11 | "devDependencies": { 12 | "typescript": "^5.2.2", 13 | "vite": "^5.2.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /7.Workshop/src/constants.ts: -------------------------------------------------------------------------------- 1 | export const CONFIG = { 2 | baseUrl: "https://jsonplaceholder.typicode.com", 3 | }; 4 | -------------------------------------------------------------------------------- /7.Workshop/src/main.ts: -------------------------------------------------------------------------------- 1 | import { CONFIG } from "./constants"; 2 | import { PostService } from "./services/postService"; 3 | import { UserService } from "./services/userService"; 4 | import "./style.css"; 5 | import { HtmlUtil } from "./utils/html"; 6 | 7 | /** Handling the data */ 8 | const { baseUrl } = CONFIG; 9 | const postService = new PostService(baseUrl); 10 | const userId = 3; 11 | 12 | /** Read All - Posts */ 13 | postService.getAll().then((data) => { 14 | console.log("posts ", data); 15 | }); 16 | 17 | /** Read All - Users */ 18 | const userService = new UserService(baseUrl); 19 | userService.getAll().then((data) => { 20 | console.log("users ", data); 21 | }); 22 | 23 | /** Read One */ 24 | userService.getSingleUser(userId, (id: number) => { 25 | postService.getUserPosts(id).then((data) => { 26 | console.log("user's posts ", data[0]); 27 | }); 28 | }); 29 | 30 | // userService.getOne(userId).then((data) => { 31 | // console.log("single user", data); 32 | // }); 33 | 34 | /** Delete */ 35 | // userService.delete(userId).then((x) => { 36 | // console.log("delete", x); 37 | // }); 38 | 39 | // const user: UserDetails = { 40 | // id: 2, 41 | // name: "Pesho Ivanonv", 42 | // username: "Pesho", 43 | // email: "Pesho@april.biz", 44 | // address: { 45 | // street: "", 46 | // suite: "", 47 | // city: "", 48 | // zipcode: "", 49 | // geo: { lat: "", lng: "" }, 50 | // }, 51 | // phone: "0876123123123", 52 | // website: "peshoivanov.org", 53 | // company: { 54 | // name: "", 55 | // catchPhrase: "", 56 | // bs: "", 57 | // }, 58 | // }; 59 | 60 | /** Update */ 61 | // userService.update(user).then((x) => { 62 | // console.log("update", x); 63 | // }); 64 | 65 | /** Create */ 66 | // userService.create(user).then((res) => { 67 | // console.log({ res }); 68 | // }); 69 | 70 | /** Rendering of the views */ 71 | const root = document.querySelector("#root"); 72 | HtmlUtil.render(root); 73 | -------------------------------------------------------------------------------- /7.Workshop/src/router.ts: -------------------------------------------------------------------------------- 1 | import { RouterMap } from "./type/router"; 2 | import { postPage } from "./views/post"; 3 | import { userPage } from "./views/user"; 4 | 5 | export const router: RouterMap = { 6 | "/": userPage, 7 | "/post": postPage, 8 | }; 9 | -------------------------------------------------------------------------------- /7.Workshop/src/services/httpService.ts: -------------------------------------------------------------------------------- 1 | import { fetchUtil } from "../utils/http"; 2 | 3 | export class HttpService { 4 | protected apiUrl: string; 5 | protected data = {} as T; 6 | protected dataCollection = [] as T[]; 7 | 8 | constructor(apiUrl: string) { 9 | this.apiUrl = apiUrl; 10 | } 11 | 12 | create(body: T) { 13 | const config = { 14 | method: "POST", 15 | body: JSON.stringify(body), 16 | headers: { 17 | "Content-type": "application/json; charset=UTF-8", 18 | }, 19 | }; 20 | return fetchUtil(this.apiUrl, config); 21 | } 22 | 23 | getAll() { 24 | return fetchUtil(this.apiUrl) as Promise; 25 | } 26 | 27 | getOne(id: number) { 28 | return fetchUtil(`${this.apiUrl}/${id}`) as Promise; 29 | } 30 | 31 | update(body: T) { 32 | const config = { 33 | method: "PUT", 34 | body: JSON.stringify(body), 35 | headers: { 36 | "Content-type": "application/json; charset=UTF-8", 37 | }, 38 | }; 39 | return fetchUtil(`${this.apiUrl}/${body.id}`, config); 40 | } 41 | 42 | delete(id: number) { 43 | const config = { method: "DELETE" }; 44 | return fetchUtil(`${this.apiUrl}/${id}`, config); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /7.Workshop/src/services/postService.ts: -------------------------------------------------------------------------------- 1 | import { Post } from "../type/post"; 2 | import { fetchUtil } from "../utils/http"; 3 | import { HttpService } from "./httpService"; 4 | 5 | export class PostService extends HttpService { 6 | constructor(baseUrl: string) { 7 | super(`${baseUrl}/posts`); // new HttpService(`${baseUrl}/posts`); 8 | } 9 | 10 | getUserPosts(userId: number) { 11 | return fetchUtil(`${this.apiUrl}?userId=${userId}`) as Promise< 12 | Post[] 13 | >; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /7.Workshop/src/services/userService.ts: -------------------------------------------------------------------------------- 1 | import { UserDetails } from "../type/user"; 2 | import { HttpService } from "./httpService"; 3 | 4 | export class UserService extends HttpService { 5 | constructor(baseUrl: string) { 6 | super(`${baseUrl}/users`); // new HttpService(`${baseUrl}/users`); 7 | } 8 | 9 | getSingleUser(id: number, cb: Function) { 10 | return this.getOne(id).then((data) => { 11 | cb(data.id); 12 | }); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /7.Workshop/src/style.css: -------------------------------------------------------------------------------- 1 | a { 2 | font-weight: 500; 3 | color: #646cff; 4 | text-decoration: inherit; 5 | } 6 | a:hover { 7 | color: #535bf2; 8 | } 9 | 10 | html, 11 | body { 12 | margin: 0; 13 | font-family: sans-serif; 14 | background-color: beige; 15 | height: 100%; 16 | } 17 | 18 | #root { 19 | flex-grow: 1; 20 | } 21 | 22 | #wrapper { 23 | height: 100%; 24 | display: flex; 25 | } 26 | 27 | .sidebar { 28 | display: flex; 29 | flex-direction: column; 30 | padding: 1rem; 31 | border-right: 1px solid lightgray; 32 | background-color: rgb(216, 216, 200); 33 | } 34 | 35 | .sidebar > a { 36 | padding: 10px; 37 | margin: 5px 0; 38 | } 39 | 40 | a:hover { 41 | cursor: pointer; 42 | background-color: gray; 43 | } 44 | -------------------------------------------------------------------------------- /7.Workshop/src/type/common.ts: -------------------------------------------------------------------------------- 1 | export type Geo = { 2 | lat: string; 3 | lng: string; 4 | }; 5 | 6 | export type Address = { 7 | street: string; 8 | suite: string; 9 | city: string; 10 | zipcode: string; 11 | geo: Geo; 12 | }; 13 | 14 | export type Company = { 15 | name: string; 16 | catchPhrase: string; 17 | bs: string; 18 | }; 19 | -------------------------------------------------------------------------------- /7.Workshop/src/type/post.ts: -------------------------------------------------------------------------------- 1 | export type Post = { 2 | userId: number; 3 | id: number; 4 | title: string; 5 | body: string; 6 | }; 7 | -------------------------------------------------------------------------------- /7.Workshop/src/type/router.ts: -------------------------------------------------------------------------------- 1 | export type RouterMap = { 2 | [key: string]: string; 3 | }; 4 | -------------------------------------------------------------------------------- /7.Workshop/src/type/user.ts: -------------------------------------------------------------------------------- 1 | import { Address, Company } from "./common"; 2 | 3 | export type User = { 4 | id: number; 5 | name: string; 6 | username: string; 7 | email: string; 8 | website: string; 9 | }; 10 | 11 | export type UserDetails = { 12 | address: Address; 13 | phone: string; 14 | company: Company; 15 | } & User; 16 | -------------------------------------------------------------------------------- /7.Workshop/src/utils/html.ts: -------------------------------------------------------------------------------- 1 | import { router } from "../router"; 2 | 3 | export abstract class HtmlUtil { 4 | static render(rootDiv: HTMLElement | null) { 5 | if (!rootDiv) { 6 | throw Error("Missing root element!"); 7 | } 8 | 9 | // on init 10 | const { pathname } = window.location; 11 | rootDiv.innerHTML = router[pathname]; 12 | 13 | // List events 14 | HtmlUtil.addEventListeners(rootDiv); 15 | } 16 | 17 | private static addEventListeners(rootDiv: HTMLElement) { 18 | // capture elements 19 | const usersBtn: HTMLElement | null = document.getElementById("users"); 20 | const postsBtn: HTMLElement | null = document.getElementById("posts"); 21 | 22 | // attach events 23 | if (usersBtn) { 24 | usersBtn.addEventListener("click", () => { 25 | HtmlUtil.navigate(rootDiv, "/"); 26 | }); 27 | } 28 | 29 | if (postsBtn) { 30 | postsBtn.addEventListener("click", () => { 31 | HtmlUtil.navigate(rootDiv, "/post"); 32 | }); 33 | } 34 | } 35 | 36 | private static navigate(rootDiv: HTMLElement, pathname: string) { 37 | const { origin } = window.location; 38 | const url = `${origin}${pathname}`; 39 | 40 | // to change url 41 | window.history.pushState({}, pathname, url); 42 | 43 | // to render content 44 | rootDiv.innerHTML = router[pathname]; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /7.Workshop/src/utils/http.ts: -------------------------------------------------------------------------------- 1 | export const fetchUtil = (url: string, httpConfig?: RequestInit) => { 2 | return fetch(url, httpConfig) 3 | .then((response) => response.json()) 4 | .then((data: T) => data) 5 | .catch((error) => console.error(`Error: ${error}`)); 6 | }; 7 | -------------------------------------------------------------------------------- /7.Workshop/src/views/post.ts: -------------------------------------------------------------------------------- 1 | export const postPage = `
Hello, from POSTS page!
`; 2 | -------------------------------------------------------------------------------- /7.Workshop/src/views/user.ts: -------------------------------------------------------------------------------- 1 | export const userPage = `
Hello, from USERS page!
`; 2 | -------------------------------------------------------------------------------- /7.Workshop/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /7.Workshop/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true 21 | }, 22 | "include": ["src"] 23 | } 24 | -------------------------------------------------------------------------------- /8.ExamPrep/1.Calculator/dist/index.js: -------------------------------------------------------------------------------- 1 | // function calc(first: number, operator: string, second: number): string { 2 | // let result = null; 3 | function calc(first, operator, second) { 4 | const dictCalculator = { 5 | "+": (first + second).toFixed(2), 6 | "-": (first - second).toFixed(2), 7 | "/": (first / second).toFixed(2), 8 | "*": (first * second).toFixed(2), 9 | }; 10 | if (!dictCalculator[operator]) { 11 | return "Non existing operator!"; 12 | } 13 | return dictCalculator[operator]; 14 | } 15 | // Input 16 | // 5, "+", 10 17 | // Output 18 | // 15.00 19 | // Input 20 | // 25.5, "-", 3 21 | // Output 22 | // 23.5 23 | const result = calc(25, "+", 10); 24 | console.log(result); 25 | -------------------------------------------------------------------------------- /8.ExamPrep/1.Calculator/src/index.ts: -------------------------------------------------------------------------------- 1 | // function calc(first: number, operator: string, second: number): string { 2 | // let result = null; 3 | 4 | // switch (operator) { 5 | // case "+": 6 | // result = (first + second).toFixed(2); 7 | // break; 8 | // case "-": 9 | // result = (first - second).toFixed(2); 10 | // break; 11 | // case "/": 12 | // result = (first / second).toFixed(2); 13 | // break; 14 | // case "*": 15 | // result = (first * second).toFixed(2); 16 | // break; 17 | // default: 18 | // result = "Non existing operator!"; 19 | // break; 20 | // } 21 | 22 | // return result; 23 | // } 24 | 25 | type DictCalc = { 26 | [key: string]: string; 27 | }; 28 | 29 | function calc(first: number, operator: string, second: number): string { 30 | const dictCalculator = { 31 | "+": (first + second).toFixed(2), 32 | "-": (first - second).toFixed(2), 33 | "/": (first / second).toFixed(2), 34 | "*": (first * second).toFixed(2), 35 | }; 36 | 37 | if (!dictCalculator[operator]) { 38 | return "Non existing operator!"; 39 | } 40 | 41 | return dictCalculator[operator]; 42 | } 43 | 44 | // Input 45 | // 5, "+", 10 46 | // Output 47 | // 15.00 48 | 49 | // Input 50 | // 25.5, "-", 3 51 | // Output 52 | // 23.5 53 | 54 | const result = calc(25, "+", 10); 55 | console.log(result); 56 | -------------------------------------------------------------------------------- /8.ExamPrep/1.Calculator/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist", 4 | "rootDir": "./src", 5 | "target": "ES2022" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /8.ExamPrep/2.LowestPricesInCity/dist/index.js: -------------------------------------------------------------------------------- 1 | const inputData = [ 2 | "Sample Town | Sample Product | 1000", 3 | "Sample Town | Orange | 3", 4 | "Sample Town | Peach | 1", 5 | "Sofia | Orange | 1", 6 | "Sofia | Orange | 2", 7 | "Sofia | Peach | 2", 8 | "New York | Sample Product | 1000.1", 9 | "New York | Burger | 10", 10 | ]; 11 | function solve(input) { 12 | const result = {}; 13 | for (const line of input) { 14 | const [town, product, price] = line.split(" | "); 15 | if (!result[product]) { 16 | result[product] = {}; 17 | } 18 | const currentPrice = Number(price); 19 | if (!result[product][town]) { 20 | result[product][town] = currentPrice; 21 | } 22 | else { 23 | if (result[product][town] > currentPrice) { 24 | result[product][town] = currentPrice; 25 | } 26 | } 27 | } 28 | const tuples = Object.entries(result); 29 | for (const [product, townsWithPriceMap] of tuples) { 30 | const townPriceTuples = Object.entries(townsWithPriceMap); 31 | const sorted = townPriceTuples.sort((a, b) => { 32 | return a[1] - b[1]; 33 | }); 34 | const [town, price] = sorted[0]; 35 | console.log(`${product} -> ${price} (${town})`); 36 | } 37 | } 38 | solve(inputData); 39 | -------------------------------------------------------------------------------- /8.ExamPrep/2.LowestPricesInCity/src/index.ts: -------------------------------------------------------------------------------- 1 | const inputData: string[] = [ 2 | "Sample Town | Sample Product | 1000", 3 | "Sample Town | Orange | 3", 4 | "Sample Town | Peach | 1", 5 | "Sofia | Orange | 1", 6 | "Sofia | Orange | 2", 7 | "Sofia | Peach | 2", 8 | "New York | Sample Product | 1000.1", 9 | "New York | Burger | 10", 10 | ]; 11 | 12 | // Output 13 | // Sample Product -> 1000 (Sample Town) 14 | // Orange -> 2 (Sample Town) 15 | // Peach -> 1 (Sample Town) 16 | // Burger -> 10 (New York) 17 | 18 | type TownPriceMap = { 19 | [townName: string]: number; 20 | }; 21 | 22 | type ResultType = { 23 | [key: string]: TownPriceMap; 24 | }; 25 | 26 | function solve(input: string[]): void { 27 | const result = {} as ResultType; 28 | 29 | for (const line of input) { 30 | const [town, product, price] = line.split(" | "); 31 | if (!result[product]) { 32 | result[product] = {}; 33 | } 34 | 35 | const currentPrice = Number(price); 36 | if (!result[product][town]) { 37 | result[product][town] = currentPrice; 38 | } else { 39 | if (result[product][town] > currentPrice) { 40 | result[product][town] = currentPrice; 41 | } 42 | } 43 | } 44 | 45 | const tuples = Object.entries(result); 46 | 47 | for (const [product, townsWithPriceMap] of tuples) { 48 | const townPriceTuples = Object.entries(townsWithPriceMap); 49 | 50 | const sorted = townPriceTuples.sort((a, b) => { 51 | return a[1] - b[1]; 52 | }); 53 | const [town, price] = sorted[0]; 54 | console.log(`${product} -> ${price} (${town})`); 55 | } 56 | } 57 | 58 | solve(inputData); 59 | -------------------------------------------------------------------------------- /8.ExamPrep/2.LowestPricesInCity/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist", 4 | "rootDir": "./src", 5 | "target": "ES2022" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /8.ExamPrep/3.ClotheMagazine/dist/Cloth.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.Cloth = void 0; 4 | class Cloth { 5 | color; 6 | size; 7 | type; 8 | constructor(color, size, type) { 9 | this.color = color; 10 | this.size = size; 11 | this.type = type; 12 | } 13 | toString() { 14 | return `Product: ${this.type} with size ${this.size}, color ${this.color}`; 15 | } 16 | } 17 | exports.Cloth = Cloth; 18 | -------------------------------------------------------------------------------- /8.ExamPrep/3.ClotheMagazine/dist/Magazine.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.Magazine = void 0; 4 | class Magazine { 5 | type; 6 | capacity; 7 | clothes; 8 | constructor(type, capacity) { 9 | this.type = type; 10 | this.capacity = capacity; 11 | this.clothes = []; 12 | } 13 | addCloth(cloth) { 14 | if (this.clothes.length < this.capacity) { 15 | this.clothes.push(cloth); 16 | } 17 | } 18 | removeCloth(color) { 19 | const index = this.clothes.findIndex((c) => c.color === color); 20 | if (index !== -1) { 21 | this.clothes.splice(index, 1); 22 | return true; 23 | } 24 | return false; 25 | } 26 | getSortedClothes() { 27 | const sorted = this.clothes.sort((a, b) => a.size - b.size); 28 | return sorted; 29 | } 30 | getSmallestCloth() { 31 | if (!this.clothes.length) { 32 | return {}; 33 | } 34 | if (this.clothes.length === 1) { 35 | return this.clothes[0]; 36 | } 37 | const smallestCloth = this.getSortedClothes()[0]; 38 | return smallestCloth; 39 | } 40 | getCloth(color) { 41 | const cloth = this.clothes.find((c) => c.color === color); 42 | return cloth; 43 | } 44 | getClothCount() { 45 | const count = this.clothes.length; 46 | return count; 47 | } 48 | report() { 49 | // 50 | const sorthClothes = this.getSortedClothes(); 51 | const clothesForReport = sorthClothes.map((c) => c.toString()).join("\n"); 52 | const report = `${this.type} magazine contains:\n${clothesForReport}`; 53 | return report; 54 | } 55 | } 56 | exports.Magazine = Magazine; 57 | -------------------------------------------------------------------------------- /8.ExamPrep/3.ClotheMagazine/dist/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const Magazine_1 = require("./Magazine"); 4 | const Cloth_1 = require("./Cloth"); 5 | function main() { 6 | // Initialize the repository (Magazine) 7 | const magazine = new Magazine_1.Magazine("Zara", 20); 8 | // Initialize entity (Cloth) 9 | const cloth1 = new Cloth_1.Cloth("red", 36, "dress"); 10 | // Print Cloth 11 | console.log(cloth1.toString()); 12 | // Product: dress with size 36, color red 13 | // Add Cloth 14 | magazine.addCloth(cloth1); 15 | // Remove Cloth 16 | console.log(magazine.removeCloth("black")); // false 17 | const cloth2 = new Cloth_1.Cloth("brown", 34, "t-shirt"); 18 | const cloth3 = new Cloth_1.Cloth("blue", 32, "jeans"); 19 | // Add Cloth 20 | magazine.addCloth(cloth2); 21 | magazine.addCloth(cloth3); 22 | // Get smallest cloth 23 | const smallestCloth = magazine.getSmallestCloth(); 24 | console.log(smallestCloth?.toString()); 25 | // Product: jeans with size 32, color blue 26 | // Get Cloth 27 | const getCloth = magazine.getCloth("brown"); 28 | // Product: t-shirt with size 34, color brown 29 | console.log(getCloth?.toString()); 30 | console.log(magazine.report()); 31 | // Zara magazine contains: 32 | // Product: jeans with size 32, color blue 33 | // Product: t-shirt with size 34, color brown 34 | // Product: dress with size 36, color red 35 | } 36 | main(); 37 | -------------------------------------------------------------------------------- /8.ExamPrep/3.ClotheMagazine/src/Cloth.ts: -------------------------------------------------------------------------------- 1 | export class Cloth { 2 | public color: string; 3 | public size: number; 4 | private type: string; 5 | 6 | constructor(color: string, size: number, type: string) { 7 | this.color = color; 8 | this.size = size; 9 | this.type = type; 10 | } 11 | 12 | toString() { 13 | return `Product: ${this.type} with size ${this.size}, color ${this.color}`; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /8.ExamPrep/3.ClotheMagazine/src/Magazine.ts: -------------------------------------------------------------------------------- 1 | import { Cloth } from "./Cloth"; 2 | 3 | export class Magazine { 4 | private type: string; 5 | private capacity: number; 6 | private clothes: Cloth[]; 7 | 8 | constructor(type: string, capacity: number) { 9 | this.type = type; 10 | this.capacity = capacity; 11 | this.clothes = []; 12 | } 13 | 14 | addCloth(cloth: Cloth): void { 15 | if (this.clothes.length < this.capacity) { 16 | this.clothes.push(cloth); 17 | } 18 | } 19 | 20 | removeCloth(color: string): boolean { 21 | const index = this.clothes.findIndex((c) => c.color === color); 22 | 23 | if (index !== -1) { 24 | this.clothes.splice(index, 1); 25 | return true; 26 | } 27 | 28 | return false; 29 | } 30 | 31 | getSortedClothes(): Cloth[] { 32 | const sorted = this.clothes.sort((a, b) => a.size - b.size); 33 | return sorted; 34 | } 35 | 36 | getSmallestCloth(): Cloth { 37 | if (!this.clothes.length) { 38 | return {} as Cloth; 39 | } 40 | 41 | if (this.clothes.length === 1) { 42 | return this.clothes[0]; 43 | } 44 | 45 | const smallestCloth = this.getSortedClothes()[0]; 46 | return smallestCloth; 47 | } 48 | 49 | getCloth(color: string): Cloth { 50 | const cloth = this.clothes.find((c) => c.color === color); 51 | return cloth; 52 | } 53 | 54 | getClothCount(): number { 55 | const count = this.clothes.length; 56 | return count; 57 | } 58 | 59 | report(): string { 60 | // 61 | const sorthClothes = this.getSortedClothes(); 62 | const clothesForReport = sorthClothes.map((c) => c.toString()).join("\n"); 63 | 64 | const report = `${this.type} magazine contains:\n${clothesForReport}`; 65 | return report; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /8.ExamPrep/3.ClotheMagazine/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Magazine } from "./Magazine"; 2 | import { Cloth } from "./Cloth"; 3 | 4 | function main() { 5 | // Initialize the repository (Magazine) 6 | const magazine = new Magazine("Zara", 20); 7 | // Initialize entity (Cloth) 8 | const cloth1 = new Cloth("red", 36, "dress"); 9 | 10 | // Print Cloth 11 | console.log(cloth1.toString()); 12 | // Product: dress with size 36, color red 13 | 14 | // Add Cloth 15 | magazine.addCloth(cloth1); 16 | 17 | // Remove Cloth 18 | console.log(magazine.removeCloth("black")); // false 19 | 20 | const cloth2 = new Cloth("brown", 34, "t-shirt"); 21 | const cloth3 = new Cloth("blue", 32, "jeans"); 22 | 23 | // Add Cloth 24 | magazine.addCloth(cloth2); 25 | magazine.addCloth(cloth3); 26 | 27 | // Get smallest cloth 28 | const smallestCloth = magazine.getSmallestCloth(); 29 | console.log(smallestCloth?.toString()); 30 | // Product: jeans with size 32, color blue 31 | 32 | // Get Cloth 33 | const getCloth = magazine.getCloth("brown"); 34 | // Product: t-shirt with size 34, color brown 35 | console.log(getCloth?.toString()); 36 | 37 | console.log(magazine.report()); 38 | // Zara magazine contains: 39 | // Product: jeans with size 32, color blue 40 | // Product: t-shirt with size 34, color brown 41 | // Product: dress with size 36, color red 42 | } 43 | 44 | main(); 45 | -------------------------------------------------------------------------------- /8.ExamPrep/3.ClotheMagazine/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist", 4 | "rootDir": "./src", 5 | "target": "ES2022", 6 | "module": "CommonJS" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /8.ExamPrep/Bonus/dist/index.js: -------------------------------------------------------------------------------- 1 | const sortedNums = [ 2 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 3 | ]; 4 | function binarySearch(sortNums, target, startIndex = 0, endIndex = sortNums.length - 1) { 5 | if (endIndex < startIndex) 6 | return -1; 7 | const middleIndex = Math.floor((startIndex + endIndex) / 2); 8 | const currentEl = sortNums[middleIndex]; 9 | // to right 10 | if (currentEl < target) { 11 | return binarySearch(sortNums, target, middleIndex + 1, endIndex); 12 | } 13 | // to left 14 | if (currentEl > target) { 15 | return binarySearch(sortNums, target, startIndex, middleIndex - 1); 16 | } 17 | return middleIndex; 18 | } 19 | console.log(binarySearch(sortedNums, 13)); 20 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /8.ExamPrep/Bonus/dist/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,GAAa;IAC3B,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;CACtD,CAAC;AAEF,SAAS,YAAY,CACnB,QAAkB,EAClB,MAAc,EACd,UAAU,GAAG,CAAC,EACd,QAAQ,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC;IAE9B,IAAI,QAAQ,GAAG,UAAU;QAAE,OAAO,CAAC,CAAC,CAAC;IAErC,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5D,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;IAExC,WAAW;IACX,IAAI,SAAS,GAAG,MAAM,EAAE,CAAC;QACvB,OAAO,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;IACnE,CAAC;IAED,UAAU;IACV,IAAI,SAAS,GAAG,MAAM,EAAE,CAAC;QACvB,OAAO,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC;IACrE,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC"} -------------------------------------------------------------------------------- /8.ExamPrep/Bonus/src/index.ts: -------------------------------------------------------------------------------- 1 | const sortedNums: number[] = [ 2 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 3 | ]; 4 | 5 | function binarySearch( 6 | sortNums: number[], 7 | target: number, 8 | startIndex = 0, 9 | endIndex = sortNums.length - 1 10 | ) { 11 | if (endIndex < startIndex) return -1; 12 | 13 | const middleIndex = Math.floor((startIndex + endIndex) / 2); 14 | const currentEl = sortNums[middleIndex]; 15 | 16 | // to right 17 | if (currentEl < target) { 18 | return binarySearch(sortNums, target, middleIndex + 1, endIndex); 19 | } 20 | 21 | // to left 22 | if (currentEl > target) { 23 | return binarySearch(sortNums, target, startIndex, middleIndex - 1); 24 | } 25 | 26 | return middleIndex; 27 | } 28 | 29 | console.log(binarySearch(sortedNums, 13)); 30 | -------------------------------------------------------------------------------- /8.ExamPrep/Bonus/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist", 4 | "rootDir": "./src", 5 | "target": "ES2022", 6 | "module": "CommonJS", 7 | "sourceMap": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SoftUni-TypeScript-Apr-2024 2 | --------------------------------------------------------------------------------