@cloudnux/local-cloud-provider 0.18.0 → 0.19.0

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.d.ts CHANGED
@@ -1,10 +1,25 @@
1
- import { CloudProvider } from '@cloudnux/core-cloud-provider';
1
+ import { LoggerService, LogEntry, CloudProvider } from '@cloudnux/core-cloud-provider';
2
2
  import { FastifyInstance } from 'fastify';
3
3
 
4
+ type LogContext = {
5
+ module?: string;
6
+ reqId?: string;
7
+ };
8
+ type LogListener = (entry: LogEntry) => void;
9
+ type RunWithLogContext = <T>(context: LogContext, fn: () => T) => T;
10
+ type SubscribeToLogs = (listener: LogListener) => () => void;
11
+ type LoggingContext = LoggerService & {
12
+ runWithLogContext: RunWithLogContext;
13
+ subscribeToLogs: SubscribeToLogs;
14
+ };
15
+ declare module "fastify" {
16
+ interface FastifyInstance {
17
+ logging: LoggingContext;
18
+ }
19
+ }
20
+
4
21
  type RouterInstance = FastifyInstance;
5
- declare function createRouter(options?: {
6
- logger?: boolean;
7
- }): RouterInstance;
22
+ declare function createRouter(): RouterInstance;
8
23
 
9
24
  declare const localCloudProvider: CloudProvider;
10
25
 
package/dist/index.js CHANGED
@@ -1,6 +1,5 @@
1
- // src/logging/pretty-writer.ts
2
- import chalk from "chalk";
3
- import { EOL as EOL2 } from "os";
1
+ // src/services/event-broker.ts
2
+ import axios from "axios";
4
3
 
5
4
  // ../../../node_modules/lodash-es/_freeGlobal.js
6
5
  var freeGlobal = typeof global == "object" && global && global.Object === Object && global;
@@ -964,190 +963,9 @@ var tokenUtils = {
964
963
  verifyAccessToken: verify
965
964
  };
966
965
 
