fnos-cli 0.1.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.
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Logger utility using Winston
3
+ */
4
+
5
+ const winston = require('winston');
6
+ const os = require('os');
7
+ const path = require('path');
8
+ const crypto = require('crypto');
9
+ const util = require('util');
10
+
11
+ // Create logs directory if it doesn't exist
12
+ const logsDir = path.join(os.homedir(), '.fnos', 'logs');
13
+ const fs = require('fs');
14
+ if (!fs.existsSync(logsDir)) {
15
+ fs.mkdirSync(logsDir, { recursive: true });
16
+ }
17
+
18
+ // Generate random number for log filename
19
+ const randomNum = crypto.randomBytes(4).toString('hex');
20
+ const logFilename = `fnos-${new Date().toISOString().split('T')[0]}-${randomNum}.log`;
21
+
22
+ // Log format
23
+ const logFormat = winston.format.printf(({ timestamp, level, message }) => {
24
+ return `${timestamp} - ${level.toUpperCase()} - ${message}`;
25
+ });
26
+
27
+ // Create a custom transport that outputs to stderr
28
+ class StderrTransport extends winston.Transport {
29
+ constructor(opts = {}) {
30
+ super(opts);
31
+ this.level = opts.level || 'error';
32
+ this.format = opts.format || winston.format.simple();
33
+ }
34
+
35
+ log(info, callback) {
36
+ setImmediate(() => {
37
+ this.emit('logged', info);
38
+ });
39
+
40
+ // Format the message
41
+ const formatted = this.format.transform(info);
42
+ const message = typeof formatted === 'string' ? formatted : formatted[Symbol.for('message')] || formatted.message;
43
+
44
+ // Output to stderr
45
+ process.stderr.write(message + '\n');
46
+
47
+ callback();
48
+ }
49
+ }
50
+
51
+ // Create logger
52
+ const logger = winston.createLogger({
53
+ level: 'silly', // Capture all levels for file output
54
+ format: winston.format.combine(
55
+ winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
56
+ logFormat
57
+ ),
58
+ transports: [
59
+ // Console transport - output all logs to stderr
60
+ new StderrTransport({
61
+ level: 'error', // Default: only show errors
62
+ format: winston.format.combine(
63
+ winston.format.colorize(),
64
+ logFormat
65
+ )
66
+ }),
67
+ // File transport - output all levels
68
+ new winston.transports.File({
69
+ level: 'silly', // Write all levels to file
70
+ filename: path.join(logsDir, logFilename),
71
+ maxsize: 10 * 1024 * 1024, // 10MB
72
+ maxFiles: 5
73
+ })
74
+ ]
75
+ });
76
+
77
+ /**
78
+ * Set log level based on verbose flag
79
+ * @param {number} verbose - Verbose level (0, 1, 2, 3)
80
+ */
81
+ function setLogLevel(verbose) {
82
+ const consoleTransport = logger.transports.find(t => t instanceof StderrTransport);
83
+
84
+ if (verbose === 0) {
85
+ // Default: only show errors on console
86
+ consoleTransport.level = 'error';
87
+ } else if (verbose >= 1 && verbose <= 3) {
88
+ const levels = ['info', 'debug', 'silly'];
89
+ // Show logs at specified level on console
90
+ consoleTransport.level = levels[verbose - 1];
91
+ }
92
+
93
+ // Also update the overall logger level to ensure file transport works correctly
94
+ logger.level = verbose >= 3 ? 'silly' : (verbose >= 2 ? 'debug' : (verbose >= 1 ? 'info' : 'error'));
95
+
96
+ // Try to update SDK logger level if available
97
+ try {
98
+ const fnosLogger = require('fnos/dist/logger');
99
+ if (fnosLogger && fnosLogger.default && fnosLogger.default.transports) {
100
+ // Remove existing console transport
101
+ const sdkConsoleTransport = fnosLogger.default.transports.find(t => t instanceof winston.transports.Console);
102
+ if (sdkConsoleTransport) {
103
+ fnosLogger.default.remove(sdkConsoleTransport);
104
+ }
105
+ // Add our custom stderr transport
106
+ const sdkStderrTransport = new StderrTransport({
107
+ level: consoleTransport.level,
108
+ format: winston.format.combine(
109
+ winston.format.colorize(),
110
+ logFormat
111
+ )
112
+ });
113
+ fnosLogger.default.add(sdkStderrTransport);
114
+ }
115
+ } catch (error) {
116
+ // Ignore if fnos logger is not available
117
+ }
118
+ }
119
+
120
+ module.exports = { logger, setLogLevel };
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Settings manager for fnos
3
+ */
4
+
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+ const os = require('os');
8
+
9
+ class Settings {
10
+ constructor() {
11
+ this.settingsDir = path.join(os.homedir(), '.fnos');
12
+ this.settingsPath = path.join(this.settingsDir, 'settings.json');
13
+ }
14
+
15
+ /**
16
+ * Ensure settings directory exists
17
+ */
18
+ _ensureDir() {
19
+ if (!fs.existsSync(this.settingsDir)) {
20
+ fs.mkdirSync(this.settingsDir, { recursive: true });
21
+ }
22
+ }
23
+
24
+ /**
25
+ * Load settings from file
26
+ * @returns {Object|null} Settings object or null if not exists
27
+ */
28
+ load() {
29
+ if (!fs.existsSync(this.settingsPath)) {
30
+ return null;
31
+ }
32
+ try {
33
+ const data = fs.readFileSync(this.settingsPath, 'utf8');
34
+ return JSON.parse(data);
35
+ } catch (error) {
36
+ console.error('Failed to load settings:', error.message);
37
+ return null;
38
+ }
39
+ }
40
+
41
+ /**
42
+ * Save settings to file
43
+ * @param {Object} data - Settings data to save
44
+ */
45
+ save(data) {
46
+ this._ensureDir();
47
+ try {
48
+ fs.writeFileSync(this.settingsPath, JSON.stringify(data, null, 2), {
49
+ mode: 0o600 // Read/write for owner only
50
+ });
51
+ } catch (error) {
52
+ console.error('Failed to save settings:', error.message);
53
+ throw error;
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Clear settings file
59
+ */
60
+ clear() {
61
+ if (fs.existsSync(this.settingsPath)) {
62
+ fs.unlinkSync(this.settingsPath);
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Check if settings file exists
68
+ * @returns {boolean} True if settings file exists
69
+ */
70
+ exists() {
71
+ return fs.existsSync(this.settingsPath);
72
+ }
73
+
74
+ /**
75
+ * Get authentication credentials
76
+ * @returns {Object|null} Credentials object or null
77
+ */
78
+ getCredentials() {
79
+ const settings = this.load();
80
+ if (!settings) {
81
+ return null;
82
+ }
83
+ return {
84
+ endpoint: settings.endpoint,
85
+ username: settings.username,
86
+ password: settings.password,
87
+ token: settings.token,
88
+ longToken: settings.longToken,
89
+ secret: settings.secret
90
+ };
91
+ }
92
+
93
+ /**
94
+ * Save authentication credentials
95
+ * @param {Object} credentials - Credentials to save
96
+ */
97
+ saveCredentials(credentials) {
98
+ const existingSettings = this.load() || {};
99
+ this.save({
100
+ ...existingSettings,
101
+ ...credentials
102
+ });
103
+ }
104
+ }
105
+
106
+ module.exports = new Settings();