lms-sync 1.0.49 → 1.0.50

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,6 +7,7 @@ const Mixins = require('../utils/Mixins')
7
7
 
8
8
  const {
9
9
  AcademicDepartments,
10
+ AcademicDepartmentInstructors,
10
11
  AcademicYears,
11
12
  Campuses,
12
13
  Colleges,
@@ -22,6 +23,7 @@ const {
22
23
  Semesters,
23
24
  Employees,
24
25
 
26
+
25
27
  } = db
26
28
 
27
29
  const server = {
@@ -853,7 +855,6 @@ const server = {
853
855
  logger.info(`Total Successful Instructors Records Created: ${createdCounter}/${createdCounter}`);
854
856
  logger.info(`Total Existing Instructors Records: ${errorCounter}/${errorCounter}`);
855
857
  logger.info(`Total Records: ${createdCounter + errorCounter}`);
856
-
857
858
  console.log("")
858
859
  console.log("########################################################")
859
860
  console.log("")
@@ -872,182 +873,95 @@ const server = {
872
873
  }
873
874
  },
874
875
 
875
- // async Instructorsss(){
876
- // try {
877
- // console.log("");
878
- // console.log("########################################################")
879
- // console.log(" Instructors Migration ")
880
- // console.log("########################################################")
881
- // console.log("");
882
-
883
- // const db_schema = schema
884
- // let maxIds = await Instructors.max('_id'); //Fetch maximum _id directly from the Instructors model
885
- // let maxId = maxIds|| 0;
886
- // await db.sequelize.query(`CREATE SEQUENCE IF NOT EXISTS ${db_schema}."Instructors__id_seq"`);
887
- // await db.sequelize.query(`ALTER SEQUENCE ${db_schema}."Instructors__id_seq" RESTART WITH ${maxId + 1}`);
888
-
889
- // const instructorApi = await api.Instructor()
890
- // const departmentApi = await api.Department()
891
-
892
- // const departmentSeq = await AcademicDepartments.findAll()
893
- // const campusSeq = await Campuses.findAll()
894
- // const userSeq = await Users.findAll()
895
-
896
- // const userMail = await Users.findOne({ where: { email: 'ccci_integrator@gmail.com' } });
897
- // if (!userMail){}
898
- // const campusDefault = await Campuses.findOne({ where: { name: 'Campus Default' } });
899
- // const departmentDefault = await AcademicDepartments.findOne({ where: { name: 'AcademicDepartments Default' } });
900
-
901
- // let defaultPayload = {
902
- // firstName: 'Instructor',
903
- // lastName: 'Default',
904
- // middleName: 'Migration',
905
- // employeeNumber: '_Instructor',
906
- // departmentId: departmentDefault?._id,
907
- // campusId: campusDefault?._id,
908
- // modifiedById: userMail?._id,
909
- // createdById: userMail?._id
910
- // };
876
+ async AcadDeptInstructor(){
877
+ try {
878
+ console.log("");
879
+ console.log("########################################################")
880
+ console.log(" Academic Department Instructors Migrations ")
881
+ console.log("########################################################")
882
+ console.log("");
911
883
 
912
- // let [defaults, createddef] = await Instructors.findOrCreate({
913
- // where: { employeeNumber: defaultPayload.employeeNumber, lastName: defaultPayload.lastName},
914
- // defaults: defaultPayload
915
- // });
916
-
917
- // let createdCounter = 0
918
- // let errorCounter = 0
919
- // let uniqueErrors = new Set()
884
+ const db_schema = schema
885
+ let maxIds = await AcademicDepartmentInstructors.max('_id'); //Fetch maximum _id directly from the Users model
886
+ let maxId = maxIds|| 0;
887
+ await db.sequelize.query(`CREATE SEQUENCE IF NOT EXISTS ${db_schema}."AcademicDepartmentInstructors__id_seq"`);
888
+ await db.sequelize.query(`ALTER SEQUENCE ${db_schema}."AcademicDepartmentInstructors__id_seq" RESTART WITH ${maxId + 1}`);
920
889
 
921
- // let uDept = new Set()
922
- // let uCamp = new Set()
923
- // let uLname = new Set()
924
- // let uMname = new Set()
925
- // let uFname = new Set()
926
- // let uNum = new Set()
890
+ const instructorApi = await api.Instructor()
927
891
 
928
- // let newInstructor = []
892
+ const instructorSeq = await Instructors.findAll()
893
+ const departmentSeq = await AcademicDepartments.findAll()
929
894
 
930
- // const exInst = await Instructors.findAll()
931
- // const exInstMap = new Map(exInst.map(inst => [`[${inst.employeeNumber}] - ${inst.lastName}, ${inst.firstName} ${inst.middleName} [${inst.departmentId}, ${inst.campusId}]` , inst]))
895
+ const userMail = await Users.findOne({ where: { email: 'ccci_integrator@gmail.com' } });
896
+ if (!userMail){}
932
897
 
898
+ let createdCounter = 0
899
+ let errorCounter = 0
900
+ let uniqueErrors = new Set()
933
901
 
934
- // for (let i = 0; i < instructorApi.length; i++){
935
- // try {
936
-
937
- // let _instructor = instructorApi[i]
938
-
939
- // let findUser = await userSeq.find( f => f.lastName === _instructor?.last_name && f.firstName === _instructor?.first_name && f.middleName === _instructor?.middle_name)
902
+ for(let i = 0; i < instructorApi.length; i++){
903
+ try {
904
+ let instructor = instructorApi[i]
905
+
906
+ let _instructor = instructorSeq.find(num => num.employeeNumber === instructor?.faculty_id)
907
+ let _department = departmentSeq.find(dep => dep._id === _instructor?.departmentId)
908
+
909
+ let modifiedById = userMail._id
910
+ let createdById = userMail._id
911
+
912
+ let [record, created] = await AcademicDepartmentInstructors.findOrCreate({
913
+ where:{
914
+ instructorId: _instructor?._id,
915
+ academicDepartmentId: _department?._id,
916
+ },
917
+ defaults:{
918
+ instructorId: _instructor?._id,
919
+ academicDepartmentId: _department?._id,
920
+ modifiedById,
921
+ createdById
922
+ }
923
+ })
924
+ if (created){
925
+ logger.info(`${createdCounter + 1}/${createdCounter + 1} New Academic Department Instructor Record Created: instructorId: ${record.instructorId}, academicDepartmentId: ${record.academicDepartmentId} `)
926
+ createdCounter++;
927
+ }
928
+ else {
929
+ const errorMsg = `Academic Department Instructor Record Already Exists: instructorId: ${record.instructorId}, academicDepartmentId: ${record.academicDepartmentId}`;
940
930
 
941
- // let acadDepartmentMap = departmentApi.find(a => a.name === _instructor?.department_name)
942
- // let _acadDepartment = departmentSeq.find(b => b.name === acadDepartmentMap?.name)
943
- // let campusMap = campusSeq.find(c => c._id === _acadDepartment?.campusId)
944
-
945
- // let modifiedById = userMail?._id
946
- // let createdById = userMail?._id
931
+ if (!uniqueErrors.has(errorMsg)) {
932
+ logger.error(`${errorCounter + 1}/${errorCounter + 1} ${errorMsg}`);
933
+ uniqueErrors.add(errorMsg);
934
+ errorCounter++;
935
+ }
947
936
 
948
- // let campusDefault = "MSC - Boac Campus"
949
- // let _campusDefault = campusSeq.find(ccc => ccc.name === campusDefault)
937
+ }
938
+ } catch (error) {
939
+ logger.error(`Error occurred: ${error} ${error.stack}`);
940
+ }
941
+ }
942
+ let items = createdCounter + errorCounter
943
+ console.log("");
944
+ console.log("########################################################")
945
+ console.log("")
946
+ logger.info('Academic Department Instructors Data Migration Completed');
947
+ logger.info(`Total Successful Records Created: ${createdCounter}/${createdCounter}`);
948
+ logger.info(`Total Existing Records: ${errorCounter}/${errorCounter}`);
949
+ logger.info(`Total Record Fetched: ${items} `)
950
+ console.log("")
951
+ console.log("########################################################")
952
+ console.log("")
950
953
 
951
- // let role = _instructor?.role
952
- // let isChairPerson = false
953
- // let isDean = false
954
-
955
- // if(role === "Program Chair"){
956
- // isChairPerson = true
957
- // }
958
- // if(role === "Dean"){
959
- // isDean = true
960
- // }
961
-
962
- // let firstName = _instructor?.first_name
963
- // let lastName = _instructor?.last_name
964
- // let middleName = _instructor?.middle_name
965
- // let employeeNumber = _instructor?.faculty_id
966
- // let departmentId = _acadDepartment?._id??departmentDefault?._id
967
- // let campusId = campusMap?._id??_campusDefault?._id
968
- // let userId = findUser?._id
969
-
970
- // if(uNum.has(employeeNumber) && uLname.has(lastName) && uFname.has(firstName) && uMname.has(middleName) && uDept.has(departmentId) && uCamp.has(campusId)){
971
- // const errorMsg = `Duplicate Payload Found: [${employeeNumber}] - ${lastName}, ${firstName} ${middleName} [departmentId: ${departmentId}, campusId:${campusId}]`
972
- // if(!uniqueErrors.has(errorMsg)){
973
- // logger.error(`${errorCounter + 1}/${errorCounter + 1}: ${errorMsg}`)
974
- // uniqueErrors.add(errorMsg)
975
- // errorCounter++
976
- // }
977
- // }
978
- // else if ( exInstMap.has(`[${employeeNumber}] - ${lastName}, ${firstName} ${middleName} [${departmentId}, ${campusId}]`)){
979
- // const exInst = exInstMap.get(`[${employeeNumber}] - ${lastName}, ${firstName} ${middleName} [${departmentId}, ${campusId}]`)
980
- // const errorMsg = `Existing Data Found:[${exInst.employeeNumber}] - ${exInst.lastName}, ${exInst.firstName} ${exInst.middleName} [departmentId: ${exInst.departmentId}, campusId: ${exInst.campusId}]`
981
- // if(!uniqueErrors.has(errorMsg)){
982
- // logger.error(`${errorCounter + 1}/${errorCounter + 1}: ${errorMsg}`)
983
- // uniqueErrors.add(errorMsg)
984
- // errorCounter++
985
- // }
986
- // }
987
- // else{
988
- // uNum.add(employeeNumber)
989
- // uLname.add(lastName)
990
- // uFname.add(firstName)
991
- // uMname.add(middleName)
992
- // uDept.add(departmentId)
993
- // uCamp.add(campusId)
994
- // newInstructor.push({
995
- // firstName: _instructor?.first_name,
996
- // lastName: _instructor?.last_name,
997
- // middleName: _instructor?.middle_name,
998
- // employeeNumber: _instructor?.faculty_id,
999
- // departmentId: _acadDepartment?._id??departmentDefault?._id,
1000
- // academicDepartmentId: _acadDepartment?._id??departmentDefault?._id,
1001
- // campusId: campusMap?._id??_campusDefault?._id??campusDefault?._id,
1002
- // isDean,
1003
- // isChairPerson,
1004
- // modifiedById,
1005
- // createdById,
1006
- // userId
1007
- // })
1008
- // }
1009
-
1010
- // } catch (error) {
1011
- // logger.error(`Error occurred: ${error} ${error.stack}`);
1012
- // }
1013
- // }
954
+ let totalSummary = {
955
+ itemLength: items,
956
+ error: errorCounter,
957
+ success: createdCounter
958
+ }
959
+ return totalSummary
1014
960
 
1015
- // if (newInstructor.length > 0) {
1016
-
1017
- // await Instructors.bulkCreate(newInstructor)
1018
- // createdCounter += newInstructor.length
1019
-
1020
- // newInstructor.forEach((inst, index) => {
1021
- // logger.info(`${index + 1}/${index + 1}: New Instructor Record Created: [${inst.employeeNumber}] - ${inst.lastName}, ${inst.firstName} ${inst.middleName} [ departmentId: ${inst.departmentId}, campusId: ${inst.campusId}]`)
1022
- // });
1023
-
1024
- // }
1025
-
1026
- // console.log("");
1027
- // console.log("########################################################")
1028
- // console.log("")
1029
- // logger.info('Instructors Data Migration Completed');
1030
- // logger.info(`Total Successful Instructors Records Created: ${createdCounter}/${createdCounter}`);
1031
- // logger.info(`Total Existing Instructors Records: ${errorCounter}/${errorCounter}`);
1032
- // logger.info(`Total Records: ${createdCounter + errorCounter}`);
1033
-
1034
- // console.log("")
1035
- // console.log("########################################################")
1036
- // console.log("")
1037
-
1038
- // let totalSummary = {
1039
- // itemLength: createdCounter + errorCounter,
1040
- // error: errorCounter,
1041
- // success: createdCounter
1042
- // }
1043
- // return totalSummary
1044
-
1045
- // } catch (error) {
1046
- // ;
1047
- // logger.error(`Error occurred: ${error} ${error.stack} `);
1048
-
1049
- // }
1050
- // },
961
+ } catch (error) {
962
+ logger.error(`Error occurred: ${error} ${error.stack}`);
963
+ }
964
+ },
1051
965
 
1052
966
  async Course(){
1053
967
  try {
@@ -2073,167 +1987,6 @@ const server = {
2073
1987
  }
2074
1988
  },
2075
1989
 
2076
- // async Studentsss(){
2077
- // try {
2078
- // console.log("");
2079
- // console.log("########################################################")
2080
- // console.log(" Students Migration ")
2081
- // console.log("########################################################")
2082
- // console.log("");
2083
-
2084
- // const db_schema = schema
2085
- // let maxIds = await Students.max('_id'); // Fetch maximum _id directly from the Students model
2086
- // let maxId = maxIds|| 0;
2087
- // await db.sequelize.query(`CREATE SEQUENCE IF NOT EXISTS ${db_schema}."Students__id_seq"`);
2088
- // await db.sequelize.query(`ALTER SEQUENCE ${db_schema}."Students__id_seq" RESTART WITH ${maxId + 1}`);
2089
-
2090
- // const studentApi = await api.Student()
2091
-
2092
- // const campusSeq = await Campuses.findAll()
2093
- // const courseSeq = await Courses.findAll()
2094
- // const collegeSeq = await Colleges.findAll()
2095
- // const semesterSeq = await Semesters.findAll()
2096
- // const acadYearSeq = await AcademicYears.findAll()
2097
- // const userSeq = await Users.findAll()
2098
-
2099
- // const userMail = await Users.findOne({ where: { email: 'ccci_integrator@gmail.com' } });
2100
- // const campusDefault = await Campuses.findOne({ where: { name: 'Campus Default' } });
2101
- // const courseDefault = await Courses.findOne({ where: { name: 'Course Default' } });
2102
- // const collegeDefault = await Colleges.findOne({ where: { name: 'Colleges Default' } });
2103
-
2104
- // let createdCounter = 0
2105
- // let errorCounter = 0
2106
- // let uniqueErrors = new Set()
2107
-
2108
- // let uNum = new Set()
2109
- // let uLname = new Set()
2110
- // let uMname = new Set()
2111
- // let uFname = new Set()
2112
- // let uCourse = new Set()
2113
- // let uCampus = new Set()
2114
-
2115
- // let newStudent = []
2116
-
2117
- // const exStudent = await Students.findAll()
2118
- // const exStudentMap = new Map(exStudent.map(student => [`[${student.studentNumber}] - ${student.lastName}, ${student.firstName} ${student.middleName} [${student.courseId}, ${student.campusId}]`, student]))
2119
-
2120
- // const {data} = studentApi
2121
-
2122
- // for (let i = 0; i < data.length; i++){
2123
- // try {
2124
- // let _student = data[i]
2125
-
2126
- // let _campus = campusSeq.find(a => a.name === _student?.campus)
2127
- // let _course = courseSeq.find(b => b.name === _student?.course)
2128
- // let _college = collegeSeq.find(c => c.name === _student?.college)
2129
-
2130
- // let findUser = await userSeq.find( f => f.lastName === _student?.last_name && f.firstName === _student?.first_name && f.middleName === _student?.middle_name)
2131
-
2132
- // let modifiedById = userMail?._id
2133
- // let createdById = userMail?._id
2134
-
2135
- // let fromPrompts = await Picked()
2136
-
2137
- // // let semester = "2nd Semester"
2138
- // let semester = fromPrompts.semester
2139
- // let yearsFrom = fromPrompts.yearFrom
2140
- // let yearsTo = fromPrompts.yearTo
2141
-
2142
- // let _semester = semesterSeq.find(sem => sem.code === semester)
2143
- // let _acadYear = acadYearSeq.find(yr => yr.from === parseInt(yearsFrom) && yr.to === parseInt(yearsTo))
2144
-
2145
- // let studentNumber = _student?.student_number
2146
- // let firstName = _student?.first_name
2147
- // let lastName = _student?.last_name
2148
- // let middleName = _student?.middle_name
2149
- // let courseId = _course?._id??courseDefault?._id
2150
- // let campusId = _campus?._id??campusDefault?._id
2151
-
2152
- // let getUserName = Mixins.generateUsername(firstName, lastName)
2153
- // let email = `${getUserName}@msumarinduque.edu.ph`
2154
-
2155
- // let userId = findUser?._id
2156
-
2157
-
2158
- // if(uNum.has(studentNumber) && uLname.has(lastName) && uFname.has(firstName) && uMname.has(middleName) && uCourse.has(courseId) && uCampus.has(campusId)){
2159
- // const errorMsg = `Duplicate Payload Found: [${studentNumber}] - ${lastName}, ${firstName} ${middleName} [courseId: ${courseId}, campusId:${campusId}]`
2160
- // if(!uniqueErrors.has(errorMsg)){
2161
- // logger.error(`${errorCounter + 1}/${errorCounter + 1}: ${errorMsg}`)
2162
- // uniqueErrors.add(errorMsg)
2163
- // errorCounter++
2164
- // }
2165
- // }
2166
- // else if ( exStudentMap.has(`[${studentNumber}] - ${lastName}, ${firstName} ${middleName} [${courseId}, ${campusId}]`)){
2167
- // const exStudent = exStudentMap.get(`[${studentNumber}] - ${lastName}, ${firstName} ${middleName} [${courseId}, ${campusId}]`)
2168
- // const errorMsg = `Existing Data Found:[${exStudent.studentNumber}] - ${exStudent.lastName}, ${exStudent.firstName} ${exStudent.middleName} [courseId: ${exStudent.courseId}, campusId: ${exStudent.campusId}]`
2169
- // if(!uniqueErrors.has(errorMsg)){
2170
- // logger.error(`${errorCounter + 1}/${errorCounter + 1}: ${errorMsg}`)
2171
- // uniqueErrors.add(errorMsg)
2172
- // errorCounter++
2173
- // }
2174
- // }
2175
- // else{
2176
- // uNum.add(studentNumber)
2177
- // uLname.add(lastName)
2178
- // uMname.add(middleName)
2179
- // uFname.add(firstName)
2180
- // uCourse.add(courseId)
2181
- // uCampus.add(campusId)
2182
- // newStudent.push({
2183
- // studentNumber: _student?.student_number,
2184
- // firstName: _student?.first_name,
2185
- // lastName: _student?.last_name,
2186
- // middleName: _student?.middle_name,
2187
- // email: email,
2188
- // courseId: _course?._id??courseDefault?._id,
2189
- // campusId: _campus?._id??campusDefault?._id,
2190
- // collegeId: _college?._id??collegeDefault?._id,
2191
- // admittedYearId: _acadYear?._id ?? null,
2192
- // admittedSemId: _semester?._id ?? null,
2193
- // modifiedById,
2194
- // createdById,
2195
- // userId
2196
- // })
2197
- // }
2198
-
2199
- // } catch (error) {
2200
- // logger.error(`Error occurred: ${error.stack} ${error}`);
2201
- // }
2202
- // }
2203
-
2204
- // if (newStudent.length > 0) {
2205
- // await Students.bulkCreate(newStudent)
2206
- // createdCounter += newStudent.length
2207
-
2208
- // newStudent.forEach((exStudent, index) => {
2209
- // logger.info(`${index + 1}/${index + 1}: New Student Record Created: [${exStudent.studentNumber}] - ${exStudent.lastName}, ${exStudent.firstName} ${exStudent.middleName} [courseId: ${exStudent.courseId}, campusId: ${exStudent.campusId}]`)
2210
- // });
2211
- // }
2212
-
2213
- // console.log("");
2214
- // console.log("########################################################")
2215
- // console.log("")
2216
- // logger.info('Student Data Migration Completed');
2217
- // logger.info(`Total Successful Student Records Created: ${createdCounter}/${createdCounter}`);
2218
- // logger.info(`Total Existing Student Records: ${errorCounter}/${errorCounter}`);
2219
- // logger.info(`Total Records: ${createdCounter + errorCounter}`);
2220
- // console.log("")
2221
- // console.log("########################################################")
2222
- // console.log("")
2223
-
2224
- // let totalSummary = {
2225
- // itemLength: createdCounter + errorCounter,
2226
- // error: errorCounter,
2227
- // success: createdCounter
2228
- // }
2229
- // return totalSummary
2230
-
2231
- // } catch (error) {
2232
- // logger.error(`Error occurred: ${error.stack} ${error}`);
2233
-
2234
- // }
2235
- // },
2236
-
2237
1990
  async Section() {
2238
1991
  try {
2239
1992
  console.log("");
@@ -2450,7 +2203,6 @@ const server = {
2450
2203
  }
2451
2204
  },
2452
2205
 
2453
-
2454
2206
  async EnrolledStudent(){
2455
2207
  try {
2456
2208
  console.log("");
@@ -2703,6 +2455,7 @@ module.exports = {
2703
2455
  Course: server.Course,
2704
2456
  Room: server.Room,
2705
2457
  Instructor: server.Instructor,
2458
+ AcadDeptInstructor: server.AcadDeptInstructor,
2706
2459
  AcademicYear: server.AcademicYear,
2707
2460
  Subject: server.Subject,
2708
2461
  Schedule: server.Schedule,
@@ -14,8 +14,8 @@ async function promptYearSem() {
14
14
  { title: 'Campus', value: 'Campus' },
15
15
  { title: 'College', value: 'College' },
16
16
  { title: 'AcademicDepartments', value: 'AcademicDepartments' },
17
- // { title: 'UserInstructor', value: 'UserInstructor' },
18
17
  { title: 'Instructor', value: 'Instructor' },
18
+ { title: 'Academic Department Instructors', value: 'AcadDeptInstructor' },
19
19
  { title: 'Course', value: 'Course' },
20
20
  { title: 'Room', value: 'Room' },
21
21
  { title: 'AcademicYear', value: 'AcademicYear' },
package/login.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "email": "ictsc@mscmarinduque.edu.ph",
3
+ "password": "MjU8qweXLaFpDnEyfRrbY9",
4
+ "baseURL": "https://lms.api.msc.priisms.online/api"
5
+ }
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+
3
+
4
+ module.exports = (sequelize, DataTypes,schema) => {
5
+
6
+ const AcademicDepartmentInstructors = sequelize.define('AcademicDepartmentInstructors',
7
+ {
8
+ instructorId: {
9
+ type: DataTypes.INTEGER,
10
+ allowNull: false
11
+ },
12
+ academicDepartmentId: {
13
+ type: DataTypes.INTEGER,
14
+ allowNull: false
15
+ },
16
+ isActive: {
17
+ type: DataTypes.BOOLEAN,
18
+ unique: false,
19
+ allowNull: true,
20
+ autoIncrement: false,
21
+ primaryKey: false,
22
+ defaultValue: true,
23
+ },
24
+ _id: {
25
+ type: DataTypes.INTEGER,
26
+ unique: true,
27
+ allowNull: false,
28
+ autoIncrement: true,
29
+ primaryKey: true,
30
+ },
31
+ createdById: {
32
+ type: DataTypes.INTEGER,
33
+ unique: false,
34
+ allowNull: true,
35
+ autoIncrement: false,
36
+ primaryKey: false,
37
+ },
38
+ modifiedById: {
39
+ type: DataTypes.INTEGER,
40
+ unique: false,
41
+ allowNull: true,
42
+ autoIncrement: false,
43
+ primaryKey: false,
44
+ },
45
+ },
46
+ {
47
+ sequelize,
48
+ schema,
49
+ modelName: "AcademicDepartmentInstructors",
50
+ }
51
+ );
52
+
53
+
54
+ return AcademicDepartmentInstructors;
55
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lms-sync",
3
- "version": "1.0.49",
3
+ "version": "1.0.50",
4
4
  "description": "Migration App for MSC LMS",
5
5
  "main": "index.js",
6
6
  "scripts": {