967
- // ../../utils/src/logging/types.ts
968
- var logLevels = {
969
- fatal: -1,
970
- error: 0,
971
- warn: 1,
972
- info: 2,
973
- debug: 3,
974
- trace: 4
975
- };
976
-
977
- // ../../utils/src/logging/error-to-string.ts
978
- var safeJsonStringify = (value) => {
979
- const seen = /* @__PURE__ */ new WeakSet();
980
- return JSON.stringify(value, (key, currentValue) => {
981
- if (key === "constructor") return void 0;
982
- if (typeof currentValue === "object" && currentValue !== null) {
983
- if (seen.has(currentValue)) return "[Circular]";
984
- seen.add(currentValue);
985
- }
986
- return currentValue;
987
- });
988
- };
989
- var hasOwnConstructorProp = (value) => {
990
- if (typeof value !== "object" || value === null) return false;
991
- return Object.prototype.hasOwnProperty.call(value, "constructor");
992
- };
993
- var errorToString = (error) => {
994
- if (error === null) return "Null error";
995
- if (error === void 0) return "Undefined error";
996
- if (error instanceof Error) {
997
- return [
998
- `Name: ${error.name}`,
999
- `Message: ${error.message}`,
1000
- `Stack: ${error.stack || "No stack trace available"}`,
1001
- // Handle additional properties that might exist on custom errors
1002
- ...Object.entries(error).filter(
1003
- ([key, value]) => !["name", "message", "stack"].includes(key) && !hasOwnConstructorProp(value)
1004
- ).map(([key, value]) => `${key}: ${safeJsonStringify(value)}`)
1005
- ].join("\n");
1006
- }
1007
- if (typeof error === "string") return error;
1008
- if (typeof error === "object") {
1009
- try {
1010
- return JSON.stringify(
1011
- error,
1012
- (key, value) => {
1013
- if (key === "constructor") return void 0;
1014
- return value;
1015
- },
1016
- 2
1017
- );
1018
- } catch {
1019
- return `[Object that cannot be stringified: ${Object.prototype.toString.call(error)}]`;
1020
- }
1021
- }
1022
- return String(error);
1023
- };
1024
-
1025
- // ../../utils/src/logging/writer.ts
1026
- import { EOL } from "os";
1027
- var jsonWriter = (entry) => {
1028
- process.stdout.write(JSON.stringify(entry) + EOL);
1029
- };
1030
- var _writer = jsonWriter;
1031
- function setWriter(writer) {
1032
- _writer = writer;
1033
- }
1034
- function getWriter() {
1035
- return _writer;
1036
- }
1037
-
1038
- // ../../utils/src/logging/index.ts
1039
- var levelValues = {
1040
- fatal: 70,
1041
- error: 60,
1042
- warn: 50,
1043
- info: 40,
1044
- debug: 30,
1045
- trace: 20
1046
- };
1047
- var currentLogLevel = 2;
1048
- var _module = "default";
1049
- var _requestId = "";
1050
- function writeLine(level, mergeObject, msg, bindings) {
1051
- getWriter()({
1052
- level: levelValues[level],
1053
- levelName: level,
1054
- time: Date.now(),
1055
- module: bindings.module || _module,
1056
- reqId: bindings.reqId || _requestId,
1057
- msg: level === "error" || level === "fatal" ? errorToString(msg) : msg,
1058
- ...mergeObject ? { meta: mergeObject } : {}
1059
- });
1060
- }
1061
- function createLogger(bindings = {}) {
1062
- const currentLogLevelName = env("LOG_LEVEL")?.toLowerCase() ?? "info";
1063
- currentLogLevel = logLevels[currentLogLevelName] ?? logLevels.info;
1064
- return {
1065
- level: currentLogLevelName,
1066
- fatal: (mergeObject, msg) => {
1067
- if (currentLogLevel >= logLevels.fatal) {
1068
- typeof mergeObject === "string" || mergeObject instanceof Error ? writeLine("fatal", null, mergeObject, bindings) : writeLine("fatal", mergeObject, msg ?? "", bindings);
1069
- }
1070
- },
1071
- error: (mergeObject, msg) => {
1072
- if (currentLogLevel >= logLevels.error) {
1073
- typeof mergeObject === "string" || mergeObject instanceof Error ? writeLine("error", null, mergeObject, bindings) : writeLine("error", mergeObject, msg ?? "", bindings);
1074
- }
1075
- },
1076
- warn: (mergeObject, msg) => {
1077
- if (currentLogLevel >= logLevels.warn) {
1078
- typeof mergeObject === "string" ? writeLine("warn", null, mergeObject, bindings) : writeLine("warn", mergeObject, msg ?? "", bindings);
1079
- }
1080
- },
1081
- info: (mergeObject, msg) => {
1082
- if (currentLogLevel >= logLevels.info) {
1083
- typeof mergeObject === "string" ? writeLine("info", null, mergeObject, bindings) : writeLine("info", mergeObject, msg ?? "", bindings);
1084
- }
1085
- },
1086
- debug: (mergeObject, msg) => {
1087
- if (currentLogLevel >= logLevels.debug) {
1088
- typeof mergeObject === "string" ? writeLine("debug", null, mergeObject, bindings) : writeLine("debug", mergeObject, msg ?? "", bindings);
1089
- }
1090
- },
1091
- trace: (mergeObject, msg) => {
1092
- if (currentLogLevel >= logLevels.trace) {
1093
- typeof mergeObject === "string" ? writeLine("trace", null, mergeObject, bindings) : writeLine("trace", mergeObject, msg ?? "", bindings);
1094
- }
1095
- },
1096
- silent: () => {
1097
- },
1098
- child: (childBindings) => createLogger({ ...bindings, ...childBindings })
1099
- };
1100
- }
1101
- var logger = createLogger();
1102
-
1103
- // src/logging/pretty-writer.ts
1104
- var levelColor = {
1105
- fatal: chalk.bgRed.white,
1106
- error: chalk.red,
1107
- warn: chalk.yellow,
1108
- info: chalk.cyan,
1109
- debug: chalk.gray,
1110
- trace: chalk.white
1111
- };
1112
- function formatTime(ms) {
1113
- return new Date(ms).toTimeString().slice(0, 8);
1114
- }
1115
- function formatMeta(meta) {
1116
- const { req, res, ...rest } = meta;
1117
- const lines = [];
1118
- if (req) {
1119
- const reqParts = [`${req.method} ${req.url}`];
1120
- if (req.remoteAddress) reqParts.push(`from ${req.remoteAddress}:${req.remotePort ?? ""}`);
1121
- if (req.headers) reqParts.push(`headers=${JSON.stringify(req.headers, null, 2)}`);
1122
- if (req.body !== void 0) reqParts.push(`body=${typeof req.body === "string" ? req.body : JSON.stringify(req.body, null, 2)}`);
1123
- lines.push(chalk.dim(" req: " + reqParts.join(" ")));
1124
- }
1125
- if (res) {
1126
- const resParts = [`${res.statusCode}`];
1127
- if (res.headers) resParts.push(`headers=${JSON.stringify(res.headers, null, 2)}`);
1128
- if (res.body !== void 0) resParts.push(`body=${typeof res.body === "string" ? res.body : JSON.stringify(res.body, null, 2)}`);
1129
- lines.push(chalk.dim(" res: " + resParts.join(" ")));
1130
- }
1131
- if (Object.keys(rest).length) {
1132
- lines.push(chalk.dim(" " + JSON.stringify(rest, null, 2)));
1133
- }
1134
- return lines.length ? EOL2 + lines.join(EOL2) : "";
1135
- }
1136
- var prettyWriter = (entry) => {
1137
- const color = levelColor[entry.levelName] ?? chalk.white;
1138
- const time = chalk.dim(formatTime(entry.time));
1139
- const level = color(entry.levelName.toUpperCase().padEnd(5));
1140
- const module = chalk.magenta(entry.module);
1141
- const reqId = entry.reqId ? chalk.dim(`[${entry.reqId}]`) + " " : "";
1142
- const meta = entry.meta ? formatMeta(entry.meta) : "";
1143
- process.stdout.write(`${time} ${level} ${module} ${reqId}- ${entry.msg}${meta}${EOL2}`);
1144
- };
1145
- setWriter(prettyWriter);
1146
-
1147
966
  // src/services/event-broker.ts
