@eeplatform/core 1.4.3 → 1.4.5

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/dist/index.js CHANGED
@@ -10384,7 +10384,7 @@ var require_ms = __commonJS({
10384
10384
  options = options || {};
10385
10385
  var type = typeof val;
10386
10386
  if (type === "string" && val.length > 0) {
10387
- return parse(val);
10387
+ return parse3(val);
10388
10388
  } else if (type === "number" && isNaN(val) === false) {
10389
10389
  return options.long ? fmtLong(val) : fmtShort(val);
10390
10390
  }
@@ -10392,7 +10392,7 @@ var require_ms = __commonJS({
10392
10392
  "val is not a non-empty string or a valid number. val=" + JSON.stringify(val)
10393
10393
  );
10394
10394
  };
10395
- function parse(str) {
10395
+ function parse3(str) {
10396
10396
  str = String(str);
10397
10397
  if (str.length > 100) {
10398
10398
  return;
@@ -10839,7 +10839,7 @@ var require_follow_redirects = __commonJS({
10839
10839
  (function detectUnsupportedEnvironment() {
10840
10840
  var looksLikeNode = typeof process !== "undefined";
10841
10841
  var looksLikeBrowser = typeof window !== "undefined" && typeof document !== "undefined";
10842
- var looksLikeV8 = isFunction2(Error.captureStackTrace);
10842
+ var looksLikeV8 = isFunction3(Error.captureStackTrace);
10843
10843
  if (!looksLikeNode && (looksLikeBrowser || !looksLikeV8)) {
10844
10844
  console.warn("The follow-redirects package should be excluded from browser builds.");
10845
10845
  }
@@ -10934,7 +10934,7 @@ var require_follow_redirects = __commonJS({
10934
10934
  if (!isString2(data) && !isBuffer2(data)) {
10935
10935
  throw new TypeError("data should be a string, Buffer or Uint8Array");
10936
10936
  }
10937
- if (isFunction2(encoding)) {
10937
+ if (isFunction3(encoding)) {
10938
10938
  callback = encoding;
10939
10939
  encoding = null;
10940
10940
  }
@@ -10954,10 +10954,10 @@ var require_follow_redirects = __commonJS({
10954
10954
  }
10955
10955
  };
10956
10956
  RedirectableRequest.prototype.end = function(data, encoding, callback) {
10957
- if (isFunction2(data)) {
10957
+ if (isFunction3(data)) {
10958
10958
  callback = data;
10959
10959
  data = encoding = null;
10960
- } else if (isFunction2(encoding)) {
10960
+ } else if (isFunction3(encoding)) {
10961
10961
  callback = encoding;
10962
10962
  encoding = null;
10963
10963
  }
@@ -11158,7 +11158,7 @@ var require_follow_redirects = __commonJS({
11158
11158
  if (redirectUrl.protocol !== currentUrlParts.protocol && redirectUrl.protocol !== "https:" || redirectUrl.host !== currentHost && !isSubdomain(redirectUrl.host, currentHost)) {
11159
11159
  removeMatchingHeaders(/^(?:(?:proxy-)?authorization|cookie)$/i, this._options.headers);
11160
11160
  }
11161
- if (isFunction2(beforeRedirect)) {
11161
+ if (isFunction3(beforeRedirect)) {
11162
11162
  var responseDetails = {
11163
11163
  headers: response.headers,
11164
11164
  statusCode
@@ -11193,7 +11193,7 @@ var require_follow_redirects = __commonJS({
11193
11193
  options = validateUrl(input);
11194
11194
  input = { protocol };
11195
11195
  }
11196
- if (isFunction2(options)) {
11196
+ if (isFunction3(options)) {
11197
11197
  callback = options;
11198
11198
  options = null;
11199
11199
  }
@@ -11273,7 +11273,7 @@ var require_follow_redirects = __commonJS({
11273
11273
  }
11274
11274
  function createErrorType(code, message, baseClass) {
11275
11275
  function CustomError(properties) {
11276
- if (isFunction2(Error.captureStackTrace)) {
11276
+ if (isFunction3(Error.captureStackTrace)) {
11277
11277
  Error.captureStackTrace(this, this.constructor);
11278
11278
  }
11279
11279
  Object.assign(this, properties || {});
@@ -11308,7 +11308,7 @@ var require_follow_redirects = __commonJS({
11308
11308
  function isString2(value) {
11309
11309
  return typeof value === "string" || value instanceof String;
11310
11310
  }
11311
- function isFunction2(value) {
11311
+ function isFunction3(value) {
11312
11312
  return typeof value === "function";
11313
11313
  }
11314
11314
  function isBuffer2(value) {
@@ -11354,6 +11354,7 @@ __export(src_exports, {
11354
11354
  MOrder: () => MOrder,
11355
11355
  MOrg: () => MOrg,
11356
11356
  MPaymentMethod: () => MPaymentMethod,
11357
+ MPlantilla: () => MPlantilla,
11357
11358
  MPromoCode: () => MPromoCode,
11358
11359
  MRegion: () => MRegion,
11359
11360
  MRole: () => MRole,
@@ -11391,6 +11392,7 @@ __export(src_exports, {
11391
11392
  schemaBuilding: () => schemaBuilding,
11392
11393
  schemaBuildingUnit: () => schemaBuildingUnit,
11393
11394
  schemaDivision: () => schemaDivision,
11395
+ schemaPlantilla: () => schemaPlantilla,
11394
11396
  schemaRegion: () => schemaRegion,
11395
11397
  schemaSchool: () => schemaSchool,
11396
11398
  schemaStockCard: () => schemaStockCard,
@@ -11415,6 +11417,7 @@ __export(src_exports, {
11415
11417
  useFileController: () => useFileController,
11416
11418
  useFileRepo: () => useFileRepo,
11417
11419
  useFileService: () => useFileService,
11420
+ useGitHubService: () => useGitHubService,
11418
11421
  useInvoiceController: () => useInvoiceController,
11419
11422
  useInvoiceModel: () => useInvoiceModel,
11420
11423
  useInvoiceRepo: () => useInvoiceRepo,
@@ -11433,6 +11436,8 @@ __export(src_exports, {
11433
11436
  usePaymentModel: () => usePaymentModel,
11434
11437
  usePaymentRepo: () => usePaymentRepo,
11435
11438
  usePaypalService: () => usePaypalService,
11439
+ usePlantillaController: () => usePlantillaController,
11440
+ usePlantillaRepo: () => usePlantillaRepo,
11436
11441
  usePriceController: () => usePriceController,
11437
11442
  usePriceModel: () => usePriceModel,
11438
11443
  usePriceRepo: () => usePriceRepo,
@@ -11455,6 +11460,7 @@ __export(src_exports, {
11455
11460
  useUserController: () => useUserController,
11456
11461
  useUserRepo: () => useUserRepo,
11457
11462
  useUserService: () => useUserService,
11463
+ useUtilController: () => useUtilController,
11458
11464
  useVerificationController: () => useVerificationController,
11459
11465
  useVerificationRepo: () => useVerificationRepo,
11460
11466
  useVerificationService: () => useVerificationService,
@@ -13646,7 +13652,7 @@ var _global = (() => {
13646
13652
  })();
13647
13653
  var isContextDefined = (context) => !isUndefined(context) && context !== _global;
13648
13654
  function merge() {
13649
- const { caseless } = isContextDefined(this) && this || {};
13655
+ const { caseless, skipUndefined } = isContextDefined(this) && this || {};
13650
13656
  const result = {};
13651
13657
  const assignValue = (val, key) => {
13652
13658
  const targetKey = caseless && findKey(result, key) || key;
@@ -13656,7 +13662,7 @@ function merge() {
13656
13662
  result[targetKey] = merge({}, val);
13657
13663
  } else if (isArray(val)) {
13658
13664
  result[targetKey] = val.slice();
13659
- } else {
13665
+ } else if (!skipUndefined || !isUndefined(val)) {
13660
13666
  result[targetKey] = val;
13661
13667
  }
13662
13668
  };
@@ -13992,9 +13998,13 @@ AxiosError.from = (error, code, config2, request, response, customProps) => {
13992
13998
  }, (prop) => {
13993
13999
  return prop !== "isAxiosError";
13994
14000
  });
13995
- AxiosError.call(axiosError, error.message, code, config2, request, response);
13996
- axiosError.cause = error;
13997
- axiosError.name = error.name;
14001
+ const msg = error && error.message ? error.message : "Error";
14002
+ const errCode = code == null && error ? error.code : code;
14003
+ AxiosError.call(axiosError, msg, errCode, config2, request, response);
14004
+ if (error && axiosError.cause == null) {
14005
+ Object.defineProperty(axiosError, "cause", { value: error, configurable: true });
14006
+ }
14007
+ axiosError.name = error && error.name || "Error";
13998
14008
  customProps && Object.assign(axiosError, customProps);
13999
14009
  return axiosError;
14000
14010
  };
@@ -14157,7 +14167,7 @@ var AxiosURLSearchParams_default = AxiosURLSearchParams;
14157
14167
 
14158
14168
  // node_modules/axios/lib/helpers/buildURL.js
14159
14169
  function encode2(val) {
14160
- return encodeURIComponent(val).replace(/%3A/gi, ":").replace(/%24/g, "$").replace(/%2C/gi, ",").replace(/%20/g, "+").replace(/%5B/gi, "[").replace(/%5D/gi, "]");
14170
+ return encodeURIComponent(val).replace(/%3A/gi, ":").replace(/%24/g, "$").replace(/%2C/gi, ",").replace(/%20/g, "+");
14161
14171
  }
14162
14172
  function buildURL(url2, params, options) {
14163
14173
  if (!params) {
@@ -14455,7 +14465,7 @@ var defaults = {
14455
14465
  const silentJSONParsing = transitional2 && transitional2.silentJSONParsing;
14456
14466
  const strictJSONParsing = !silentJSONParsing && JSONRequested;
14457
14467
  try {
14458
- return JSON.parse(data);
14468
+ return JSON.parse(data, this.parseReviver);
14459
14469
  } catch (e) {
14460
14470
  if (strictJSONParsing) {
14461
14471
  if (e.name === "SyntaxError") {
@@ -14842,7 +14852,7 @@ var import_follow_redirects = __toESM(require_follow_redirects(), 1);
14842
14852
  var import_zlib = __toESM(require("zlib"), 1);
14843
14853
 
14844
14854
  // node_modules/axios/lib/env/data.js
14845
- var VERSION = "1.11.0";
14855
+ var VERSION = "1.12.2";
14846
14856
 
14847
14857
  // node_modules/axios/lib/helpers/parseProtocol.js
14848
14858
  function parseProtocol(url2) {
@@ -15241,6 +15251,60 @@ var progressEventDecorator = (total, throttled) => {
15241
15251
  };
15242
15252
  var asyncDecorator = (fn) => (...args) => utils_default.asap(() => fn(...args));
15243
15253
 
15254
+ // node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js
15255
+ function estimateDataURLDecodedBytes(url2) {
15256
+ if (!url2 || typeof url2 !== "string")
15257
+ return 0;
15258
+ if (!url2.startsWith("data:"))
15259
+ return 0;
15260
+ const comma = url2.indexOf(",");
15261
+ if (comma < 0)
15262
+ return 0;
15263
+ const meta = url2.slice(5, comma);
15264
+ const body = url2.slice(comma + 1);
15265
+ const isBase64 = /;base64/i.test(meta);
15266
+ if (isBase64) {
15267
+ let effectiveLen = body.length;
15268
+ const len = body.length;
15269
+ for (let i = 0; i < len; i++) {
15270
+ if (body.charCodeAt(i) === 37 && i + 2 < len) {
15271
+ const a = body.charCodeAt(i + 1);
15272
+ const b = body.charCodeAt(i + 2);
15273
+ const isHex = (a >= 48 && a <= 57 || a >= 65 && a <= 70 || a >= 97 && a <= 102) && (b >= 48 && b <= 57 || b >= 65 && b <= 70 || b >= 97 && b <= 102);
15274
+ if (isHex) {
15275
+ effectiveLen -= 2;
15276
+ i += 2;
15277
+ }
15278
+ }
15279
+ }
15280
+ let pad = 0;
15281
+ let idx = len - 1;
15282
+ const tailIsPct3D = (j) => j >= 2 && body.charCodeAt(j - 2) === 37 && // '%'
15283
+ body.charCodeAt(j - 1) === 51 && // '3'
15284
+ (body.charCodeAt(j) === 68 || body.charCodeAt(j) === 100);
15285
+ if (idx >= 0) {
15286
+ if (body.charCodeAt(idx) === 61) {
15287
+ pad++;
15288
+ idx--;
15289
+ } else if (tailIsPct3D(idx)) {
15290
+ pad++;
15291
+ idx -= 3;
15292
+ }
15293
+ }
15294
+ if (pad === 1 && idx >= 0) {
15295
+ if (body.charCodeAt(idx) === 61) {
15296
+ pad++;
15297
+ } else if (tailIsPct3D(idx)) {
15298
+ pad++;
15299
+ }
15300
+ }
15301
+ const groups = Math.floor(effectiveLen / 4);
15302
+ const bytes = groups * 3 - (pad || 0);
15303
+ return bytes > 0 ? bytes : 0;
15304
+ }
15305
+ return Buffer.byteLength(body, "utf8");
15306
+ }
15307
+
15244
15308
  // node_modules/axios/lib/adapters/http.js
15245
15309
  var zlibOptions = {
15246
15310
  flush: import_zlib.default.constants.Z_SYNC_FLUSH,
@@ -15384,6 +15448,17 @@ var http_default = isHttpAdapterSupported && function httpAdapter(config2) {
15384
15448
  const parsed = new URL(fullPath, platform_default.hasBrowserEnv ? platform_default.origin : void 0);
15385
15449
  const protocol = parsed.protocol || supportedProtocols[0];
15386
15450
  if (protocol === "data:") {
15451
+ if (config2.maxContentLength > -1) {
15452
+ const dataUrl = String(config2.url || fullPath || "");
15453
+ const estimated = estimateDataURLDecodedBytes(dataUrl);
15454
+ if (estimated > config2.maxContentLength) {
15455
+ return reject(new AxiosError_default(
15456
+ "maxContentLength size of " + config2.maxContentLength + " exceeded",
15457
+ AxiosError_default.ERR_BAD_RESPONSE,
15458
+ config2
15459
+ ));
15460
+ }
15461
+ }
15387
15462
  let convertedData;
15388
15463
  if (method !== "GET") {
15389
15464
  return settle(resolve, reject, {
@@ -15879,13 +15954,17 @@ var resolveConfig_default = (config2) => {
15879
15954
  "Basic " + btoa((auth.username || "") + ":" + (auth.password ? unescape(encodeURIComponent(auth.password)) : ""))
15880
15955
  );
15881
15956
  }
15882
- let contentType;
15883
15957
  if (utils_default.isFormData(data)) {
15884
15958
  if (platform_default.hasStandardBrowserEnv || platform_default.hasStandardBrowserWebWorkerEnv) {
15885
15959
  headers.setContentType(void 0);
15886
- } else if ((contentType = headers.getContentType()) !== false) {
15887
- const [type, ...tokens] = contentType ? contentType.split(";").map((token) => token.trim()).filter(Boolean) : [];
15888
- headers.setContentType([type || "multipart/form-data", ...tokens].join("; "));
15960
+ } else if (utils_default.isFunction(data.getHeaders)) {
15961
+ const formHeaders = data.getHeaders();
15962
+ const allowedHeaders = ["content-type", "content-length"];
15963
+ Object.entries(formHeaders).forEach(([key, val]) => {
15964
+ if (allowedHeaders.includes(key.toLowerCase())) {
15965
+ headers.set(key, val);
15966
+ }
15967
+ });
15889
15968
  }
15890
15969
  }
15891
15970
  if (platform_default.hasStandardBrowserEnv) {
@@ -15965,8 +16044,11 @@ var xhr_default = isXHRAdapterSupported && function(config2) {
15965
16044
  reject(new AxiosError_default("Request aborted", AxiosError_default.ECONNABORTED, config2, request));
15966
16045
  request = null;
15967
16046
  };
15968
- request.onerror = function handleError() {
15969
- reject(new AxiosError_default("Network Error", AxiosError_default.ERR_NETWORK, config2, request));
16047
+ request.onerror = function handleError(event) {
16048
+ const msg = event && event.message ? event.message : "Network Error";
16049
+ const err = new AxiosError_default(msg, AxiosError_default.ERR_NETWORK, config2, request);
16050
+ err.event = event || null;
16051
+ reject(err);
15970
16052
  request = null;
15971
16053
  };
15972
16054
  request.ontimeout = function handleTimeout() {
@@ -16141,9 +16223,16 @@ var trackStream = (stream4, chunkSize, onProgress, onFinish) => {
16141
16223
  };
16142
16224
 
16143
16225
  // node_modules/axios/lib/adapters/fetch.js
16144
- var isFetchSupported = typeof fetch === "function" && typeof Request === "function" && typeof Response === "function";
16145
- var isReadableStreamSupported = isFetchSupported && typeof ReadableStream === "function";
16146
- var encodeText = isFetchSupported && (typeof TextEncoder === "function" ? ((encoder) => (str) => encoder.encode(str))(new TextEncoder()) : async (str) => new Uint8Array(await new Response(str).arrayBuffer()));
16226
+ var DEFAULT_CHUNK_SIZE = 64 * 1024;
16227
+ var { isFunction: isFunction2 } = utils_default;
16228
+ var globalFetchAPI = (({ Request, Response }) => ({
16229
+ Request,
16230
+ Response
16231
+ }))(utils_default.global);
16232
+ var {
16233
+ ReadableStream: ReadableStream2,
16234
+ TextEncoder: TextEncoder2
16235
+ } = utils_default.global;
16147
16236
  var test = (fn, ...args) => {
16148
16237
  try {
16149
16238
  return !!fn(...args);
@@ -16151,164 +16240,204 @@ var test = (fn, ...args) => {
16151
16240
  return false;
16152
16241
  }
16153
16242
  };
16154
- var supportsRequestStream = isReadableStreamSupported && test(() => {
16155
- let duplexAccessed = false;
16156
- const hasContentType = new Request(platform_default.origin, {
16157
- body: new ReadableStream(),
16158
- method: "POST",
16159
- get duplex() {
16160
- duplexAccessed = true;
16161
- return "half";
16162
- }
16163
- }).headers.has("Content-Type");
16164
- return duplexAccessed && !hasContentType;
16165
- });
16166
- var DEFAULT_CHUNK_SIZE = 64 * 1024;
16167
- var supportsResponseStream = isReadableStreamSupported && test(() => utils_default.isReadableStream(new Response("").body));
16168
- var resolvers = {
16169
- stream: supportsResponseStream && ((res) => res.body)
16170
- };
16171
- isFetchSupported && ((res) => {
16172
- ["text", "arrayBuffer", "blob", "formData", "stream"].forEach((type) => {
16173
- !resolvers[type] && (resolvers[type] = utils_default.isFunction(res[type]) ? (res2) => res2[type]() : (_, config2) => {
16174
- throw new AxiosError_default(`Response type '${type}' is not supported`, AxiosError_default.ERR_NOT_SUPPORT, config2);
16175
- });
16176
- });
16177
- })(new Response());
16178
- var getBodyLength = async (body) => {
16179
- if (body == null) {
16180
- return 0;
16181
- }
16182
- if (utils_default.isBlob(body)) {
16183
- return body.size;
16243
+ var factory = (env) => {
16244
+ env = utils_default.merge.call({
16245
+ skipUndefined: true
16246
+ }, globalFetchAPI, env);
16247
+ const { fetch: envFetch, Request, Response } = env;
16248
+ const isFetchSupported = envFetch ? isFunction2(envFetch) : typeof fetch === "function";
16249
+ const isRequestSupported = isFunction2(Request);
16250
+ const isResponseSupported = isFunction2(Response);
16251
+ if (!isFetchSupported) {
16252
+ return false;
16184
16253
  }
16185
- if (utils_default.isSpecCompliantForm(body)) {
16186
- const _request = new Request(platform_default.origin, {
16254
+ const isReadableStreamSupported = isFetchSupported && isFunction2(ReadableStream2);
16255
+ const encodeText = isFetchSupported && (typeof TextEncoder2 === "function" ? ((encoder) => (str) => encoder.encode(str))(new TextEncoder2()) : async (str) => new Uint8Array(await new Request(str).arrayBuffer()));
16256
+ const supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(() => {
16257
+ let duplexAccessed = false;
16258
+ const hasContentType = new Request(platform_default.origin, {
16259
+ body: new ReadableStream2(),
16187
16260
  method: "POST",
16188
- body
16189
- });
16190
- return (await _request.arrayBuffer()).byteLength;
16191
- }
16192
- if (utils_default.isArrayBufferView(body) || utils_default.isArrayBuffer(body)) {
16193
- return body.byteLength;
16194
- }
16195
- if (utils_default.isURLSearchParams(body)) {
16196
- body = body + "";
16197
- }
16198
- if (utils_default.isString(body)) {
16199
- return (await encodeText(body)).byteLength;
16200
- }
16201
- };
16202
- var resolveBodyLength = async (headers, body) => {
16203
- const length = utils_default.toFiniteNumber(headers.getContentLength());
16204
- return length == null ? getBodyLength(body) : length;
16205
- };
16206
- var fetch_default = isFetchSupported && (async (config2) => {
16207
- let {
16208
- url: url2,
16209
- method,
16210
- data,
16211
- signal,
16212
- cancelToken,
16213
- timeout,
16214
- onDownloadProgress,
16215
- onUploadProgress,
16216
- responseType,
16217
- headers,
16218
- withCredentials = "same-origin",
16219
- fetchOptions
16220
- } = resolveConfig_default(config2);
16221
- responseType = responseType ? (responseType + "").toLowerCase() : "text";
16222
- let composedSignal = composeSignals_default([signal, cancelToken && cancelToken.toAbortSignal()], timeout);
16223
- let request;
16224
- const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => {
16225
- composedSignal.unsubscribe();
16261
+ get duplex() {
16262
+ duplexAccessed = true;
16263
+ return "half";
16264
+ }
16265
+ }).headers.has("Content-Type");
16266
+ return duplexAccessed && !hasContentType;
16226
16267
  });
16227
- let requestContentLength;
16228
- try {
16229
- if (onUploadProgress && supportsRequestStream && method !== "get" && method !== "head" && (requestContentLength = await resolveBodyLength(headers, data)) !== 0) {
16230
- let _request = new Request(url2, {
16231
- method: "POST",
16232
- body: data,
16233
- duplex: "half"
16268
+ const supportsResponseStream = isResponseSupported && isReadableStreamSupported && test(() => utils_default.isReadableStream(new Response("").body));
16269
+ const resolvers = {
16270
+ stream: supportsResponseStream && ((res) => res.body)
16271
+ };
16272
+ isFetchSupported && (() => {
16273
+ ["text", "arrayBuffer", "blob", "formData", "stream"].forEach((type) => {
16274
+ !resolvers[type] && (resolvers[type] = (res, config2) => {
16275
+ let method = res && res[type];
16276
+ if (method) {
16277
+ return method.call(res);
16278
+ }
16279
+ throw new AxiosError_default(`Response type '${type}' is not supported`, AxiosError_default.ERR_NOT_SUPPORT, config2);
16234
16280
  });
16235
- let contentTypeHeader;
16236
- if (utils_default.isFormData(data) && (contentTypeHeader = _request.headers.get("content-type"))) {
16237
- headers.setContentType(contentTypeHeader);
16238
- }
16239
- if (_request.body) {
16240
- const [onProgress, flush] = progressEventDecorator(
16241
- requestContentLength,
16242
- progressEventReducer(asyncDecorator(onUploadProgress))
16243
- );
16244
- data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush);
16245
- }
16281
+ });
16282
+ })();
16283
+ const getBodyLength = async (body) => {
16284
+ if (body == null) {
16285
+ return 0;
16246
16286
  }
16247
- if (!utils_default.isString(withCredentials)) {
16248
- withCredentials = withCredentials ? "include" : "omit";
16287
+ if (utils_default.isBlob(body)) {
16288
+ return body.size;
16249
16289
  }
16250
- const isCredentialsSupported = "credentials" in Request.prototype;
16251
- request = new Request(url2, {
16252
- ...fetchOptions,
16253
- signal: composedSignal,
16254
- method: method.toUpperCase(),
16255
- headers: headers.normalize().toJSON(),
16256
- body: data,
16257
- duplex: "half",
16258
- credentials: isCredentialsSupported ? withCredentials : void 0
16259
- });
16260
- let response = await fetch(request, fetchOptions);
16261
- const isStreamResponse = supportsResponseStream && (responseType === "stream" || responseType === "response");
16262
- if (supportsResponseStream && (onDownloadProgress || isStreamResponse && unsubscribe)) {
16263
- const options = {};
16264
- ["status", "statusText", "headers"].forEach((prop) => {
16265
- options[prop] = response[prop];
16290
+ if (utils_default.isSpecCompliantForm(body)) {
16291
+ const _request = new Request(platform_default.origin, {
16292
+ method: "POST",
16293
+ body
16266
16294
  });
16267
- const responseContentLength = utils_default.toFiniteNumber(response.headers.get("content-length"));
16268
- const [onProgress, flush] = onDownloadProgress && progressEventDecorator(
16269
- responseContentLength,
16270
- progressEventReducer(asyncDecorator(onDownloadProgress), true)
16271
- ) || [];
16272
- response = new Response(
16273
- trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => {
16274
- flush && flush();
16275
- unsubscribe && unsubscribe();
16276
- }),
16277
- options
16278
- );
16295
+ return (await _request.arrayBuffer()).byteLength;
16279
16296
  }
16280
- responseType = responseType || "text";
16281
- let responseData = await resolvers[utils_default.findKey(resolvers, responseType) || "text"](response, config2);
16282
- !isStreamResponse && unsubscribe && unsubscribe();
16283
- return await new Promise((resolve, reject) => {
16284
- settle(resolve, reject, {
16285
- data: responseData,
16286
- headers: AxiosHeaders_default.from(response.headers),
16287
- status: response.status,
16288
- statusText: response.statusText,
16289
- config: config2,
16290
- request
16291
- });
16297
+ if (utils_default.isArrayBufferView(body) || utils_default.isArrayBuffer(body)) {
16298
+ return body.byteLength;
16299
+ }
16300
+ if (utils_default.isURLSearchParams(body)) {
16301
+ body = body + "";
16302
+ }
16303
+ if (utils_default.isString(body)) {
16304
+ return (await encodeText(body)).byteLength;
16305
+ }
16306
+ };
16307
+ const resolveBodyLength = async (headers, body) => {
16308
+ const length = utils_default.toFiniteNumber(headers.getContentLength());
16309
+ return length == null ? getBodyLength(body) : length;
16310
+ };
16311
+ return async (config2) => {
16312
+ let {
16313
+ url: url2,
16314
+ method,
16315
+ data,
16316
+ signal,
16317
+ cancelToken,
16318
+ timeout,
16319
+ onDownloadProgress,
16320
+ onUploadProgress,
16321
+ responseType,
16322
+ headers,
16323
+ withCredentials = "same-origin",
16324
+ fetchOptions
16325
+ } = resolveConfig_default(config2);
16326
+ let _fetch = envFetch || fetch;
16327
+ responseType = responseType ? (responseType + "").toLowerCase() : "text";
16328
+ let composedSignal = composeSignals_default([signal, cancelToken && cancelToken.toAbortSignal()], timeout);
16329
+ let request = null;
16330
+ const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => {
16331
+ composedSignal.unsubscribe();
16292
16332
  });
16293
- } catch (err) {
16294
- unsubscribe && unsubscribe();
16295
- if (err && err.name === "TypeError" && /Load failed|fetch/i.test(err.message)) {
16296
- throw Object.assign(
16297
- new AxiosError_default("Network Error", AxiosError_default.ERR_NETWORK, config2, request),
16298
- {
16299
- cause: err.cause || err
16333
+ let requestContentLength;
16334
+ try {
16335
+ if (onUploadProgress && supportsRequestStream && method !== "get" && method !== "head" && (requestContentLength = await resolveBodyLength(headers, data)) !== 0) {
16336
+ let _request = new Request(url2, {
16337
+ method: "POST",
16338
+ body: data,
16339
+ duplex: "half"
16340
+ });
16341
+ let contentTypeHeader;
16342
+ if (utils_default.isFormData(data) && (contentTypeHeader = _request.headers.get("content-type"))) {
16343
+ headers.setContentType(contentTypeHeader);
16300
16344
  }
16301
- );
16345
+ if (_request.body) {
16346
+ const [onProgress, flush] = progressEventDecorator(
16347
+ requestContentLength,
16348
+ progressEventReducer(asyncDecorator(onUploadProgress))
16349
+ );
16350
+ data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush);
16351
+ }
16352
+ }
16353
+ if (!utils_default.isString(withCredentials)) {
16354
+ withCredentials = withCredentials ? "include" : "omit";
16355
+ }
16356
+ const isCredentialsSupported = isRequestSupported && "credentials" in Request.prototype;
16357
+ const resolvedOptions = {
16358
+ ...fetchOptions,
16359
+ signal: composedSignal,
16360
+ method: method.toUpperCase(),
16361
+ headers: headers.normalize().toJSON(),
16362
+ body: data,
16363
+ duplex: "half",
16364
+ credentials: isCredentialsSupported ? withCredentials : void 0
16365
+ };
16366
+ request = isRequestSupported && new Request(url2, resolvedOptions);
16367
+ let response = await (isRequestSupported ? _fetch(request, fetchOptions) : _fetch(url2, resolvedOptions));
16368
+ const isStreamResponse = supportsResponseStream && (responseType === "stream" || responseType === "response");
16369
+ if (supportsResponseStream && (onDownloadProgress || isStreamResponse && unsubscribe)) {
16370
+ const options = {};
16371
+ ["status", "statusText", "headers"].forEach((prop) => {
16372
+ options[prop] = response[prop];
16373
+ });
16374
+ const responseContentLength = utils_default.toFiniteNumber(response.headers.get("content-length"));
16375
+ const [onProgress, flush] = onDownloadProgress && progressEventDecorator(
16376
+ responseContentLength,
16377
+ progressEventReducer(asyncDecorator(onDownloadProgress), true)
16378
+ ) || [];
16379
+ response = new Response(
16380
+ trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => {
16381
+ flush && flush();
16382
+ unsubscribe && unsubscribe();
16383
+ }),
16384
+ options
16385
+ );
16386
+ }
16387
+ responseType = responseType || "text";
16388
+ let responseData = await resolvers[utils_default.findKey(resolvers, responseType) || "text"](response, config2);
16389
+ !isStreamResponse && unsubscribe && unsubscribe();
16390
+ return await new Promise((resolve, reject) => {
16391
+ settle(resolve, reject, {
16392
+ data: responseData,
16393
+ headers: AxiosHeaders_default.from(response.headers),
16394
+ status: response.status,
16395
+ statusText: response.statusText,
16396
+ config: config2,
16397
+ request
16398
+ });
16399
+ });
16400
+ } catch (err) {
16401
+ unsubscribe && unsubscribe();
16402
+ if (err && err.name === "TypeError" && /Load failed|fetch/i.test(err.message)) {
16403
+ throw Object.assign(
16404
+ new AxiosError_default("Network Error", AxiosError_default.ERR_NETWORK, config2, request),
16405
+ {
16406
+ cause: err.cause || err
16407
+ }
16408
+ );
16409
+ }
16410
+ throw AxiosError_default.from(err, err && err.code, config2, request);
16302
16411
  }
16303
- throw AxiosError_default.from(err, err && err.code, config2, request);
16304
- }
16305
- });
16412
+ };
16413
+ };
16414
+ var seedCache = /* @__PURE__ */ new Map();
16415
+ var getFetch = (config2) => {
16416
+ let env = config2 ? config2.env : {};
16417
+ const { fetch: fetch2, Request, Response } = env;
16418
+ const seeds = [
16419
+ Request,
16420
+ Response,
16421
+ fetch2
16422
+ ];
16423
+ let len = seeds.length, i = len, seed, target, map = seedCache;
16424
+ while (i--) {
16425
+ seed = seeds[i];
16426
+ target = map.get(seed);
16427
+ target === void 0 && map.set(seed, target = i ? /* @__PURE__ */ new Map() : factory(env));
16428
+ map = target;
16429
+ }
16430
+ return target;
16431
+ };
16432
+ var adapter = getFetch();
16306
16433
 
16307
16434
  // node_modules/axios/lib/adapters/adapters.js
16308
16435
  var knownAdapters = {
16309
16436
  http: http_default,
16310
16437
  xhr: xhr_default,
16311
- fetch: fetch_default
16438
+ fetch: {
16439
+ get: getFetch
16440
+ }
16312
16441
  };
16313
16442
  utils_default.forEach(knownAdapters, (fn, value) => {
16314
16443
  if (fn) {
@@ -16320,30 +16449,30 @@ utils_default.forEach(knownAdapters, (fn, value) => {
16320
16449
  }
16321
16450
  });
16322
16451
  var renderReason = (reason) => `- ${reason}`;
16323
- var isResolvedHandle = (adapter) => utils_default.isFunction(adapter) || adapter === null || adapter === false;
16452
+ var isResolvedHandle = (adapter2) => utils_default.isFunction(adapter2) || adapter2 === null || adapter2 === false;
16324
16453
  var adapters_default = {
16325
- getAdapter: (adapters) => {
16454
+ getAdapter: (adapters, config2) => {
16326
16455
  adapters = utils_default.isArray(adapters) ? adapters : [adapters];
16327
16456
  const { length } = adapters;
16328
16457
  let nameOrAdapter;
16329
- let adapter;
16458
+ let adapter2;
16330
16459
  const rejectedReasons = {};
16331
16460
  for (let i = 0; i < length; i++) {
16332
16461
  nameOrAdapter = adapters[i];
16333
16462
  let id;
16334
- adapter = nameOrAdapter;
16463
+ adapter2 = nameOrAdapter;
16335
16464
  if (!isResolvedHandle(nameOrAdapter)) {
16336
- adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];
16337
- if (adapter === void 0) {
16465
+ adapter2 = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];
16466
+ if (adapter2 === void 0) {
16338
16467
  throw new AxiosError_default(`Unknown adapter '${id}'`);
16339
16468
  }
16340
16469
  }
16341
- if (adapter) {
16470
+ if (adapter2 && (utils_default.isFunction(adapter2) || (adapter2 = adapter2.get(config2)))) {
16342
16471
  break;
16343
16472
  }
16344
- rejectedReasons[id || "#" + i] = adapter;
16473
+ rejectedReasons[id || "#" + i] = adapter2;
16345
16474
  }
16346
- if (!adapter) {
16475
+ if (!adapter2) {
16347
16476
  const reasons = Object.entries(rejectedReasons).map(
16348
16477
  ([id, state]) => `adapter ${id} ` + (state === false ? "is not supported by the environment" : "is not available in the build")
16349
16478
  );
@@ -16353,7 +16482,7 @@ var adapters_default = {
16353
16482
  "ERR_NOT_SUPPORT"
16354
16483
  );
16355
16484
  }
16356
- return adapter;
16485
+ return adapter2;
16357
16486
  },
16358
16487
  adapters: knownAdapters
16359
16488
  };
@@ -16377,8 +16506,8 @@ function dispatchRequest(config2) {
16377
16506
  if (["post", "put", "patch"].indexOf(config2.method) !== -1) {
16378
16507
  config2.headers.setContentType("application/x-www-form-urlencoded", false);
16379
16508
  }
16380
- const adapter = adapters_default.getAdapter(config2.adapter || defaults_default.adapter);
16381
- return adapter(config2).then(function onAdapterResolution(response) {
16509
+ const adapter2 = adapters_default.getAdapter(config2.adapter || defaults_default.adapter, config2);
16510
+ return adapter2(config2).then(function onAdapterResolution(response) {
16382
16511
  throwIfCancellationRequested(config2);
16383
16512
  response.data = transformData.call(
16384
16513
  config2,
@@ -16584,7 +16713,6 @@ var Axios = class {
16584
16713
  }
16585
16714
  len = requestInterceptorChain.length;
16586
16715
  let newConfig = config2;
16587
- i = 0;
16588
16716
  while (i < len) {
16589
16717
  const onFulfilled = requestInterceptorChain[i++];
16590
16718
  const onRejected = requestInterceptorChain[i++];
@@ -25650,7 +25778,7 @@ function useRegionService() {
25650
25778
  {
25651
25779
  id: region.toString(),
25652
25780
  name: "Admin",
25653
- type: "region",
25781
+ type: "basic-edu-ro",
25654
25782
  permissions: ["*"],
25655
25783
  status: "active",
25656
25784
  default: true
@@ -26202,7 +26330,7 @@ function useDivisionService() {
26202
26330
  {
26203
26331
  id: division.toString(),
26204
26332
  name: "Admin",
26205
- type: "division",
26333
+ type: "basic-edu-sdo",
26206
26334
  permissions: ["*"],
26207
26335
  status: "active",
26208
26336
  default: true
@@ -26306,11 +26434,8 @@ function useDivisionController() {
26306
26434
  return;
26307
26435
  }
26308
26436
  try {
26309
- const division = await _getById(id);
26310
- res.json({
26311
- message: "Successfully retrieved division.",
26312
- data: { division }
26313
- });
26437
+ const data = await _getById(id);
26438
+ res.json(data);
26314
26439
  return;
26315
26440
  } catch (error2) {
26316
26441
  next(error2);
@@ -26397,16 +26522,17 @@ var import_joi31 = __toESM(require("joi"));
26397
26522
  var import_mongodb37 = require("mongodb");
26398
26523
  var schemaSchool = import_joi31.default.object({
26399
26524
  _id: import_joi31.default.string().hex().optional().allow("", null),
26400
- id: import_joi31.default.string().required(),
26401
- name: import_joi31.default.string().required(),
26402
- country: import_joi31.default.string().required(),
26403
- address: import_joi31.default.string().required(),
26525
+ id: import_joi31.default.string().optional().allow("", null),
26526
+ name: import_joi31.default.string().optional().allow("", null),
26527
+ country: import_joi31.default.string().optional().allow("", null),
26528
+ address: import_joi31.default.string().optional().allow("", null),
26404
26529
  continuedAddress: import_joi31.default.string().optional().allow("", null),
26405
- city: import_joi31.default.string().required(),
26406
- province: import_joi31.default.string().required(),
26407
- postalCode: import_joi31.default.string().required(),
26408
- courses: import_joi31.default.array().items(import_joi31.default.string()).required(),
26409
- principalName: import_joi31.default.string().required(),
26530
+ city: import_joi31.default.string().required().allow("", null),
26531
+ province: import_joi31.default.string().required().allow("", null),
26532
+ district: import_joi31.default.string().optional().allow("", null),
26533
+ postalCode: import_joi31.default.string().required().allow("", null),
26534
+ courses: import_joi31.default.array().items(import_joi31.default.string()).optional(),
26535
+ principalName: import_joi31.default.string().required().allow("", null),
26410
26536
  principalEmail: import_joi31.default.string().email().optional().allow("", null),
26411
26537
  principalNumber: import_joi31.default.string().optional().allow("", null),
26412
26538
  region: import_joi31.default.string().hex().required(),
@@ -26416,7 +26542,7 @@ var schemaSchool = import_joi31.default.object({
26416
26542
  status: import_joi31.default.string().optional().allow(null, ""),
26417
26543
  createdAt: import_joi31.default.date().optional().allow("", null),
26418
26544
  updatedAt: import_joi31.default.date().optional().allow("", null),
26419
- createdBy: import_joi31.default.string().hex().required()
26545
+ createdBy: import_joi31.default.string().hex().optional().allow("", null)
26420
26546
  });
26421
26547
  function MSchool(value) {
26422
26548
  const { error } = schemaSchool.validate(value);
@@ -26455,15 +26581,15 @@ function MSchool(value) {
26455
26581
  _id: value._id ? value._id : new import_mongodb37.ObjectId(),
26456
26582
  id: value.id,
26457
26583
  name: value.name,
26458
- country: value.country,
26459
- address: value.address,
26584
+ country: value.country ?? "",
26585
+ address: value.address ?? "",
26460
26586
  continuedAddress: value.continuedAddress ?? "",
26461
- city: value.city,
26462
- province: value.province,
26463
- postalCode: value.postalCode,
26587
+ city: value.city ?? "",
26588
+ province: value.province ?? "",
26589
+ postalCode: value.postalCode ?? "",
26464
26590
  courses: value.courses || [],
26465
- principalName: value.principalName,
26466
- principalEmail: value.principalEmail,
26591
+ principalName: value.principalName ?? "",
26592
+ principalEmail: value.principalEmail ?? "",
26467
26593
  principalNumber: value.principalNumber ?? "",
26468
26594
  region: value.region,
26469
26595
  regionName: value.regionName ?? "",
@@ -26472,7 +26598,7 @@ function MSchool(value) {
26472
26598
  createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
26473
26599
  updatedAt: value.updatedAt ?? "",
26474
26600
  status: value.status ?? "pending",
26475
- createdBy: value.createdBy
26601
+ createdBy: value.createdBy ?? ""
26476
26602
  };
26477
26603
  }
26478
26604
 
@@ -26740,8 +26866,16 @@ function useSchoolRepo() {
26740
26866
 
26741
26867
  // src/services/school.service.ts
26742
26868
  var import_nodejs_utils64 = require("@eeplatform/nodejs-utils");
26869
+ var XLSX = __toESM(require("xlsx"));
26870
+ var Papa = __toESM(require("papaparse"));
26871
+ var BSON = __toESM(require("bson"));
26743
26872
  function useSchoolService() {
26744
- const { add, getPendingByCreatedBy, updateStatusById, getPendingById } = useSchoolRepo();
26873
+ const {
26874
+ add: addSchool,
26875
+ getPendingByCreatedBy,
26876
+ updateStatusById,
26877
+ getPendingById
26878
+ } = useSchoolRepo();
26745
26879
  const { addRole } = useRoleRepo();
26746
26880
  const { getUserById } = useUserRepo();
26747
26881
  const { add: addMember } = useMemberRepo();
@@ -26758,7 +26892,7 @@ function useSchoolService() {
26758
26892
  }
26759
26893
  try {
26760
26894
  value.status = "pending";
26761
- await add(value);
26895
+ await addSchool(value);
26762
26896
  return "Request to register school has been sent successfully. Please wait for approval.";
26763
26897
  } catch (error2) {
26764
26898
  throw error2;
@@ -26777,7 +26911,7 @@ function useSchoolService() {
26777
26911
  session.startTransaction();
26778
26912
  school.status = "approved";
26779
26913
  await updateStatusById(id, "active", session);
26780
- const roleType = "school";
26914
+ const roleType = "basic-edu-school";
26781
26915
  const roleName = "Admin";
26782
26916
  const roleId = await addRole(
26783
26917
  {
@@ -26822,9 +26956,245 @@ function useSchoolService() {
26822
26956
  await session.endSession();
26823
26957
  }
26824
26958
  }
26959
+ async function add(value) {
26960
+ const { error } = schemaSchool.validate(value);
26961
+ if (error) {
26962
+ throw new import_nodejs_utils64.BadRequestError(error.message);
26963
+ }
26964
+ const session = import_nodejs_utils64.useAtlas.getClient()?.startSession();
26965
+ if (!session) {
26966
+ throw new Error("Unable to start session for school service.");
26967
+ }
26968
+ try {
26969
+ session.startTransaction();
26970
+ value.status = "active";
26971
+ const schoolId = await addSchool(value, session);
26972
+ const roleType = "basic-edu-school";
26973
+ const roleName = "Admin";
26974
+ const roleId = await addRole(
26975
+ {
26976
+ id: schoolId.toString(),
26977
+ type: roleType,
26978
+ name: roleName,
26979
+ permissions: ["*"],
26980
+ status: "active",
26981
+ default: true
26982
+ },
26983
+ session
26984
+ );
26985
+ if (!value.createdBy) {
26986
+ throw new import_nodejs_utils64.BadRequestError("School must have a creator.");
26987
+ }
26988
+ const user = await getUserById(value.createdBy ?? "");
26989
+ if (!user) {
26990
+ throw new import_nodejs_utils64.BadRequestError("User not found for the school creator.");
26991
+ }
26992
+ await addMember(
26993
+ {
26994
+ org: schoolId.toString(),
26995
+ orgName: value.name,
26996
+ user: value.createdBy.toString(),
26997
+ name: `${user.firstName} ${user.lastName}`,
26998
+ role: roleId.toString(),
26999
+ roleName,
27000
+ type: roleType
27001
+ },
27002
+ session
27003
+ );
27004
+ await session.commitTransaction();
27005
+ return "School has been added and activated successfully.";
27006
+ } catch (error2) {
27007
+ import_nodejs_utils64.logger.log({
27008
+ level: "error",
27009
+ message: `Error adding school: ${error2.message}`
27010
+ });
27011
+ await session.abortTransaction();
27012
+ throw error2;
27013
+ } finally {
27014
+ await session.endSession();
27015
+ }
27016
+ }
27017
+ async function addBulk(file, region, division) {
27018
+ const MAX_SIZE = 16 * 1024 * 1024;
27019
+ if (file.size > MAX_SIZE) {
27020
+ throw new import_nodejs_utils64.BadRequestError(
27021
+ "File size exceeds 16MB limit. Please use a smaller file to ensure transaction compatibility."
27022
+ );
27023
+ }
27024
+ let schools = [];
27025
+ const validatedSchools = [];
27026
+ const totalSize = validatedSchools.reduce(
27027
+ (sum, school) => sum + BSON.calculateObjectSize(school),
27028
+ 0
27029
+ );
27030
+ try {
27031
+ if (file.mimetype.includes("sheet") || file.originalname.endsWith(".xlsx") || file.originalname.endsWith(".xls")) {
27032
+ const workbook = XLSX.read(file.buffer);
27033
+ const sheetName = workbook.SheetNames[0];
27034
+ const worksheet = workbook.Sheets[sheetName];
27035
+ schools = XLSX.utils.sheet_to_json(worksheet);
27036
+ } else if (file.mimetype.includes("csv") || file.originalname.endsWith(".csv")) {
27037
+ const csvText = file.buffer.toString("utf8");
27038
+ const parseResult = Papa.parse(csvText, {
27039
+ header: true,
27040
+ skipEmptyLines: true,
27041
+ transformHeader: (header) => header.trim()
27042
+ });
27043
+ if (parseResult.errors.length > 0) {
27044
+ throw new import_nodejs_utils64.BadRequestError(
27045
+ `CSV parsing error: ${parseResult.errors[0].message}`
27046
+ );
27047
+ }
27048
+ schools = parseResult.data;
27049
+ } else {
27050
+ throw new import_nodejs_utils64.BadRequestError(
27051
+ "Unsupported file type. Please upload an Excel (.xlsx, .xls) or CSV (.csv) file."
27052
+ );
27053
+ }
27054
+ if (!schools || schools.length === 0) {
27055
+ throw new import_nodejs_utils64.BadRequestError("No data found in the uploaded file.");
27056
+ }
27057
+ const errors = [];
27058
+ for (let i = 0; i < schools.length; i++) {
27059
+ const schoolData = schools[i];
27060
+ const rowNumber = i + 1;
27061
+ try {
27062
+ const schoolName = schoolData.schoolName || schoolData.name || "";
27063
+ const schoolId = schoolData.schoolId || schoolData.id || "";
27064
+ const district = schoolData.district || "";
27065
+ if (!schoolName.trim()) {
27066
+ errors.push(`Row ${rowNumber}: School name is required`);
27067
+ continue;
27068
+ }
27069
+ if (!schoolId.trim()) {
27070
+ errors.push(`Row ${rowNumber}: School ID is required`);
27071
+ continue;
27072
+ }
27073
+ if (!district.trim()) {
27074
+ errors.push(`Row ${rowNumber}: District is required`);
27075
+ continue;
27076
+ }
27077
+ const school = {
27078
+ id: schoolId.trim(),
27079
+ name: schoolName.trim(),
27080
+ country: "Philippines",
27081
+ // Default country
27082
+ address: district.trim(),
27083
+ // Use district as address
27084
+ continuedAddress: "",
27085
+ city: district.trim(),
27086
+ // Use district as city
27087
+ province: "",
27088
+ // Will need to be set based on region/division
27089
+ postalCode: "",
27090
+ courses: [],
27091
+ // Empty array for courses
27092
+ principalName: "",
27093
+ principalEmail: "",
27094
+ principalNumber: "",
27095
+ region,
27096
+ regionName: "",
27097
+ // Will be populated from region lookup
27098
+ division,
27099
+ divisionName: "",
27100
+ // Will be populated from division lookup
27101
+ status: "active"
27102
+ };
27103
+ const { error } = schemaSchool.validate(school);
27104
+ if (error) {
27105
+ errors.push(`Row ${rowNumber}: ${error.message}`);
27106
+ continue;
27107
+ }
27108
+ validatedSchools.push(school);
27109
+ } catch (error) {
27110
+ errors.push(
27111
+ `Row ${rowNumber}: ${error.message || "Invalid data format"}`
27112
+ );
27113
+ }
27114
+ }
27115
+ if (errors.length > 0) {
27116
+ throw new import_nodejs_utils64.BadRequestError(
27117
+ `Validation errors found:
27118
+ ${errors.slice(0, 10).join("\n")}${errors.length > 10 ? `
27119
+ ... and ${errors.length - 10} more errors` : ""}`
27120
+ );
27121
+ }
27122
+ if (validatedSchools.length === 0) {
27123
+ throw new import_nodejs_utils64.BadRequestError(
27124
+ "No valid school records found after validation."
27125
+ );
27126
+ }
27127
+ if (totalSize > MAX_SIZE) {
27128
+ throw new import_nodejs_utils64.BadRequestError(
27129
+ `Data payload (${Math.round(
27130
+ totalSize / 1024 / 1024
27131
+ )}MB) exceeds MongoDB transaction limit of 16MB. Please reduce the number of records or split into smaller files.`
27132
+ );
27133
+ }
27134
+ } catch (error) {
27135
+ if (error instanceof import_nodejs_utils64.BadRequestError) {
27136
+ throw error;
27137
+ }
27138
+ throw new import_nodejs_utils64.BadRequestError(`File processing error: ${error.message}`);
27139
+ }
27140
+ const session = import_nodejs_utils64.useAtlas.getClient()?.startSession();
27141
+ if (!session) {
27142
+ throw new Error("Unable to start session for bulk school upload.");
27143
+ }
27144
+ try {
27145
+ session.startTransaction();
27146
+ const results = {
27147
+ successful: 0,
27148
+ failed: 0,
27149
+ errors: []
27150
+ };
27151
+ for (const school of validatedSchools) {
27152
+ try {
27153
+ const schoolId = await addSchool(school, session);
27154
+ await addRole(
27155
+ {
27156
+ id: schoolId.toString(),
27157
+ type: "basic-edu-school",
27158
+ name: "Admin",
27159
+ permissions: ["*"],
27160
+ status: "active",
27161
+ default: true
27162
+ },
27163
+ session
27164
+ );
27165
+ results.successful++;
27166
+ } catch (error) {
27167
+ results.failed++;
27168
+ results.errors.push(`School "${school.name}": ${error.message}`);
27169
+ }
27170
+ }
27171
+ await session.commitTransaction();
27172
+ return {
27173
+ message: `Bulk upload completed. ${results.successful} schools added successfully.`,
27174
+ details: {
27175
+ successful: results.successful,
27176
+ failed: results.failed,
27177
+ total: validatedSchools.length,
27178
+ totalSizeMB: Math.round(totalSize / 1024 / 1024 * 100) / 100,
27179
+ errors: results.errors
27180
+ }
27181
+ };
27182
+ } catch (error) {
27183
+ import_nodejs_utils64.logger.log({
27184
+ level: "error",
27185
+ message: `Error in bulk school upload: ${error.message}`
27186
+ });
27187
+ await session.abortTransaction();
27188
+ throw error;
27189
+ } finally {
27190
+ await session.endSession();
27191
+ }
27192
+ }
26825
27193
  return {
26826
27194
  register,
26827
- approve
27195
+ approve,
27196
+ add,
27197
+ addBulk
26828
27198
  };
26829
27199
  }
26830
27200
 
@@ -26833,11 +27203,16 @@ var import_nodejs_utils65 = require("@eeplatform/nodejs-utils");
26833
27203
  var import_joi32 = __toESM(require("joi"));
26834
27204
  function useSchoolController() {
26835
27205
  const {
26836
- add: _add,
26837
27206
  getAll: _getAll,
26838
27207
  getPendingByCreatedBy: _getPendingByCreatedBy,
26839
27208
  updateStatusById: _updateStatusById
26840
27209
  } = useSchoolRepo();
27210
+ const {
27211
+ add: _addSchool,
27212
+ register: _registerSchool,
27213
+ approve,
27214
+ addBulk: _addBulk
27215
+ } = useSchoolService();
26841
27216
  async function add(req, res, next) {
26842
27217
  const payload = req.body;
26843
27218
  const { error } = schemaSchool.validate(payload);
@@ -26846,8 +27221,8 @@ function useSchoolController() {
26846
27221
  return;
26847
27222
  }
26848
27223
  try {
26849
- const school = await _add(payload);
26850
- res.status(201).json(school);
27224
+ const result = await _addSchool(payload);
27225
+ res.status(201).json({ message: result });
26851
27226
  return;
26852
27227
  } catch (error2) {
26853
27228
  next(error2);
@@ -26937,7 +27312,6 @@ function useSchoolController() {
26937
27312
  next(error2);
26938
27313
  }
26939
27314
  }
26940
- const { register: _registerSchool, approve } = useSchoolService();
26941
27315
  async function registerSchool(req, res, next) {
26942
27316
  const payload = req.body;
26943
27317
  const { error } = schemaSchool.validate(payload);
@@ -26972,13 +27346,38 @@ function useSchoolController() {
26972
27346
  next(error2);
26973
27347
  }
26974
27348
  }
27349
+ async function addBulk(req, res, next) {
27350
+ if (!req.file) {
27351
+ res.status(400).send("File is required!");
27352
+ return;
27353
+ }
27354
+ const { region, division } = req.body;
27355
+ const validation = import_joi32.default.object({
27356
+ region: import_joi32.default.string().hex().required(),
27357
+ division: import_joi32.default.string().hex().required()
27358
+ });
27359
+ const { error } = validation.validate({ region, division });
27360
+ if (error) {
27361
+ next(new import_nodejs_utils65.BadRequestError(`Validation error: ${error.message}`));
27362
+ return;
27363
+ }
27364
+ try {
27365
+ const result = await _addBulk(req.file, region, division);
27366
+ res.status(201).json(result);
27367
+ return;
27368
+ } catch (error2) {
27369
+ next(error2);
27370
+ return;
27371
+ }
27372
+ }
26975
27373
  return {
26976
27374
  add,
26977
27375
  getAll,
26978
27376
  getByCreatedBy,
26979
27377
  updateStatusById,
26980
27378
  registerSchool,
26981
- approveSchool
27379
+ approveSchool,
27380
+ addBulk
26982
27381
  };
26983
27382
  }
26984
27383
 
@@ -29166,6 +29565,942 @@ function useStockCardController() {
29166
29565
  getSuppliers
29167
29566
  };
29168
29567
  }
29568
+
29569
+ // src/services/github.service.ts
29570
+ var import_nodejs_utils80 = require("@eeplatform/nodejs-utils");
29571
+ var import_rest = require("@octokit/rest");
29572
+ var import_libsodium_wrappers = __toESM(require("libsodium-wrappers"));
29573
+ function useGitHubService() {
29574
+ function parseRepoUrl(url2) {
29575
+ const match = url2.match(/github\.com[:\/]([^\/]+)\/(.+)\.git$/);
29576
+ if (!match)
29577
+ throw new Error("Invalid GitHub repo URL");
29578
+ return { owner: match[1], repo: match[2] };
29579
+ }
29580
+ async function checkAdminPermission(owner, repo, octokit) {
29581
+ try {
29582
+ const { data: repoData } = await octokit.repos.get({ owner, repo });
29583
+ if (!repoData.permissions?.admin) {
29584
+ throw new import_nodejs_utils80.BadRequestError(
29585
+ "You do not have admin access to this repository."
29586
+ );
29587
+ }
29588
+ } catch (error) {
29589
+ if (error.status === 404) {
29590
+ throw new import_nodejs_utils80.BadRequestError(
29591
+ "Repository not found or you don't have access to it."
29592
+ );
29593
+ } else if (error.status === 401) {
29594
+ throw new import_nodejs_utils80.BadRequestError(
29595
+ "Invalid GitHub token or insufficient permissions."
29596
+ );
29597
+ } else if (error.message.includes("admin access")) {
29598
+ throw error;
29599
+ } else {
29600
+ throw new import_nodejs_utils80.BadRequestError(
29601
+ `Failed to check repository permissions: ${error.message}`
29602
+ );
29603
+ }
29604
+ }
29605
+ }
29606
+ async function setVariables(params) {
29607
+ try {
29608
+ const { githubToken, repoUrl, environment, type, keyValues } = params;
29609
+ const octokit = new import_rest.Octokit({ auth: githubToken });
29610
+ const { owner, repo } = parseRepoUrl(repoUrl);
29611
+ await checkAdminPermission(owner, repo, octokit);
29612
+ const lines = keyValues.split(/[\n\r\s\t]+/).map((l) => l.trim()).filter(Boolean);
29613
+ for (const line of lines) {
29614
+ const equalIndex = line.indexOf("=");
29615
+ if (equalIndex === -1)
29616
+ continue;
29617
+ const key = line.substring(0, equalIndex).trim();
29618
+ const value = line.substring(equalIndex + 1).trim();
29619
+ if (!key || !value)
29620
+ continue;
29621
+ if (type === "secret") {
29622
+ const { data: publicKeyRes } = await octokit.actions.getEnvironmentPublicKey({
29623
+ owner,
29624
+ repo,
29625
+ environment_name: environment
29626
+ });
29627
+ try {
29628
+ await import_libsodium_wrappers.default.ready;
29629
+ const sodium = import_libsodium_wrappers.default;
29630
+ const publicKeyBase64 = publicKeyRes.key;
29631
+ if (!publicKeyBase64) {
29632
+ throw new Error("No public key received from GitHub");
29633
+ }
29634
+ const keyBytes = new Uint8Array(
29635
+ Buffer.from(publicKeyBase64, "base64")
29636
+ );
29637
+ const valueBytes = new Uint8Array(Buffer.from(value, "utf8"));
29638
+ const encryptedBytes = sodium.crypto_box_seal(valueBytes, keyBytes);
29639
+ const encryptedValue = Buffer.from(encryptedBytes).toString("base64");
29640
+ await octokit.actions.createOrUpdateEnvironmentSecret({
29641
+ owner,
29642
+ repo,
29643
+ environment_name: environment,
29644
+ secret_name: key,
29645
+ encrypted_value: encryptedValue,
29646
+ key_id: publicKeyRes.key_id
29647
+ });
29648
+ } catch (encryptionError) {
29649
+ throw new import_nodejs_utils80.BadRequestError(
29650
+ `Failed to encrypt secret '${key}': ${encryptionError.message}`
29651
+ );
29652
+ }
29653
+ } else if (type === "env") {
29654
+ await octokit.actions.createEnvironmentVariable({
29655
+ owner,
29656
+ repo,
29657
+ environment_name: environment,
29658
+ name: key,
29659
+ value
29660
+ });
29661
+ }
29662
+ }
29663
+ return `Successfully set ${lines.length} ${type} variables/secrets in environment '${environment}'`;
29664
+ } catch (error) {
29665
+ if (error instanceof import_nodejs_utils80.AppError)
29666
+ throw error;
29667
+ if (error.status === 422) {
29668
+ throw new import_nodejs_utils80.BadRequestError(
29669
+ `GitHub API validation error: ${error.message}`
29670
+ );
29671
+ } else if (error.status === 404) {
29672
+ throw new import_nodejs_utils80.BadRequestError("Environment or repository not found.");
29673
+ } else if (error.status === 403) {
29674
+ throw new import_nodejs_utils80.BadRequestError(
29675
+ "Forbidden: Insufficient permissions or rate limit exceeded."
29676
+ );
29677
+ } else if (error.message.includes("admin access") || error.message.includes("permissions")) {
29678
+ throw error;
29679
+ } else {
29680
+ throw new import_nodejs_utils80.BadRequestError(
29681
+ `Failed to set GitHub variables: ${error.message}`
29682
+ );
29683
+ }
29684
+ }
29685
+ }
29686
+ return {
29687
+ setVariables
29688
+ };
29689
+ }
29690
+
29691
+ // src/controllers/util.controller.ts
29692
+ var import_joi40 = __toESM(require("joi"));
29693
+ var import_nodejs_utils81 = require("@eeplatform/nodejs-utils");
29694
+ function useUtilController() {
29695
+ async function healthCheck(req, res, next) {
29696
+ try {
29697
+ res.status(200).json({
29698
+ success: true,
29699
+ message: "Util service is healthy",
29700
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
29701
+ data: {
29702
+ availableEndpoints: [
29703
+ "POST /github/variables - Set GitHub environment variables or secrets"
29704
+ ],
29705
+ keyValueFormat: "KEY=value pairs separated by newlines, spaces, or tabs"
29706
+ }
29707
+ });
29708
+ } catch (error) {
29709
+ import_nodejs_utils81.logger.error("Health check failed", { error: error.message });
29710
+ next(new import_nodejs_utils81.InternalServerError("Health check failed"));
29711
+ }
29712
+ }
29713
+ async function setGitHubVariables(req, res, next) {
29714
+ try {
29715
+ const { githubToken, repoUrl, environment, type, keyValues } = req.body;
29716
+ const validation = import_joi40.default.object({
29717
+ githubToken: import_joi40.default.string().required().messages({
29718
+ "string.empty": "GitHub token is required",
29719
+ "any.required": "GitHub token is required"
29720
+ }),
29721
+ repoUrl: import_joi40.default.string().uri().required().messages({
29722
+ "string.empty": "Repository URL is required",
29723
+ "string.uri": "Repository URL must be a valid URL",
29724
+ "any.required": "Repository URL is required"
29725
+ }),
29726
+ environment: import_joi40.default.string().required().messages({
29727
+ "string.empty": "Environment name is required",
29728
+ "any.required": "Environment name is required"
29729
+ }),
29730
+ type: import_joi40.default.string().valid("env", "secret").required().messages({
29731
+ "any.only": 'Type must be either "env" or "secret"',
29732
+ "any.required": "Type is required"
29733
+ }),
29734
+ keyValues: import_joi40.default.string().required().messages({
29735
+ "string.empty": "Key-value pairs are required",
29736
+ "any.required": "Key-value pairs are required"
29737
+ })
29738
+ });
29739
+ const { error } = validation.validate({
29740
+ githubToken,
29741
+ repoUrl,
29742
+ environment,
29743
+ type,
29744
+ keyValues
29745
+ });
29746
+ if (error) {
29747
+ next(new import_nodejs_utils81.BadRequestError(error.message));
29748
+ return;
29749
+ }
29750
+ const repoUrlPattern = /github\.com[:\/]([^\/]+)\/(.+)\.git$/;
29751
+ if (!repoUrlPattern.test(repoUrl)) {
29752
+ next(
29753
+ new import_nodejs_utils81.BadRequestError(
29754
+ "Invalid GitHub repository URL format. Expected format: https://github.com/owner/repo.git"
29755
+ )
29756
+ );
29757
+ return;
29758
+ }
29759
+ const lines = keyValues.split(/[\n\r\s\t]+/).map((l) => l.trim()).filter(Boolean);
29760
+ const invalidLines = lines.filter(
29761
+ (line) => !line.includes("=") || line.indexOf("=") === -1
29762
+ );
29763
+ if (invalidLines.length > 0) {
29764
+ next(
29765
+ new import_nodejs_utils81.BadRequestError(
29766
+ "Invalid key-value format. Each pair should be in format: KEY=value. Pairs can be separated by newlines, spaces, or tabs."
29767
+ )
29768
+ );
29769
+ return;
29770
+ }
29771
+ const githubService = useGitHubService();
29772
+ const result = await githubService.setVariables({
29773
+ githubToken,
29774
+ repoUrl,
29775
+ environment,
29776
+ type,
29777
+ keyValues
29778
+ });
29779
+ import_nodejs_utils81.logger.info(`GitHub variables set successfully`, {
29780
+ repoUrl,
29781
+ environment,
29782
+ type,
29783
+ count: lines.length
29784
+ });
29785
+ res.status(200).json({
29786
+ success: true,
29787
+ message: result,
29788
+ data: {
29789
+ repoUrl,
29790
+ environment,
29791
+ type,
29792
+ variablesSet: lines.length
29793
+ }
29794
+ });
29795
+ } catch (error) {
29796
+ import_nodejs_utils81.logger.error("Failed to set GitHub variables", {
29797
+ error: error.message,
29798
+ stack: error.stack
29799
+ });
29800
+ if (error instanceof import_nodejs_utils81.AppError) {
29801
+ next(error);
29802
+ } else {
29803
+ next(
29804
+ new import_nodejs_utils81.InternalServerError(
29805
+ `Failed to set GitHub variables: ${error.message}`
29806
+ )
29807
+ );
29808
+ }
29809
+ }
29810
+ }
29811
+ return {
29812
+ healthCheck,
29813
+ setGitHubVariables
29814
+ };
29815
+ }
29816
+
29817
+ // src/models/plantilla.model.ts
29818
+ var import_nodejs_utils82 = require("@eeplatform/nodejs-utils");
29819
+ var import_joi41 = __toESM(require("joi"));
29820
+ var import_mongodb46 = require("mongodb");
29821
+ var schemaPlantilla = import_joi41.default.object({
29822
+ _id: import_joi41.default.string().hex().optional().allow(null, ""),
29823
+ itemNumber: import_joi41.default.string().required(),
29824
+ positionTitle: import_joi41.default.string().required(),
29825
+ positionCategory: import_joi41.default.string().required(),
29826
+ region: import_joi41.default.string().hex().optional().allow(null, ""),
29827
+ regionName: import_joi41.default.string().optional().allow(null, ""),
29828
+ division: import_joi41.default.string().hex().optional().allow(null, ""),
29829
+ divisionName: import_joi41.default.string().optional().allow(null, ""),
29830
+ salaryGrade: import_joi41.default.number().required(),
29831
+ step: import_joi41.default.number().optional().allow(null, 0),
29832
+ incumbent: import_joi41.default.string().optional().allow(null, ""),
29833
+ annualSalary: import_joi41.default.number().optional().allow(null, 0),
29834
+ monthlySalary: import_joi41.default.number().optional().allow(null, 0),
29835
+ status: import_joi41.default.string().required(),
29836
+ employee: import_joi41.default.string().hex().optional().allow(null, ""),
29837
+ createdAt: import_joi41.default.date().iso().optional().allow(null, ""),
29838
+ updatedAt: import_joi41.default.date().iso().optional().allow(null, ""),
29839
+ deletedAt: import_joi41.default.date().iso().optional().allow(null, "")
29840
+ });
29841
+ function MPlantilla(data) {
29842
+ const { error } = schemaPlantilla.validate(data);
29843
+ if (error) {
29844
+ throw new import_nodejs_utils82.BadRequestError(error.message);
29845
+ }
29846
+ if (data._id && typeof data._id === "string") {
29847
+ try {
29848
+ data._id = new import_mongodb46.ObjectId(data._id);
29849
+ } catch (error2) {
29850
+ throw new import_nodejs_utils82.BadRequestError("Invalid _id.");
29851
+ }
29852
+ }
29853
+ return {
29854
+ _id: data._id,
29855
+ itemNumber: data.itemNumber ?? "",
29856
+ positionTitle: data.positionTitle ?? "",
29857
+ positionCategory: data.positionCategory ?? "",
29858
+ status: data.status ?? "active",
29859
+ salaryGrade: data.salaryGrade ?? 0,
29860
+ step: data.step ?? 0,
29861
+ monthlySalary: data.monthlySalary ?? 0,
29862
+ annualSalary: data.annualSalary ?? 0,
29863
+ region: data.region ?? "",
29864
+ regionName: data.regionName ?? "",
29865
+ division: data.division ?? "",
29866
+ divisionName: data.divisionName ?? "",
29867
+ incumbent: data.incumbent ?? "",
29868
+ createdAt: data.createdAt ? new Date(data.createdAt) : /* @__PURE__ */ new Date(),
29869
+ updatedAt: data.updatedAt ? new Date(data.updatedAt) : "",
29870
+ deletedAt: data.deletedAt ? new Date(data.deletedAt) : ""
29871
+ };
29872
+ }
29873
+
29874
+ // src/repositories/plantilla.repository.ts
29875
+ var import_nodejs_utils83 = require("@eeplatform/nodejs-utils");
29876
+ var import_mongodb47 = require("mongodb");
29877
+ function usePlantillaRepo() {
29878
+ const db = import_nodejs_utils83.useAtlas.getDb();
29879
+ if (!db) {
29880
+ throw new Error("Unable to connect to server.");
29881
+ }
29882
+ const namespace_collection = "plantillas";
29883
+ const collection = db.collection(namespace_collection);
29884
+ const { getCache, setCache, delNamespace } = (0, import_nodejs_utils83.useCache)(namespace_collection);
29885
+ async function createIndexes() {
29886
+ try {
29887
+ await collection.createIndexes([
29888
+ { key: { name: 1 }, unique: true, name: "unique_name_index" },
29889
+ { key: { school: 1 } },
29890
+ { key: { status: 1 } }
29891
+ ]);
29892
+ } catch (error) {
29893
+ throw new Error("Failed to create index on plantillas.");
29894
+ }
29895
+ }
29896
+ async function add(value, session, clearCache = true) {
29897
+ console.log(value);
29898
+ try {
29899
+ value = MPlantilla(value);
29900
+ const res = await collection.insertOne(value, { session });
29901
+ if (clearCache) {
29902
+ delCachedData();
29903
+ }
29904
+ return res.insertedId;
29905
+ } catch (error) {
29906
+ import_nodejs_utils83.logger.log({
29907
+ level: "error",
29908
+ message: error.message
29909
+ });
29910
+ if (error instanceof import_nodejs_utils83.AppError) {
29911
+ throw error;
29912
+ } else {
29913
+ const isDuplicated = error.message.includes("duplicate");
29914
+ if (isDuplicated) {
29915
+ throw new import_nodejs_utils83.BadRequestError("Plantilla already exists.");
29916
+ }
29917
+ throw new Error("Failed to create plantilla.");
29918
+ }
29919
+ }
29920
+ }
29921
+ async function updateById(_id, value, session) {
29922
+ try {
29923
+ _id = new import_mongodb47.ObjectId(_id);
29924
+ } catch (error) {
29925
+ throw new import_nodejs_utils83.BadRequestError("Invalid ID.");
29926
+ }
29927
+ value.updatedAt = /* @__PURE__ */ new Date();
29928
+ try {
29929
+ const res = await collection.updateOne(
29930
+ { _id },
29931
+ { $set: value },
29932
+ { session }
29933
+ );
29934
+ delCachedData();
29935
+ return res;
29936
+ } catch (error) {
29937
+ import_nodejs_utils83.logger.log({
29938
+ level: "error",
29939
+ message: error.message
29940
+ });
29941
+ if (error instanceof import_nodejs_utils83.AppError) {
29942
+ throw error;
29943
+ } else {
29944
+ throw new Error("Failed to update plantilla.");
29945
+ }
29946
+ }
29947
+ }
29948
+ async function getAll({
29949
+ search = "",
29950
+ page = 1,
29951
+ limit = 10,
29952
+ sort = {},
29953
+ org = "",
29954
+ status = "active"
29955
+ } = {}) {
29956
+ page = page > 0 ? page - 1 : 0;
29957
+ const query = {
29958
+ status
29959
+ };
29960
+ sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
29961
+ if (search) {
29962
+ query.$text = { $search: search };
29963
+ }
29964
+ if (org) {
29965
+ try {
29966
+ query.org = new import_mongodb47.ObjectId(org);
29967
+ } catch (error) {
29968
+ throw new import_nodejs_utils83.BadRequestError("Invalid org ID.");
29969
+ }
29970
+ }
29971
+ const cacheParams = {
29972
+ page,
29973
+ limit,
29974
+ sort: JSON.stringify(sort)
29975
+ };
29976
+ if (search)
29977
+ cacheParams.search = search;
29978
+ if (org)
29979
+ cacheParams.org = org;
29980
+ if (status !== "active")
29981
+ cacheParams.status = status;
29982
+ const cacheKey = (0, import_nodejs_utils83.makeCacheKey)(namespace_collection, cacheParams);
29983
+ import_nodejs_utils83.logger.log({
29984
+ level: "info",
29985
+ message: `Cache key for getAll plantillas: ${cacheKey}`
29986
+ });
29987
+ try {
29988
+ const cached = await getCache(cacheKey);
29989
+ if (cached) {
29990
+ import_nodejs_utils83.logger.log({
29991
+ level: "info",
29992
+ message: `Cache hit for getAll plantillas: ${cacheKey}`
29993
+ });
29994
+ return cached;
29995
+ }
29996
+ const items = await collection.aggregate([
29997
+ { $match: query },
29998
+ { $sort: sort },
29999
+ { $skip: page * limit },
30000
+ { $limit: limit }
30001
+ ]).toArray();
30002
+ const length = await collection.countDocuments(query);
30003
+ const data = (0, import_nodejs_utils83.paginate)(items, page, limit, length);
30004
+ setCache(cacheKey, data, 600).then(() => {
30005
+ import_nodejs_utils83.logger.log({
30006
+ level: "info",
30007
+ message: `Cache set for getAll plantillas: ${cacheKey}`
30008
+ });
30009
+ }).catch((err) => {
30010
+ import_nodejs_utils83.logger.log({
30011
+ level: "error",
30012
+ message: `Failed to set cache for getAll plantillas: ${err.message}`
30013
+ });
30014
+ });
30015
+ return data;
30016
+ } catch (error) {
30017
+ import_nodejs_utils83.logger.log({ level: "error", message: `${error}` });
30018
+ throw error;
30019
+ }
30020
+ }
30021
+ async function getById(_id) {
30022
+ try {
30023
+ _id = new import_mongodb47.ObjectId(_id);
30024
+ } catch (error) {
30025
+ throw new import_nodejs_utils83.BadRequestError("Invalid ID.");
30026
+ }
30027
+ const cacheKey = (0, import_nodejs_utils83.makeCacheKey)(namespace_collection, { _id: String(_id) });
30028
+ try {
30029
+ const cached = await getCache(cacheKey);
30030
+ if (cached) {
30031
+ import_nodejs_utils83.logger.log({
30032
+ level: "info",
30033
+ message: `Cache hit for getById plantilla: ${cacheKey}`
30034
+ });
30035
+ return cached;
30036
+ }
30037
+ const result = await collection.findOne({
30038
+ _id
30039
+ });
30040
+ setCache(cacheKey, result, 300).then(() => {
30041
+ import_nodejs_utils83.logger.log({
30042
+ level: "info",
30043
+ message: `Cache set for plantilla by id: ${cacheKey}`
30044
+ });
30045
+ }).catch((err) => {
30046
+ import_nodejs_utils83.logger.log({
30047
+ level: "error",
30048
+ message: `Failed to set cache for plantilla by id: ${err.message}`
30049
+ });
30050
+ });
30051
+ return result;
30052
+ } catch (error) {
30053
+ if (error instanceof import_nodejs_utils83.AppError) {
30054
+ throw error;
30055
+ } else {
30056
+ throw new import_nodejs_utils83.InternalServerError("Failed to get plantilla.");
30057
+ }
30058
+ }
30059
+ }
30060
+ async function deleteById(_id, session) {
30061
+ try {
30062
+ _id = new import_mongodb47.ObjectId(_id);
30063
+ } catch (error) {
30064
+ throw new import_nodejs_utils83.BadRequestError("Invalid ID.");
30065
+ }
30066
+ try {
30067
+ const res = await collection.updateOne(
30068
+ { _id },
30069
+ { $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } }
30070
+ );
30071
+ delCachedData();
30072
+ return res;
30073
+ } catch (error) {
30074
+ import_nodejs_utils83.logger.log({
30075
+ level: "error",
30076
+ message: error.message
30077
+ });
30078
+ if (error instanceof import_nodejs_utils83.AppError) {
30079
+ throw error;
30080
+ } else {
30081
+ throw new import_nodejs_utils83.InternalServerError("Failed to delete plantilla.");
30082
+ }
30083
+ }
30084
+ }
30085
+ function delCachedData() {
30086
+ delNamespace().then(() => {
30087
+ import_nodejs_utils83.logger.log({
30088
+ level: "info",
30089
+ message: `Cache namespace cleared for ${namespace_collection}`
30090
+ });
30091
+ }).catch((err) => {
30092
+ import_nodejs_utils83.logger.log({
30093
+ level: "error",
30094
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
30095
+ });
30096
+ });
30097
+ }
30098
+ return {
30099
+ createIndexes,
30100
+ add,
30101
+ getAll,
30102
+ getById,
30103
+ updateById,
30104
+ deleteById,
30105
+ delCachedData
30106
+ };
30107
+ }
30108
+
30109
+ // src/controllers/plantilla.controller.ts
30110
+ var import_nodejs_utils85 = require("@eeplatform/nodejs-utils");
30111
+ var import_joi42 = __toESM(require("joi"));
30112
+
30113
+ // src/services/plantilla.service.ts
30114
+ var import_nodejs_utils84 = require("@eeplatform/nodejs-utils");
30115
+ var XLSX2 = __toESM(require("xlsx"));
30116
+ var Papa2 = __toESM(require("papaparse"));
30117
+ function usePlantillaService() {
30118
+ const { add: addPlantilla, delCachedData } = usePlantillaRepo();
30119
+ async function addBulk(file, region, division) {
30120
+ import_nodejs_utils84.logger.log({
30121
+ level: "info",
30122
+ message: `Starting plantilla bulk upload. File: ${file.originalname}, Size: ${file.size} bytes`
30123
+ });
30124
+ const MAX_SIZE = 16 * 1024 * 1024;
30125
+ let plantillas = [];
30126
+ let totalSize = 0;
30127
+ let validatedPlantillas = [];
30128
+ if (!file.buffer) {
30129
+ throw new import_nodejs_utils84.BadRequestError("File buffer is empty or corrupted");
30130
+ }
30131
+ try {
30132
+ const fileExtension = file.originalname.split(".").pop()?.toLowerCase();
30133
+ if (fileExtension === "csv") {
30134
+ const csvData = file.buffer.toString("utf-8");
30135
+ totalSize = Buffer.byteLength(csvData, "utf8");
30136
+ const parseResult = Papa2.parse(csvData, {
30137
+ header: true,
30138
+ skipEmptyLines: true,
30139
+ transformHeader: (header) => {
30140
+ return header.toLowerCase().replace(/\s+/g, "").replace(/[^\w]/g, "");
30141
+ }
30142
+ });
30143
+ if (parseResult.errors.length > 0) {
30144
+ throw new import_nodejs_utils84.BadRequestError(
30145
+ `CSV parsing errors: ${parseResult.errors.map((e) => e.message).join(", ")}`
30146
+ );
30147
+ }
30148
+ plantillas = parseResult.data;
30149
+ } else if (fileExtension === "xlsx" || fileExtension === "xls") {
30150
+ totalSize = file.buffer.length;
30151
+ const workbook = XLSX2.read(file.buffer, { type: "buffer" });
30152
+ const sheetName = workbook.SheetNames[0];
30153
+ const worksheet = workbook.Sheets[sheetName];
30154
+ plantillas = XLSX2.utils.sheet_to_json(worksheet, {
30155
+ header: 1,
30156
+ defval: ""
30157
+ });
30158
+ if (plantillas.length === 0) {
30159
+ throw new import_nodejs_utils84.BadRequestError("Excel file is empty.");
30160
+ }
30161
+ const headers = plantillas[0];
30162
+ const normalizedHeaders = headers.map(
30163
+ (header) => header.toLowerCase().replace(/\s+/g, "").replace(/[^\w]/g, "")
30164
+ );
30165
+ plantillas = plantillas.slice(1).map((row) => {
30166
+ const obj = {};
30167
+ normalizedHeaders.forEach((header, index) => {
30168
+ obj[header] = row[index] || "";
30169
+ });
30170
+ return obj;
30171
+ });
30172
+ } else {
30173
+ throw new import_nodejs_utils84.BadRequestError(
30174
+ "Unsupported file type. Please upload an Excel (.xlsx, .xls) or CSV (.csv) file."
30175
+ );
30176
+ }
30177
+ if (!plantillas || plantillas.length === 0) {
30178
+ throw new import_nodejs_utils84.BadRequestError("No data found in the uploaded file.");
30179
+ }
30180
+ const errors = [];
30181
+ for (let i = 0; i < plantillas.length; i++) {
30182
+ const plantillaData = plantillas[i];
30183
+ const rowNumber = i + 1;
30184
+ try {
30185
+ const itemNumber = plantillaData.itemnumber || plantillaData.item_number || "";
30186
+ const positionTitle = plantillaData.positiontitle || plantillaData.position_title || plantillaData.title || "";
30187
+ const positionCategory = plantillaData.positioncategory || plantillaData.position_category || "";
30188
+ const status = plantillaData.status || "active";
30189
+ if (!itemNumber.trim()) {
30190
+ errors.push(`Row ${rowNumber}: Item Number is required`);
30191
+ continue;
30192
+ }
30193
+ if (!positionTitle.trim()) {
30194
+ errors.push(`Row ${rowNumber}: Position Title is required`);
30195
+ continue;
30196
+ }
30197
+ if (!positionCategory.trim()) {
30198
+ errors.push(`Row ${rowNumber}: Position Category is required`);
30199
+ continue;
30200
+ }
30201
+ const plantilla = {
30202
+ itemNumber: itemNumber.trim(),
30203
+ positionTitle: positionTitle.trim(),
30204
+ positionCategory: positionCategory.trim(),
30205
+ salaryGrade: parseInt(
30206
+ plantillaData.salarygrade || plantillaData.salary_grade || "1"
30207
+ ) || 1,
30208
+ step: parseInt(plantillaData.step || "1") || 1,
30209
+ status: status.trim() || "active"
30210
+ };
30211
+ if (region)
30212
+ plantilla.region = region;
30213
+ if (division)
30214
+ plantilla.division = division;
30215
+ if (plantillaData.regionname || plantillaData.region_name) {
30216
+ plantilla.regionName = plantillaData.regionname || plantillaData.region_name;
30217
+ }
30218
+ if (plantillaData.divisionname || plantillaData.division_name) {
30219
+ plantilla.divisionName = plantillaData.divisionname || plantillaData.division_name;
30220
+ }
30221
+ if (plantillaData.incumbent) {
30222
+ plantilla.incumbent = plantillaData.incumbent;
30223
+ }
30224
+ if (plantillaData.employee) {
30225
+ plantilla.employee = plantillaData.employee;
30226
+ }
30227
+ if (plantillaData.annualsalary || plantillaData.annual_salary) {
30228
+ plantilla.annualSalary = parseFloat(
30229
+ plantillaData.annualsalary || plantillaData.annual_salary
30230
+ ) || void 0;
30231
+ }
30232
+ if (plantillaData.monthlysalary || plantillaData.monthly_salary) {
30233
+ plantilla.monthlySalary = parseFloat(
30234
+ plantillaData.monthlysalary || plantillaData.monthly_salary
30235
+ ) || void 0;
30236
+ }
30237
+ if (!plantilla.itemNumber || !plantilla.positionTitle || !plantilla.positionCategory) {
30238
+ errors.push(`Row ${rowNumber}: Missing required fields`);
30239
+ continue;
30240
+ }
30241
+ validatedPlantillas.push(plantilla);
30242
+ } catch (error) {
30243
+ errors.push(
30244
+ `Row ${rowNumber}: ${error.message || "Invalid data format"}`
30245
+ );
30246
+ }
30247
+ }
30248
+ if (errors.length > 0) {
30249
+ throw new import_nodejs_utils84.BadRequestError(
30250
+ `Validation errors found:
30251
+ ${errors.slice(0, 10).join("\n")}${errors.length > 10 ? `
30252
+ ... and ${errors.length - 10} more errors` : ""}`
30253
+ );
30254
+ }
30255
+ if (validatedPlantillas.length === 0) {
30256
+ throw new import_nodejs_utils84.BadRequestError(
30257
+ "No valid plantilla records found after validation."
30258
+ );
30259
+ }
30260
+ if (totalSize > MAX_SIZE) {
30261
+ throw new import_nodejs_utils84.BadRequestError(
30262
+ `Data payload (${Math.round(
30263
+ totalSize / 1024 / 1024
30264
+ )}MB) exceeds MongoDB transaction limit of 16MB. Please reduce the number of records or split into smaller files.`
30265
+ );
30266
+ }
30267
+ } catch (error) {
30268
+ if (error instanceof import_nodejs_utils84.BadRequestError) {
30269
+ throw error;
30270
+ }
30271
+ throw new import_nodejs_utils84.BadRequestError(`File processing error: ${error.message}`);
30272
+ }
30273
+ const session = import_nodejs_utils84.useAtlas.getClient()?.startSession();
30274
+ if (!session) {
30275
+ throw new Error("Unable to start session for bulk plantilla upload.");
30276
+ }
30277
+ import_nodejs_utils84.logger.log({
30278
+ level: "info",
30279
+ message: `Starting bulk plantilla upload with ${validatedPlantillas.length} records`
30280
+ });
30281
+ try {
30282
+ session.startTransaction();
30283
+ const results = {
30284
+ successful: 0,
30285
+ failed: 0,
30286
+ errors: []
30287
+ };
30288
+ const promises = [];
30289
+ for (let i = 0; i < validatedPlantillas.length; i++) {
30290
+ const plantilla = validatedPlantillas[i];
30291
+ promises.push(addPlantilla(plantilla, session, false));
30292
+ }
30293
+ await Promise.all(promises);
30294
+ await delCachedData();
30295
+ await session.commitTransaction();
30296
+ return {
30297
+ message: `Bulk upload completed. ${results.successful} plantillas added successfully.`,
30298
+ details: {
30299
+ successful: results.successful,
30300
+ failed: results.failed,
30301
+ total: validatedPlantillas.length,
30302
+ totalSizeMB: Math.round(totalSize / 1024 / 1024 * 100) / 100,
30303
+ errors: results.errors
30304
+ }
30305
+ };
30306
+ } catch (error) {
30307
+ import_nodejs_utils84.logger.log({
30308
+ level: "error",
30309
+ message: `Error in bulk plantilla upload: ${error.message}`
30310
+ });
30311
+ await session.abortTransaction();
30312
+ throw error;
30313
+ } finally {
30314
+ await session.endSession();
30315
+ }
30316
+ }
30317
+ return {
30318
+ addBulk
30319
+ };
30320
+ }
30321
+
30322
+ // src/controllers/plantilla.controller.ts
30323
+ function usePlantillaController() {
30324
+ const {
30325
+ add: _addPlantilla,
30326
+ getAll: _getAllPlantillas,
30327
+ getById: _getPlantillaById,
30328
+ updateById: _updatePlantillaById,
30329
+ deleteById: _deletePlantillaById
30330
+ } = usePlantillaRepo();
30331
+ const { addBulk: _addBulk } = usePlantillaService();
30332
+ async function createPlantilla(req, res, next) {
30333
+ const value = req.body;
30334
+ const validation = import_joi42.default.object({
30335
+ itemNumber: import_joi42.default.string().required(),
30336
+ positionTitle: import_joi42.default.string().required(),
30337
+ positionCategory: import_joi42.default.string().required(),
30338
+ status: import_joi42.default.string().required()
30339
+ });
30340
+ const { error } = validation.validate(value);
30341
+ if (error) {
30342
+ next(new import_nodejs_utils85.BadRequestError(error.message));
30343
+ return;
30344
+ }
30345
+ try {
30346
+ const id = await _addPlantilla(value);
30347
+ res.json({ message: "Plantilla created successfully", id });
30348
+ return;
30349
+ } catch (error2) {
30350
+ next(error2);
30351
+ }
30352
+ }
30353
+ async function getAllPlantillas(req, res, next) {
30354
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
30355
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
30356
+ const search = req.query.search ?? "";
30357
+ const org = req.query.org ?? "";
30358
+ const isPageNumber = isFinite(page);
30359
+ if (!isPageNumber) {
30360
+ next(new import_nodejs_utils85.BadRequestError("Invalid page number."));
30361
+ return;
30362
+ }
30363
+ const isLimitNumber = isFinite(limit);
30364
+ if (!isLimitNumber) {
30365
+ next(new import_nodejs_utils85.BadRequestError("Invalid limit number."));
30366
+ return;
30367
+ }
30368
+ const validation = import_joi42.default.object({
30369
+ page: import_joi42.default.number().min(1).optional().allow("", null),
30370
+ limit: import_joi42.default.number().min(1).optional().allow("", null),
30371
+ search: import_joi42.default.string().optional().allow("", null),
30372
+ org: import_joi42.default.string().optional().allow("", null)
30373
+ });
30374
+ const { error } = validation.validate({ page, limit, search, org });
30375
+ if (error) {
30376
+ next(new import_nodejs_utils85.BadRequestError(error.message));
30377
+ return;
30378
+ }
30379
+ try {
30380
+ const plantillas = await _getAllPlantillas({
30381
+ search,
30382
+ page,
30383
+ limit,
30384
+ org
30385
+ });
30386
+ res.json(plantillas);
30387
+ return;
30388
+ } catch (error2) {
30389
+ next(error2);
30390
+ }
30391
+ }
30392
+ async function getPlantillaById(req, res, next) {
30393
+ const id = req.params.id;
30394
+ const validation = import_joi42.default.object({
30395
+ id: import_joi42.default.string().hex().required()
30396
+ });
30397
+ const { error } = validation.validate({ id });
30398
+ if (error) {
30399
+ next(new import_nodejs_utils85.BadRequestError(error.message));
30400
+ return;
30401
+ }
30402
+ try {
30403
+ const plantilla = await _getPlantillaById(id);
30404
+ if (!plantilla) {
30405
+ next(new import_nodejs_utils85.BadRequestError("Plantilla not found."));
30406
+ return;
30407
+ }
30408
+ res.json(plantilla);
30409
+ return;
30410
+ } catch (error2) {
30411
+ next(error2);
30412
+ }
30413
+ }
30414
+ async function updatePlantilla(req, res, next) {
30415
+ const id = req.params.id;
30416
+ const value = req.body;
30417
+ const validation = import_joi42.default.object({
30418
+ id: import_joi42.default.string().hex().required(),
30419
+ employee: import_joi42.default.string().hex().optional().allow(null, ""),
30420
+ status: import_joi42.default.string().optional(),
30421
+ positionTitle: import_joi42.default.string().optional(),
30422
+ positionCategory: import_joi42.default.string().optional()
30423
+ });
30424
+ const { error } = validation.validate({ id, ...value });
30425
+ if (error) {
30426
+ next(new import_nodejs_utils85.BadRequestError(error.message));
30427
+ return;
30428
+ }
30429
+ try {
30430
+ const result = await _updatePlantillaById(id, value);
30431
+ if (result.matchedCount === 0) {
30432
+ next(new import_nodejs_utils85.BadRequestError("Plantilla not found."));
30433
+ return;
30434
+ }
30435
+ res.json({ message: "Plantilla updated successfully" });
30436
+ return;
30437
+ } catch (error2) {
30438
+ next(error2);
30439
+ }
30440
+ }
30441
+ async function deletePlantilla(req, res, next) {
30442
+ const id = req.params.id;
30443
+ const validation = import_joi42.default.object({
30444
+ id: import_joi42.default.string().hex().required()
30445
+ });
30446
+ const { error } = validation.validate({ id });
30447
+ if (error) {
30448
+ next(new import_nodejs_utils85.BadRequestError(error.message));
30449
+ return;
30450
+ }
30451
+ try {
30452
+ const result = await _deletePlantillaById(id);
30453
+ if (result.matchedCount === 0) {
30454
+ next(new import_nodejs_utils85.BadRequestError("Plantilla not found."));
30455
+ return;
30456
+ }
30457
+ res.json({ message: "Plantilla deleted successfully" });
30458
+ return;
30459
+ } catch (error2) {
30460
+ next(error2);
30461
+ }
30462
+ }
30463
+ async function bulkAddPlantillas(req, res, next) {
30464
+ if (!req.file) {
30465
+ res.status(400).send("File is required!");
30466
+ return;
30467
+ }
30468
+ const { region, division } = req.body;
30469
+ const validation = import_joi42.default.object({
30470
+ region: import_joi42.default.string().hex().optional(),
30471
+ division: import_joi42.default.string().hex().optional()
30472
+ });
30473
+ const { error } = validation.validate({ region, division });
30474
+ if (error) {
30475
+ next(new import_nodejs_utils85.BadRequestError(`Validation error: ${error.message}`));
30476
+ return;
30477
+ }
30478
+ if (!region && !division) {
30479
+ next(
30480
+ new import_nodejs_utils85.BadRequestError(
30481
+ "At least one of region or division must be provided"
30482
+ )
30483
+ );
30484
+ return;
30485
+ }
30486
+ try {
30487
+ const result = await _addBulk(req.file, region, division);
30488
+ res.status(201).json(result);
30489
+ return;
30490
+ } catch (error2) {
30491
+ next(error2);
30492
+ return;
30493
+ }
30494
+ }
30495
+ return {
30496
+ createPlantilla,
30497
+ getAllPlantillas,
30498
+ getPlantillaById,
30499
+ updatePlantilla,
30500
+ deletePlantilla,
30501
+ bulkAddPlantillas
30502
+ };
30503
+ }
29169
30504
  // Annotate the CommonJS export names for ESM import in node:
29170
30505
  0 && (module.exports = {
29171
30506
  ACCESS_TOKEN_EXPIRY,
@@ -29197,6 +30532,7 @@ function useStockCardController() {
29197
30532
  MOrder,
29198
30533
  MOrg,
29199
30534
  MPaymentMethod,
30535
+ MPlantilla,
29200
30536
  MPromoCode,
29201
30537
  MRegion,
29202
30538
  MRole,
@@ -29234,6 +30570,7 @@ function useStockCardController() {
29234
30570
  schemaBuilding,
29235
30571
  schemaBuildingUnit,
29236
30572
  schemaDivision,
30573
+ schemaPlantilla,
29237
30574
  schemaRegion,
29238
30575
  schemaSchool,
29239
30576
  schemaStockCard,
@@ -29258,6 +30595,7 @@ function useStockCardController() {
29258
30595
  useFileController,
29259
30596
  useFileRepo,
29260
30597
  useFileService,
30598
+ useGitHubService,
29261
30599
  useInvoiceController,
29262
30600
  useInvoiceModel,
29263
30601
  useInvoiceRepo,
@@ -29276,6 +30614,8 @@ function useStockCardController() {
29276
30614
  usePaymentModel,
29277
30615
  usePaymentRepo,
29278
30616
  usePaypalService,
30617
+ usePlantillaController,
30618
+ usePlantillaRepo,
29279
30619
  usePriceController,
29280
30620
  usePriceModel,
29281
30621
  usePriceRepo,
@@ -29298,6 +30638,7 @@ function useStockCardController() {
29298
30638
  useUserController,
29299
30639
  useUserRepo,
29300
30640
  useUserService,
30641
+ useUtilController,
29301
30642
  useVerificationController,
29302
30643
  useVerificationRepo,
29303
30644
  useVerificationService,