@eeplatform/core 1.7.4 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/index.d.ts +52 -1
- package/dist/index.js +454 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +459 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -1
package/dist/index.mjs
CHANGED
|
@@ -7039,6 +7039,461 @@ var transactionSchema = Joi17.object({
|
|
|
7039
7039
|
updatedAt: Joi17.string().optional().allow("", null),
|
|
7040
7040
|
deletedAt: Joi17.string().optional().allow("", null)
|
|
7041
7041
|
});
|
|
7042
|
+
|
|
7043
|
+
// src/resources/psgc/psgc.model.ts
|
|
7044
|
+
import Joi18 from "joi";
|
|
7045
|
+
var schemaPSGC = Joi18.object({
|
|
7046
|
+
code: Joi18.string().length(10).required(),
|
|
7047
|
+
name: Joi18.string().required(),
|
|
7048
|
+
type: Joi18.string().valid("Reg", "Prov", "City", "Mun", "Bgy").required()
|
|
7049
|
+
});
|
|
7050
|
+
function modelPSGC(data) {
|
|
7051
|
+
const { error } = schemaPSGC.validate(data);
|
|
7052
|
+
if (error) {
|
|
7053
|
+
throw new Error(`Invalid PSGC data: ${error.message}`);
|
|
7054
|
+
}
|
|
7055
|
+
return {
|
|
7056
|
+
code: data.code,
|
|
7057
|
+
name: data.name,
|
|
7058
|
+
type: data.type
|
|
7059
|
+
};
|
|
7060
|
+
}
|
|
7061
|
+
|
|
7062
|
+
// src/resources/psgc/psgc.repository.ts
|
|
7063
|
+
import {
|
|
7064
|
+
AppError as AppError14,
|
|
7065
|
+
BadRequestError as BadRequestError34,
|
|
7066
|
+
InternalServerError as InternalServerError20,
|
|
7067
|
+
logger as logger19,
|
|
7068
|
+
makeCacheKey as makeCacheKey13,
|
|
7069
|
+
paginate as paginate8,
|
|
7070
|
+
useAtlas as useAtlas18,
|
|
7071
|
+
useCache as useCache14
|
|
7072
|
+
} from "@eeplatform/nodejs-utils";
|
|
7073
|
+
import { ObjectId as ObjectId21 } from "mongodb";
|
|
7074
|
+
function usePSGCRepo() {
|
|
7075
|
+
const db = useAtlas18.getDb();
|
|
7076
|
+
if (!db) {
|
|
7077
|
+
throw new Error("Unable to connect to server.");
|
|
7078
|
+
}
|
|
7079
|
+
const namespace_collection = "psgc";
|
|
7080
|
+
const collection = db.collection(namespace_collection);
|
|
7081
|
+
const { getCache, setCache, delNamespace } = useCache14(namespace_collection);
|
|
7082
|
+
async function createIndexes() {
|
|
7083
|
+
try {
|
|
7084
|
+
await collection.createIndexes([
|
|
7085
|
+
{ key: { name: 1 } },
|
|
7086
|
+
{ key: { name: "text" } },
|
|
7087
|
+
{ key: { code: 1 }, unique: true, name: "unique_code" }
|
|
7088
|
+
]);
|
|
7089
|
+
} catch (error) {
|
|
7090
|
+
throw new Error("Failed to create index on PSGC.");
|
|
7091
|
+
}
|
|
7092
|
+
}
|
|
7093
|
+
function delCachedData() {
|
|
7094
|
+
delNamespace().then(() => {
|
|
7095
|
+
logger19.log({
|
|
7096
|
+
level: "info",
|
|
7097
|
+
message: `Cache namespace cleared for ${namespace_collection}`
|
|
7098
|
+
});
|
|
7099
|
+
}).catch((err) => {
|
|
7100
|
+
logger19.log({
|
|
7101
|
+
level: "error",
|
|
7102
|
+
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
7103
|
+
});
|
|
7104
|
+
});
|
|
7105
|
+
}
|
|
7106
|
+
async function add(value, session) {
|
|
7107
|
+
try {
|
|
7108
|
+
value = modelPSGC(value);
|
|
7109
|
+
const res = await collection.insertOne(value, { session });
|
|
7110
|
+
delCachedData();
|
|
7111
|
+
return res.insertedId;
|
|
7112
|
+
} catch (error) {
|
|
7113
|
+
logger19.log({
|
|
7114
|
+
level: "error",
|
|
7115
|
+
message: error.message
|
|
7116
|
+
});
|
|
7117
|
+
if (error instanceof AppError14) {
|
|
7118
|
+
throw error;
|
|
7119
|
+
} else {
|
|
7120
|
+
const isDuplicated = error.message.includes("duplicate");
|
|
7121
|
+
if (isDuplicated) {
|
|
7122
|
+
throw new BadRequestError34("Region already exists.");
|
|
7123
|
+
}
|
|
7124
|
+
throw new Error("Failed to create PSGC.");
|
|
7125
|
+
}
|
|
7126
|
+
}
|
|
7127
|
+
}
|
|
7128
|
+
async function getAll({
|
|
7129
|
+
search = "",
|
|
7130
|
+
page = 1,
|
|
7131
|
+
limit = 10,
|
|
7132
|
+
sort = {},
|
|
7133
|
+
type = "",
|
|
7134
|
+
prefix = ""
|
|
7135
|
+
} = {}) {
|
|
7136
|
+
page = page > 0 ? page - 1 : 0;
|
|
7137
|
+
const query = {
|
|
7138
|
+
type
|
|
7139
|
+
};
|
|
7140
|
+
const cacheKeyOptions = {
|
|
7141
|
+
type,
|
|
7142
|
+
page,
|
|
7143
|
+
limit,
|
|
7144
|
+
sort: JSON.stringify(sort)
|
|
7145
|
+
};
|
|
7146
|
+
if (prefix) {
|
|
7147
|
+
query.code = { $regex: `^${prefix}` };
|
|
7148
|
+
cacheKeyOptions.prefix = prefix;
|
|
7149
|
+
}
|
|
7150
|
+
if (type === "City" || type === "Mun") {
|
|
7151
|
+
query.type = { $in: ["City", "Mun"] };
|
|
7152
|
+
}
|
|
7153
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: 1 };
|
|
7154
|
+
if (search) {
|
|
7155
|
+
query.$text = { $search: search };
|
|
7156
|
+
cacheKeyOptions.search = search;
|
|
7157
|
+
}
|
|
7158
|
+
const cacheKey = makeCacheKey13(namespace_collection, cacheKeyOptions);
|
|
7159
|
+
logger19.log({
|
|
7160
|
+
level: "info",
|
|
7161
|
+
message: `Cache key for getAll PSGC: ${cacheKey}`
|
|
7162
|
+
});
|
|
7163
|
+
try {
|
|
7164
|
+
const cached = await getCache(cacheKey);
|
|
7165
|
+
if (cached) {
|
|
7166
|
+
logger19.log({
|
|
7167
|
+
level: "info",
|
|
7168
|
+
message: `Cache hit for getAll PSGC: ${cacheKey}`
|
|
7169
|
+
});
|
|
7170
|
+
return cached;
|
|
7171
|
+
}
|
|
7172
|
+
const items = await collection.aggregate([
|
|
7173
|
+
{ $match: query },
|
|
7174
|
+
{ $sort: sort },
|
|
7175
|
+
{ $skip: page * limit },
|
|
7176
|
+
{ $limit: limit }
|
|
7177
|
+
]).toArray();
|
|
7178
|
+
const length = await collection.countDocuments(query);
|
|
7179
|
+
const data = paginate8(items, page, limit, length);
|
|
7180
|
+
setCache(cacheKey, data, 600).then(() => {
|
|
7181
|
+
logger19.log({
|
|
7182
|
+
level: "info",
|
|
7183
|
+
message: `Cache set for getAll PSGC: ${cacheKey}`
|
|
7184
|
+
});
|
|
7185
|
+
}).catch((err) => {
|
|
7186
|
+
logger19.log({
|
|
7187
|
+
level: "error",
|
|
7188
|
+
message: `Failed to set cache for getAll PSGC: ${err.message}`
|
|
7189
|
+
});
|
|
7190
|
+
});
|
|
7191
|
+
return data;
|
|
7192
|
+
} catch (error) {
|
|
7193
|
+
logger19.log({ level: "error", message: `${error}` });
|
|
7194
|
+
throw error;
|
|
7195
|
+
}
|
|
7196
|
+
}
|
|
7197
|
+
async function getById(_id) {
|
|
7198
|
+
try {
|
|
7199
|
+
_id = new ObjectId21(_id);
|
|
7200
|
+
} catch (error) {
|
|
7201
|
+
throw new BadRequestError34("Invalid ID.");
|
|
7202
|
+
}
|
|
7203
|
+
const cacheKey = makeCacheKey13(namespace_collection, { _id: String(_id) });
|
|
7204
|
+
try {
|
|
7205
|
+
const cached = await getCache(cacheKey);
|
|
7206
|
+
if (cached) {
|
|
7207
|
+
logger19.log({
|
|
7208
|
+
level: "info",
|
|
7209
|
+
message: `Cache hit for getById PSGC: ${cacheKey}`
|
|
7210
|
+
});
|
|
7211
|
+
return cached;
|
|
7212
|
+
}
|
|
7213
|
+
const result = await collection.findOne({
|
|
7214
|
+
_id,
|
|
7215
|
+
deletedAt: { $in: ["", null] }
|
|
7216
|
+
});
|
|
7217
|
+
if (!result) {
|
|
7218
|
+
throw new BadRequestError34("Region not found.");
|
|
7219
|
+
}
|
|
7220
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
7221
|
+
logger19.log({
|
|
7222
|
+
level: "info",
|
|
7223
|
+
message: `Cache set for PSGC by id: ${cacheKey}`
|
|
7224
|
+
});
|
|
7225
|
+
}).catch((err) => {
|
|
7226
|
+
logger19.log({
|
|
7227
|
+
level: "error",
|
|
7228
|
+
message: `Failed to set cache for PSGC by id: ${err.message}`
|
|
7229
|
+
});
|
|
7230
|
+
});
|
|
7231
|
+
return result;
|
|
7232
|
+
} catch (error) {
|
|
7233
|
+
if (error instanceof AppError14) {
|
|
7234
|
+
throw error;
|
|
7235
|
+
} else {
|
|
7236
|
+
throw new InternalServerError20("Failed to get PSGC.");
|
|
7237
|
+
}
|
|
7238
|
+
}
|
|
7239
|
+
}
|
|
7240
|
+
async function getByName({ name, prefix = "", type = "" } = {}) {
|
|
7241
|
+
const query = { $text: { $search: name } };
|
|
7242
|
+
const cacheKeyOptions = { name };
|
|
7243
|
+
if (["City", "Mun"].includes(type)) {
|
|
7244
|
+
query.type = { $in: ["City", "Mun"] };
|
|
7245
|
+
cacheKeyOptions.type = type;
|
|
7246
|
+
}
|
|
7247
|
+
if (prefix) {
|
|
7248
|
+
query.code = { $regex: `^${prefix}` };
|
|
7249
|
+
cacheKeyOptions.prefix = prefix;
|
|
7250
|
+
}
|
|
7251
|
+
const cacheKey = makeCacheKey13(namespace_collection, { name });
|
|
7252
|
+
try {
|
|
7253
|
+
const cached = await getCache(cacheKey);
|
|
7254
|
+
if (cached) {
|
|
7255
|
+
logger19.log({
|
|
7256
|
+
level: "info",
|
|
7257
|
+
message: `Cache hit for getByName PSGC: ${cacheKey}`
|
|
7258
|
+
});
|
|
7259
|
+
return cached;
|
|
7260
|
+
}
|
|
7261
|
+
const result = await collection.findOne(query);
|
|
7262
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
7263
|
+
logger19.log({
|
|
7264
|
+
level: "info",
|
|
7265
|
+
message: `Cache set for PSGC by name: ${cacheKey}`
|
|
7266
|
+
});
|
|
7267
|
+
}).catch((err) => {
|
|
7268
|
+
logger19.log({
|
|
7269
|
+
level: "error",
|
|
7270
|
+
message: `Failed to set cache for PSGC by name: ${err.message}`
|
|
7271
|
+
});
|
|
7272
|
+
});
|
|
7273
|
+
return result;
|
|
7274
|
+
} catch (error) {
|
|
7275
|
+
if (error instanceof AppError14) {
|
|
7276
|
+
throw error;
|
|
7277
|
+
} else {
|
|
7278
|
+
throw new InternalServerError20("Failed to get PSGC.");
|
|
7279
|
+
}
|
|
7280
|
+
}
|
|
7281
|
+
}
|
|
7282
|
+
async function updateFieldById({ _id, field, value } = {}, session) {
|
|
7283
|
+
const allowedFields = ["name"];
|
|
7284
|
+
if (!allowedFields.includes(field)) {
|
|
7285
|
+
throw new BadRequestError34(
|
|
7286
|
+
`Field "${field}" is not allowed to be updated.`
|
|
7287
|
+
);
|
|
7288
|
+
}
|
|
7289
|
+
try {
|
|
7290
|
+
_id = new ObjectId21(_id);
|
|
7291
|
+
} catch (error) {
|
|
7292
|
+
throw new BadRequestError34("Invalid ID.");
|
|
7293
|
+
}
|
|
7294
|
+
try {
|
|
7295
|
+
await collection.updateOne(
|
|
7296
|
+
{ _id, deletedAt: { $in: ["", null] } },
|
|
7297
|
+
{ $set: { [field]: value, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
|
|
7298
|
+
{ session }
|
|
7299
|
+
);
|
|
7300
|
+
delCachedData();
|
|
7301
|
+
return `Successfully updated PSGC ${field}.`;
|
|
7302
|
+
} catch (error) {
|
|
7303
|
+
throw new InternalServerError20(`Failed to update PSGC ${field}.`);
|
|
7304
|
+
}
|
|
7305
|
+
}
|
|
7306
|
+
async function deleteById(_id) {
|
|
7307
|
+
try {
|
|
7308
|
+
_id = new ObjectId21(_id);
|
|
7309
|
+
} catch (error) {
|
|
7310
|
+
throw new BadRequestError34("Invalid ID.");
|
|
7311
|
+
}
|
|
7312
|
+
try {
|
|
7313
|
+
await collection.updateOne(
|
|
7314
|
+
{ _id },
|
|
7315
|
+
{ $set: { status: "deleted", deletedAt: (/* @__PURE__ */ new Date()).toISOString() } }
|
|
7316
|
+
);
|
|
7317
|
+
delCachedData();
|
|
7318
|
+
return "Successfully deleted PSGC.";
|
|
7319
|
+
} catch (error) {
|
|
7320
|
+
throw new InternalServerError20("Failed to delete PSGC.");
|
|
7321
|
+
}
|
|
7322
|
+
}
|
|
7323
|
+
return {
|
|
7324
|
+
createIndexes,
|
|
7325
|
+
add,
|
|
7326
|
+
getAll,
|
|
7327
|
+
getById,
|
|
7328
|
+
updateFieldById,
|
|
7329
|
+
deleteById,
|
|
7330
|
+
getByName
|
|
7331
|
+
};
|
|
7332
|
+
}
|
|
7333
|
+
|
|
7334
|
+
// src/resources/psgc/psgc.controller.ts
|
|
7335
|
+
import { BadRequestError as BadRequestError35 } from "@eeplatform/nodejs-utils";
|
|
7336
|
+
import Joi19 from "joi";
|
|
7337
|
+
function usePSGCController() {
|
|
7338
|
+
const {
|
|
7339
|
+
add: _add,
|
|
7340
|
+
getAll: _getAll,
|
|
7341
|
+
getById: _getById,
|
|
7342
|
+
getByName: _getByName,
|
|
7343
|
+
updateFieldById: _updateFieldById,
|
|
7344
|
+
deleteById: _deleteById
|
|
7345
|
+
} = usePSGCRepo();
|
|
7346
|
+
async function add(req, res, next) {
|
|
7347
|
+
const value = req.body;
|
|
7348
|
+
const { error } = schemaPSGC.validate(value);
|
|
7349
|
+
if (error) {
|
|
7350
|
+
next(new BadRequestError35(error.message));
|
|
7351
|
+
return;
|
|
7352
|
+
}
|
|
7353
|
+
try {
|
|
7354
|
+
const data = await _add(value);
|
|
7355
|
+
res.json({
|
|
7356
|
+
message: "Successfully created region.",
|
|
7357
|
+
data
|
|
7358
|
+
});
|
|
7359
|
+
return;
|
|
7360
|
+
} catch (error2) {
|
|
7361
|
+
next(error2);
|
|
7362
|
+
}
|
|
7363
|
+
}
|
|
7364
|
+
async function getAll(req, res, next) {
|
|
7365
|
+
const query = req.query;
|
|
7366
|
+
const validation = Joi19.object({
|
|
7367
|
+
page: Joi19.number().min(1).optional().allow("", null),
|
|
7368
|
+
limit: Joi19.number().min(1).optional().allow("", null),
|
|
7369
|
+
search: Joi19.string().optional().allow("", null),
|
|
7370
|
+
type: Joi19.string().valid("Reg", "Prov", "City", "Mun", "Bgy").required(),
|
|
7371
|
+
prefix: Joi19.string().optional().allow("", null)
|
|
7372
|
+
});
|
|
7373
|
+
const { error } = validation.validate(query);
|
|
7374
|
+
const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
|
|
7375
|
+
const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
|
|
7376
|
+
const search = req.query.search ?? "";
|
|
7377
|
+
const type = req.query.type ?? "";
|
|
7378
|
+
const prefix = req.query.prefix ? String(req.query.prefix) : "";
|
|
7379
|
+
const isPageNumber = isFinite(page);
|
|
7380
|
+
if (!isPageNumber) {
|
|
7381
|
+
next(new BadRequestError35("Invalid page number."));
|
|
7382
|
+
return;
|
|
7383
|
+
}
|
|
7384
|
+
const isLimitNumber = isFinite(limit);
|
|
7385
|
+
if (!isLimitNumber) {
|
|
7386
|
+
next(new BadRequestError35("Invalid limit number."));
|
|
7387
|
+
return;
|
|
7388
|
+
}
|
|
7389
|
+
if (error) {
|
|
7390
|
+
next(new BadRequestError35(error.message));
|
|
7391
|
+
return;
|
|
7392
|
+
}
|
|
7393
|
+
try {
|
|
7394
|
+
const data = await _getAll({
|
|
7395
|
+
page,
|
|
7396
|
+
limit,
|
|
7397
|
+
search,
|
|
7398
|
+
type,
|
|
7399
|
+
prefix
|
|
7400
|
+
});
|
|
7401
|
+
res.json(data);
|
|
7402
|
+
return;
|
|
7403
|
+
} catch (error2) {
|
|
7404
|
+
next(error2);
|
|
7405
|
+
}
|
|
7406
|
+
}
|
|
7407
|
+
async function getById(req, res, next) {
|
|
7408
|
+
const id = req.params.id;
|
|
7409
|
+
const validation = Joi19.object({
|
|
7410
|
+
id: Joi19.string().hex().required()
|
|
7411
|
+
});
|
|
7412
|
+
const { error } = validation.validate({ id });
|
|
7413
|
+
if (error) {
|
|
7414
|
+
next(new BadRequestError35(error.message));
|
|
7415
|
+
return;
|
|
7416
|
+
}
|
|
7417
|
+
try {
|
|
7418
|
+
const data = await _getById(id);
|
|
7419
|
+
res.json({
|
|
7420
|
+
message: "Successfully retrieved region.",
|
|
7421
|
+
data
|
|
7422
|
+
});
|
|
7423
|
+
return;
|
|
7424
|
+
} catch (error2) {
|
|
7425
|
+
next(error2);
|
|
7426
|
+
}
|
|
7427
|
+
}
|
|
7428
|
+
async function getByName(req, res, next) {
|
|
7429
|
+
const name = req.params.name;
|
|
7430
|
+
const validation = Joi19.object({
|
|
7431
|
+
name: Joi19.string().required()
|
|
7432
|
+
});
|
|
7433
|
+
const { error } = validation.validate({ name });
|
|
7434
|
+
if (error) {
|
|
7435
|
+
next(new BadRequestError35(error.message));
|
|
7436
|
+
return;
|
|
7437
|
+
}
|
|
7438
|
+
try {
|
|
7439
|
+
const data = await _getByName({ name });
|
|
7440
|
+
res.json({
|
|
7441
|
+
message: "Successfully retrieved region.",
|
|
7442
|
+
data
|
|
7443
|
+
});
|
|
7444
|
+
return;
|
|
7445
|
+
} catch (error2) {
|
|
7446
|
+
next(error2);
|
|
7447
|
+
}
|
|
7448
|
+
}
|
|
7449
|
+
async function updateField(req, res, next) {
|
|
7450
|
+
const _id = req.params.id;
|
|
7451
|
+
const { field, value } = req.body;
|
|
7452
|
+
const validation = Joi19.object({
|
|
7453
|
+
_id: Joi19.string().hex().required(),
|
|
7454
|
+
field: Joi19.string().valid("name", "director", "directorName").required(),
|
|
7455
|
+
value: Joi19.string().required()
|
|
7456
|
+
});
|
|
7457
|
+
const { error } = validation.validate({ _id, field, value });
|
|
7458
|
+
if (error) {
|
|
7459
|
+
next(new BadRequestError35(error.message));
|
|
7460
|
+
return;
|
|
7461
|
+
}
|
|
7462
|
+
try {
|
|
7463
|
+
const message = await _updateFieldById({ _id, field, value });
|
|
7464
|
+
res.json({ message });
|
|
7465
|
+
return;
|
|
7466
|
+
} catch (error2) {
|
|
7467
|
+
next(error2);
|
|
7468
|
+
}
|
|
7469
|
+
}
|
|
7470
|
+
async function deleteById(req, res, next) {
|
|
7471
|
+
const _id = req.params.id;
|
|
7472
|
+
const validation = Joi19.object({
|
|
7473
|
+
_id: Joi19.string().hex().required()
|
|
7474
|
+
});
|
|
7475
|
+
const { error } = validation.validate({ _id });
|
|
7476
|
+
if (error) {
|
|
7477
|
+
next(new BadRequestError35(error.message));
|
|
7478
|
+
return;
|
|
7479
|
+
}
|
|
7480
|
+
try {
|
|
7481
|
+
const message = await _deleteById(_id);
|
|
7482
|
+
res.json({ message });
|
|
7483
|
+
return;
|
|
7484
|
+
} catch (error2) {
|
|
7485
|
+
next(error2);
|
|
7486
|
+
}
|
|
7487
|
+
}
|
|
7488
|
+
return {
|
|
7489
|
+
add,
|
|
7490
|
+
getAll,
|
|
7491
|
+
getById,
|
|
7492
|
+
getByName,
|
|
7493
|
+
updateField,
|
|
7494
|
+
deleteById
|
|
7495
|
+
};
|
|
7496
|
+
}
|
|
7042
7497
|
export {
|
|
7043
7498
|
ACCESS_TOKEN_EXPIRY,
|
|
7044
7499
|
ACCESS_TOKEN_SECRET,
|
|
@@ -7090,9 +7545,11 @@ export {
|
|
|
7090
7545
|
XENDIT_SECRET_KEY,
|
|
7091
7546
|
addressSchema,
|
|
7092
7547
|
isDev,
|
|
7548
|
+
modelPSGC,
|
|
7093
7549
|
schemaBuilding,
|
|
7094
7550
|
schemaBuildingUnit,
|
|
7095
7551
|
schemaOrg,
|
|
7552
|
+
schemaPSGC,
|
|
7096
7553
|
schemaUpdateOptions,
|
|
7097
7554
|
transactionSchema,
|
|
7098
7555
|
useAddressController,
|
|
@@ -7118,6 +7575,8 @@ export {
|
|
|
7118
7575
|
useOrgController,
|
|
7119
7576
|
useOrgRepo,
|
|
7120
7577
|
useOrgService,
|
|
7578
|
+
usePSGCController,
|
|
7579
|
+
usePSGCRepo,
|
|
7121
7580
|
useRoleController,
|
|
7122
7581
|
useRoleRepo,
|
|
7123
7582
|
useTokenRepo,
|