1148
- import axios from "axios";
1149
967
  function createLocalEventBrokerService() {
1150
- const baseURL = env("DEV_CLOUD_EVENT_BROKER_URL", "http://localhost:3000");
968
+ const baseURL = env("DEV_CLOUD_EVENT_BROKER_URL");
1151
969
  function getQueueUrl(queueName) {
1152
970
  if (queueName.startsWith("http://") || queueName.startsWith("https://")) {
1153
971
  return queueName;
@@ -1243,9 +1061,11 @@ function createLocalEventBrokerService() {
1243
1061
  // src/services/storage.ts
1244
1062
  import * as fs from "fs";
1245
1063
  import * as path from "path";
1064
+ import { getService } from "@cloudnux/core-cloud-provider";
1246
1065
  var { mkdir, writeFile, readFile, unlink, access } = fs.promises;
1247
1066
  function createLocalStorageService() {
1248
1067
  const baseDir = env("DEV_CLOUD_STORAGE_BUCKET", path.join(process.cwd(), ".local-storage"));
1068
+ const logger2 = getService("logger");
1249
1069
  if (!fs.existsSync(baseDir)) {
1250
1070
  fs.mkdirSync(baseDir, { recursive: true });
1251
1071
  }
@@ -1341,7 +1161,7 @@ function createLocalStorageService() {
1341
1161
  await unlink(metadataPath);
1342
1162
  } catch (error) {
1343
1163
  if (error.code !== "ENOENT") {
1344
- logger.warn({ error }, "Error deleting metadata file:");
1164
+ logger2.warn({ error }, "Error deleting metadata file:");
1345
1165
  }
1346
1166
  }
1347
1167
  } catch (error) {
@@ -1357,6 +1177,9 @@ function createLocalStorageService() {
1357
1177
  // src/services/locations.ts
1358
1178
  import * as fs2 from "fs";
1359
1179
  import * as path2 from "path";
1180
+ import {
1181
+ getService as getService2
1182
+ } from "@cloudnux/core-cloud-provider";
1360
1183
  var { readFile: readFile2, writeFile: writeFile2, access: access2, mkdir: mkdir2 } = fs2.promises;
1361
1184
  var DEFAULT_MOCK_LOCATIONS = {
1362
1185
  "place-001": {
@@ -1590,6 +1413,7 @@ function toLocationAddress(location) {
1590
1413
  function createLocalLocationService() {
1591
1414
  const baseDir = env("DEV_CLOUD_LOCATION_PATH", path2.join(process.cwd(), ".develop", ".local-location"));
1592
1415
  const placesFilePath = path2.join(baseDir, "places.json");
1416
+ const logger2 = getService2("logger");
1593
1417
  async function loadPlaces() {
1594
1418
  try {
1595
1419
  try {
@@ -1603,11 +1427,11 @@ function createLocalLocationService() {
1603
1427
  return JSON.parse(data);
1604
1428
  } catch {
1605
1429
  await writeFile2(placesFilePath, JSON.stringify(DEFAULT_MOCK_LOCATIONS, null, 2), "utf8");
1606
- logger.info(`Created default places file at: ${placesFilePath}`);
1430
+ logger2.info(`Created default places file at: ${placesFilePath}`);
1607
1431
  return DEFAULT_MOCK_LOCATIONS;
1608
1432
  }
1609
1433
  } catch (error) {
1610
- logger.warn(`Error loading places data: ${String(error)}`);
1434
+ logger2.warn(`Error loading places data: ${String(error)}`);
1611
1435
  return DEFAULT_MOCK_LOCATIONS;
1612
1436
  }
1613
1437
  }
@@ -1746,7 +1570,7 @@ function createLocalLocationService() {
1746
1570
  Math.max(...lats)
1747
1571
  // maxLat
1748
1572
  ];
1749
- logger.info(`Calculated route: ${totalDistanceKm.toFixed(2)}km, ${totalDurationMinutes.toFixed(0)}min, ${legs.length} legs`);
1573
+ logger2.info(`Calculated route: ${totalDistanceKm.toFixed(2)}km, ${totalDurationMinutes.toFixed(0)}min, ${legs.length} legs`);
1750
1574
  return {
1751
1575
  totalDistanceKm,
1752
1576
  totalDurationMinutes,
@@ -1790,7 +1614,8 @@ function createLocalFunctionsService() {
1790
1614
  params: request.params,
1791
1615
  rawQueryString: querystring.stringify(request.query),
1792
1616
  host: request.hostname,
1793
- requestId: request.id
1617
+ requestId: request.id,
1618
+ moduleName: request.routeOptions.config?.module
1794
1619
  };
1795
1620
  const jwtClaims = token && tokenUtils.decodeAccessToken(token);
1796
1621
  const httpAuth = isAuth ? {
@@ -1819,7 +1644,8 @@ function createLocalFunctionsService() {
1819
1644
  const scheduleName = job.name;
1820
1645
  const scheduleRequest = {
1821
1646
  name: scheduleName,
1822
- requestId: execution.id
1647
+ requestId: execution.id,
1648
+ moduleName: job.module
1823
1649
  };
1824
1650
  return [scheduleRequest];
1825
1651
  },
@@ -1837,7 +1663,6 @@ function createLocalFunctionsService() {
1837
1663
  return [eventRequest];
1838
1664
  },
1839
1665
  createWebSocketRequest: (connectionId, event, data, request) => {
1840
- logger.info(request.params);
1841
1666
  const wsRequest = {
1842
1667
  connectionId,
1843
1668
  event,
@@ -1937,16 +1762,138 @@ function createLocalInvokeService() {
1937
1762
  };
1938
1763
  }
1939
1764
 
1765
+ // src/logger/index.ts
1766
+ import chalk from "chalk";
1767
+ import { EOL } from "os";
1768
+ import { AsyncLocalStorage } from "async_hooks";
1769
+ var storage = new AsyncLocalStorage();
1770
+ function enterLogContext(context) {
1771
+ storage.enterWith(context);
1772
+ }
1773
+ function runWithLogContext(context, fn) {
1774
+ return storage.run(context, fn);
1775
+ }
1776
+ function getLogContext() {
1777
+ return storage.getStore() ?? {};
1778
+ }
1779
+ var listeners = /* @__PURE__ */ new Set();
1780
+ function subscribeToLogs(listener) {
1781
+ listeners.add(listener);
1782
+ return () => listeners.delete(listener);
1783
+ }
1784
+ function publish(entry) {
1785
+ for (const listener of listeners) {
1786
+ listener(entry);
1787
+ }
1788
+ }
1789
+ var levels = ["fatal", "error", "warn", "info", "debug", "trace"];
1790
+ function resolveLevel() {
1791
+ const configured = env("LOG_LEVEL", "info").toLowerCase();
1792
+ return levels.includes(configured) ? configured : "info";
1793
+ }
1794
+ var cachedLevel;
1795
+ function currentLevel() {
1796
+ if (cachedLevel === void 0) {
1797
+ cachedLevel = resolveLevel();
1798
+ }
1799
+ return cachedLevel;
1800
+ }
1801
+ function isEnabled(level) {
1802
+ return levels.indexOf(level) <= levels.indexOf(currentLevel());
1803
+ }
1804
+ var levelColor = {
1805
+ fatal: chalk.bgRed.white,
1806
+ error: chalk.red,
1807
+ warn: chalk.yellow,
1808
+ info: chalk.cyan,
1809
+ debug: chalk.gray,
1810
+ trace: chalk.white
1811
+ };
1812
+ function formatTime(ms) {
1813
+ return new Date(ms).toTimeString().slice(0, 8);
1814
+ }
1815
+ function circularSafeReplacer() {
1816
+ const seen = /* @__PURE__ */ new WeakSet();
1817
+ return (_key, value) => {
1818
+ if (typeof value === "object" && value !== null) {
1819
+ if (seen.has(value)) return "[Circular]";
1820
+ seen.add(value);
1821
+ }
1822
+ return value;
1823
+ };
1824
+ }
1825
+ function formatMeta(meta) {
1826
+ return EOL + chalk.dim(" " + JSON.stringify(meta, circularSafeReplacer()));
1827
+ }
1828
+ function printPretty(entry) {
1829
+ const color = levelColor[entry.levelName] ?? chalk.white;
1830
+ const time = chalk.dim(formatTime(entry.time));
1831
+ const level = color(entry.levelName.toUpperCase().padEnd(5));
1832
+ const module = chalk.magenta(entry.module);
1833
+ const reqId = entry.reqId ? chalk.dim(`[${entry.reqId}] `) : "";
1834
+ const meta = entry.meta ? formatMeta(entry.meta) : "";
1835
+ process.stdout.write(`${time} ${level} ${module} ${reqId}- ${entry.msg}${meta}${EOL}`);
1836
+ }
1837
+ function write(level, mergeObject, msg) {
1838
+ if (!isEnabled(level)) return;
1839
+ const context = getLogContext();
1840
+ let module = context.module ?? "default";
1841
+ let reqId = context.reqId ?? "";
1842
+ let text;
1843
+ let meta;
1844
+ if (typeof mergeObject === "string") {
1845
+ text = mergeObject;
1846
+ } else if (mergeObject instanceof Error) {
1847
+ text = mergeObject.stack ?? mergeObject.message;
1848
+ } else {
1849
+ const { module: explicitModule, reqId: explicitReqId, ...rest } = mergeObject;
1850
+ if (explicitModule) module = explicitModule;
1851
+ if (explicitReqId) reqId = explicitReqId;
1852
+ meta = Object.keys(rest).length ? rest : void 0;
1853
+ text = msg ?? "";
1854
+ }
1855
+ const entry = {
1856
+ level: levels.indexOf(level),
1857
+ levelName: level,
1858
+ time: Date.now(),
1859
+ module,
1860
+ reqId,
1861
+ msg: text,
1862
+ ...meta ? { meta } : {}
1863
+ };
1864
+ printPretty(entry);
1865
+ publish(entry);
1866
+ }
1867
+ var logger = {
1868
+ get level() {
1869
+ return currentLevel();
1870
+ },
1871
+ setBindings: () => {
1872
+ },
1873
+ fatal: (mergeObject, msg) => write("fatal", mergeObject, msg),
1874
+ error: (mergeObject, msg) => write("error", mergeObject, msg),
1875
+ warn: (mergeObject, msg) => write("warn", mergeObject, msg),
1876
+ info: (mergeObject, msg) => write("info", mergeObject, msg),
1877
+ debug: (mergeObject, msg) => write("debug", mergeObject, msg),
1878
+ trace: (mergeObject, msg) => write("trace", mergeObject, msg)
1879
+ };
1880
+
1881
+ // src/services/logger.ts
1882
+ function createLocalLoggerService() {
1883
+ return logger;
1884
+ }
1885
+
1940
1886
  // src/router/index.ts
1941
1887
  import Fastify from "fastify";
1942
1888
  import fastifyRawBody from "fastify-raw-body";
1943
1889
  import cors from "@fastify/cors";
1944
1890
  import fastifyPrintRoutes from "fastify-print-routes";
1945
- function createRouter(options = {}) {
1891
+ function createRouter() {
1946
1892
  const fastify = Fastify({
1947
1893
  maxParamLength: 1e3,
1948
- ...options.logger ? { loggerInstance: logger } : {}
1894
+ logger: false
1949
1895
  });
1896
+ fastify.decorate("logging", { ...logger, runWithLogContext, subscribeToLogs });
1950
1897
  fastify.register(fastifyRawBody, {
1951
1898
  field: "rawBody",
1952
1899
  encoding: "utf8"
@@ -1955,6 +1902,24 @@ function createRouter(options = {}) {
1955
1902
  "methods": ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"]
1956
1903
  });
1957
1904
  fastify.register(fastifyPrintRoutes);
1905
+ fastify.addHook("onRequest", (request, _reply, done) => {
1906
+ const module = request.routeOptions.config?.module;
1907
+ enterLogContext({ module, reqId: request.id });
1908
+ done();
1909
+ });
1910
+ fastify.addHook("onResponse", (request, reply, done) => {
1911
+ if (!request.url.startsWith("/console")) {
1912
+ logger.info(
1913
+ { method: request.method, url: request.url, statusCode: reply.statusCode, responseTime: reply.elapsedTime },
1914
+ `${request.method} ${request.url} ${reply.statusCode}`
1915
+ );
1916
+ }
1917
+ done();
1918
+ });
1919
+ fastify.addHook("onError", (_request, _reply, error, done) => {
1920
+ logger.error(error);
1921
+ done();
1922
+ });
1958
1923
  fastify.addHook("onReady", () => {
1959
1924
  setWebSocketManager(fastify.websockets);
1960
1925
  setInvokeManager(fastify.invokes);
@@ -1970,7 +1935,8 @@ var localCloudProvider = {
1970
1935
  createEventBrokerService: createLocalEventBrokerService,
1971
1936
  createFunctionsService: createLocalFunctionsService,
1972
1937
  createWebSocketService: createLocalWebSocketService,
1973
- createInvokeService: createLocalInvokeService
1938
+ createInvokeService: createLocalInvokeService,
1939
+ createLoggerService: createLocalLoggerService
1974
1940
  };
1975
1941
  export {
1976
1942
  createRouter,