fix(ci): Update CI workflows, build scripts, and export configuration

This commit is contained in:
2025-05-12 10:03:22 +00:00
parent e853b2d5e4
commit 9b63777a76
50 changed files with 7188 additions and 1823 deletions

View File

@ -0,0 +1,66 @@
name: Default (not tags)
on:
push:
tags-ignore:
- '**'
env:
IMAGE: code.foss.global/host.today/ht-docker-node:npmci
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@/${{gitea.repository}}.git
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
NPMCI_URL_CLOUDLY: ${{secrets.NPMCI_URL_CLOUDLY}}
jobs:
security:
runs-on: ubuntu-latest
continue-on-error: true
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Install pnpm and npmci
run: |
pnpm install -g pnpm
pnpm install -g @ship.zone/npmci
- name: Run npm prepare
run: npmci npm prepare
- name: Audit production dependencies
run: |
npmci command npm config set registry https://registry.npmjs.org
npmci command pnpm audit --audit-level=high --prod
continue-on-error: true
- name: Audit development dependencies
run: |
npmci command npm config set registry https://registry.npmjs.org
npmci command pnpm audit --audit-level=high --dev
continue-on-error: true
test:
if: ${{ always() }}
needs: security
runs-on: ubuntu-latest
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Test stable
run: |
npmci node install stable
npmci npm install
npmci npm test
- name: Test build
run: |
npmci node install stable
npmci npm install
npmci npm build

View File

@ -0,0 +1,124 @@
name: Default (tags)
on:
push:
tags:
- '*'
env:
IMAGE: code.foss.global/host.today/ht-docker-node:npmci
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@/${{gitea.repository}}.git
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
NPMCI_URL_CLOUDLY: ${{secrets.NPMCI_URL_CLOUDLY}}
jobs:
security:
runs-on: ubuntu-latest
continue-on-error: true
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @ship.zone/npmci
npmci npm prepare
- name: Audit production dependencies
run: |
npmci command npm config set registry https://registry.npmjs.org
npmci command pnpm audit --audit-level=high --prod
continue-on-error: true
- name: Audit development dependencies
run: |
npmci command npm config set registry https://registry.npmjs.org
npmci command pnpm audit --audit-level=high --dev
continue-on-error: true
test:
if: ${{ always() }}
needs: security
runs-on: ubuntu-latest
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @ship.zone/npmci
npmci npm prepare
- name: Test stable
run: |
npmci node install stable
npmci npm install
npmci npm test
- name: Test build
run: |
npmci node install stable
npmci npm install
npmci npm build
release:
needs: test
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @ship.zone/npmci
npmci npm prepare
- name: Release
run: |
npmci node install stable
npmci npm publish
metadata:
needs: test
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
container:
image: ${{ env.IMAGE }}
continue-on-error: true
steps:
- uses: actions/checkout@v3
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @ship.zone/npmci
npmci npm prepare
- name: Code quality
run: |
npmci command npm install -g typescript
npmci npm install
- name: Trigger
run: npmci trigger
- name: Build docs and upload artifacts
run: |
npmci node install stable
npmci npm install
pnpm install -g @git.zone/tsdoc
npmci command tsdoc
continue-on-error: true

4
.gitignore vendored
View File

@ -3,7 +3,6 @@
# artifacts
coverage/
public/
pages/
# installs
node_modules/
@ -17,4 +16,5 @@ node_modules/
dist/
dist_*/
# custom
#------# custom
**/.claude/settings.local.json

313
changelog.md Normal file
View File

@ -0,0 +1,313 @@
# Changelog
## 2025-05-11 - 3.0.8 - fix(ci)
Update CI workflows, build scripts, and export configuration
- Add separate Gitea workflows for tag and non-tag pushes to automate testing, auditing, and release steps
- Revise package.json exports and update dependency versions and build scripts for improved module resolution
- Enhance tsconfig settings with baseUrl and paths for consistency
- Refine source code formatting and adjust test cases for better maintenance
## 2024-06-06 - 3.0.7 - no notable changes
This release contains no detailed changes.
## 2024-06-06 - 3.0.6 - core
A few fixes and updates were made in this release.
- fix(core): update
- update description
## 2024-05-17 - 3.0.5 - core
A minor core fix was applied.
- fix(core): update
## 2024-05-17 - 3.0.4 - core
This release includes several updates to core files and configuration.
- fix(core): update
- update tsconfig
- update npmextra.json: githost
- update npmextra.json: githost
- update npmextra.json: githost
## 2023-08-08 - 3.0.3 - core
A simple core update was performed.
- fix(core): update
## 2023-07-12 - 3.0.2 - core
Core updates and a change of organizational scheme were introduced.
- fix(core): update
- switch to new org scheme (x2)
## 2022-10-26 - 3.0.1 - core
A core fix was applied.
- fix(core): update
## 2022-07-26 - 3.0.0 - core
A minor core update was made.
- fix(core): update
## 2022-06-26 - 2.0.44 - core
A breaking change switched the module system to esm.
- BREAKING CHANGE(core): switch to esm
## 2021-07-21 - 2.0.43 - core
A core update was applied.
- fix(core): update
## 2021-07-20 - 2.0.42 - core
A core update was applied.
- fix(core): update
## 2021-07-20 - 2.0.41 - core
A core update was applied.
- fix(core): update
## 2021-07-20 - 2.0.40 - core
A core update was applied.
- fix(core): update
## 2021-07-06 - 2.0.39 - core
A core update was applied.
- fix(core): update
## 2020-09-08 - 2.0.38 - core
A core update was applied.
- fix(core): update
## 2020-09-07 - 2.0.37 - core
A core update was applied.
- fix(core): update
## 2020-09-07 - 2.0.36 - core
A core update was applied.
- fix(core): update
## 2020-08-02 - 2.0.35 - core
A core update was applied.
- fix(core): update
## 2020-06-11 - 2.0.34 - core
A core update was applied.
- fix(core): update
## 2020-06-11 - 2.0.33 - core
A core update was applied.
- fix(core): update
## 2020-06-11 - 2.0.32 - core
A core update was applied.
- fix(core): update
## 2020-06-11 - 2.0.31 - core
A core update was applied.
- fix(core): update
## 2020-06-11 - 2.0.30 - core
A core update was applied.
- fix(core): update
## 2020-06-11 - 2.0.29 - core
A core update was applied.
- fix(core): update
## 2020-06-11 - 2.0.28 - core
A core update was applied.
- fix(core): update
## 2020-06-08 - 2.0.27 - core
A core update was applied.
- fix(core): update
## 2020-06-08 - 2.0.26 - core
A core update was applied.
- fix(core): update
## 2020-06-08 - 2.0.25 - core
A core update was applied.
- fix(core): update
## 2020-06-08 - 2.0.24 - core
A core update was applied.
- fix(core): update
## 2020-06-07 - 2.0.23 - core
A core update was applied.
- fix(core): update
## 2020-06-05 - 2.0.22 - core
A core update was applied.
- fix(core): update
## 2020-06-05 - 2.0.21 - core
A core update was applied.
- fix(core): update
## 2019-10-22 - 2.0.20 - core
A core update was applied.
- fix(core): update
## 2019-10-22 - 2.0.19 - core
Dependencies were updated in the core.
- fix(core): update dependencies
## 2019-01-30 - 2.0.18 - license
License files were updated.
- fix(license): update license files
## 2019-01-30 - 2.0.17 - readme
A typo in the readme was fixed.
- fix(readme): fix typo
## 2019-01-30 - 2.0.16 - readme
A typo in the readme was fixed.
- fix(readme): fix typo
## 2019-01-28 - 2.0.15 - core
A core update was applied.
- fix(core): update
## 2019-01-28 - 2.0.14 - core
A core update was applied.
- fix(core): update
## 2019-01-22 - 2.0.13 - core
A core update was applied.
- fix(core): update
## 2019-01-22 - 2.0.12 - core
A core update was applied.
- fix(core): update
## 2019-01-18 - 2.0.11 - core
A core update was applied.
- fix(core): update
## 2019-01-15 - 2.0.10 - core
A core update was applied.
- fix(core): update
## 2019-01-15 - 2.0.9 - core
A core update was applied.
- fix(core): update
## 2018-11-11 - 2.0.8 - core
A core update was applied.
- fix(core): update
## 2018-11-04 - 2.0.7 - core
A core update was applied.
- fix(core): update
## 2018-11-04 - 2.0.6 - core
A core update was applied.
- fix(core): update
## 2018-11-04 - 2.0.5 - api
An API improvement was made.
- fix(api): streamline api
## 2018-11-04 - 2.0.4 - core
A core update was applied.
- fix(core): update
## 2018-11-03 - 2.0.3 - core
A core update was applied.
- fix(core): update
## 2018-10-31 - 2.0.2 - core
A core update was applied.
- fix(core): update
## 2018-10-30 - 2.0.1 - core
A new log router was implemented in core.
- fix(core): implement log router
## 2018-07-10 - 2.0.0 - core
Console enabling was fixed.
- fix(.enableConsole()): now works
## 2018-07-10 - 1.0.6 - core
A breaking change added a simple defaultLogger to core.
- BREAKING CHANGE(core): now has simple defaultLogger
## 2018-07-08 - 1.0.5 - npm
Package distribution was fixed.
- fix(npm): package distribution
## 2018-06-05 - 1.0.4 - package
The package name was updated.
- fix(package): update package name
## 2018-06-05 - 1.0.3 - core
Several changes were made to update standards and system behavior.
- fix(core): update to latest standards
- system change
## 2018-01-28 - 1.0.2 - docs
Documentation was added to the readme.
- docs(readme): add readme
## 2018-01-28 - 1.0.1 - misc
Initial cleanup and TypeScript support were introduced.
- fix(cleanup):
- feat(ts): initial
## 2016-10-15 - 1.0.0 - no notable changes
This initial release contains no detailed changes.

View File

@ -19,27 +19,48 @@
"error tracking",
"development tools"
],
"main": "dist_ts/index.js",
"typings": "dist_ts/index.d.ts",
"exports": {
".": {
"import": "./dist_ts/index.js"
},
"./context": "./dist_ts_context/index.js",
"./interfaces": "./dist_ts_interfaces/index.js",
"./source-ora": "./dist_ts_source_ora/index.js",
"./destination-clickhouse": "./dist_ts_destination_clickhouse/index.js",
"./destination-devtools": "./dist_ts_destination_devtools/index.js",
"./destination-file": "./dist_ts_destination_file/index.js",
"./destination-local": "./dist_ts_destination_local/index.js",
"./destination-receiver": "./dist_ts_destination_receiver/index.js",
"./receiver": "./dist_ts_receiver/index.js"
},
"author": "Lossless GmbH",
"license": "MIT",
"scripts": {
"test": "(tstest test/)",
"build": "(tsbuild --web && tsbundle npm)",
"build": "(tsbuild tsfolders --allowimplicitany && tsbundle npm)",
"format": "(gitzone format)",
"buildDocs": "tsdoc"
},
"devDependencies": {
"@git.zone/tsbuild": "^2.1.66",
"@git.zone/tsbundle": "^2.0.8",
"@git.zone/tsrun": "^1.2.44",
"@git.zone/tstest": "^1.0.77",
"@push.rocks/tapbundle": "^5.0.23",
"@types/node": "^20.14.2"
"@git.zone/tsbuild": "^2.3.2",
"@git.zone/tsbundle": "^2.2.5",
"@git.zone/tsrun": "^1.3.3",
"@git.zone/tstest": "^1.0.96",
"@push.rocks/tapbundle": "^6.0.3",
"@types/node": "^22.15.17"
},
"dependencies": {
"@api.global/typedrequest-interfaces": "^3.0.19",
"@push.rocks/consolecolor": "^2.0.2",
"@push.rocks/isounique": "^1.0.4",
"@push.rocks/smartlog-interfaces": "^3.0.2"
"@push.rocks/smartclickhouse": "^2.0.17",
"@push.rocks/smartfile": "^11.2.0",
"@push.rocks/smarthash": "^3.0.4",
"@push.rocks/smartpromise": "^4.2.3",
"@push.rocks/smarttime": "^4.1.1",
"@push.rocks/webrequest": "^3.0.37",
"@tsclass/tsclass": "^9.2.0",
"ora": "^8.2.0"
},
"files": [
"ts/**/*",
@ -57,9 +78,16 @@
"last 1 chrome versions"
],
"type": "module",
"homepage": "https://code.foss.global/push.rocks/smartlog",
"homepage": "https://code.foss.global/push.rocks/smartlog#readme",
"repository": {
"type": "git",
"url": "https://code.foss.global/push.rocks/smartlog.git"
},
"packageManager": "pnpm@10.10.0+sha512.d615db246fe70f25dcfea6d8d73dee782ce23e2245e3c4f6f888249fb568149318637dca73c2c5c8ef2a4ca0d5657fb9567188bfab47f566d1ee6ce987815c39",
"bugs": {
"url": "https://code.foss.global/push.rocks/smartlog/issues"
},
"pnpm": {
"overrides": {}
}
}

7164
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -30,8 +30,8 @@ const logger = new Smartlog({
containerName: 'awesome-container',
environment: 'kubernetes-production',
runtime: 'node',
zone: 'zone x'
}
zone: 'zone x',
},
});
```
@ -76,7 +76,11 @@ class MyCustomLogDestination implements ILogDestination {
}
}
const logger = new Smartlog({ logContext: { /* your context */ } });
const logger = new Smartlog({
logContext: {
/* your context */
},
});
logger.addLogDestination(new MyCustomLogDestination());
```

0
readme.plan.md Normal file
View File

9
test/test.context.ts Normal file
View File

@ -0,0 +1,9 @@
import { expect, tap } from '@push.rocks/tapbundle';
import * as smartlogContext from '../ts_context/index.js';
tap.test('should correctly export strings from context module', async () => {
expect(typeof smartlogContext.standardExport).toEqual('string');
expect(smartlogContext.standardExport).toEqual('Hi there! :) This is an exported string');
});
export default tap.start();

View File

@ -0,0 +1,19 @@
import { expect, tap } from '@push.rocks/tapbundle';
import { SmartlogDestinationClickhouse } from '../ts_destination_clickhouse/index.js';
import * as smartclickhouse from '@push.rocks/smartclickhouse';
// Test we can create a destination instance
tap.test('should create a ClickHouse destination instance', async () => {
// Use mock configuration
const clickhouseOptions: smartclickhouse.IClickhouseConstructorOptions = {
url: 'defult:@localhost:8123',
database: 'test_logs'
};
// Verify we can create an instance
// We won't start it to avoid making real connections
const clickhouseDestination = new SmartlogDestinationClickhouse(clickhouseOptions);
expect(clickhouseDestination).toBeTruthy();
});
export default tap.start();

View File

@ -0,0 +1,117 @@
import { expect, tap } from '@push.rocks/tapbundle';
import { SmartlogDestinationDevtools } from '../ts_destination_devtools/index.js';
import * as smartlogInterfaces from '../ts_interfaces/index.js';
let testDestination: SmartlogDestinationDevtools;
let originalConsoleLog: any;
let consoleLogCalls: any[] = [];
// Helper to create log package
const createMockLogPackage = (level: smartlogInterfaces.TLogLevel, message: string): smartlogInterfaces.ILogPackage => {
return {
timestamp: Date.now(),
type: 'log',
level,
message,
context: {
environment: 'test',
runtime: 'chrome'
},
correlation: {
id: '123',
type: 'none'
}
};
};
// Tests
tap.test('should setup test environment', async () => {
// Save original console.log
originalConsoleLog = console.log;
// Replace with mock
console.log = (...args: any[]) => {
consoleLogCalls.push(args);
// Don't call original to avoid polluting test output
};
});
tap.test('should create a devtools destination instance', async () => {
testDestination = new SmartlogDestinationDevtools();
expect(testDestination).toBeTruthy();
});
tap.test('should log error level messages with appropriate styling', async () => {
consoleLogCalls = [];
const logPackage = createMockLogPackage('error', 'Test error message');
await testDestination.handleLog(logPackage);
expect(consoleLogCalls.length).toEqual(1);
expect(consoleLogCalls[0][0]).toContain('Error:');
expect(consoleLogCalls[0][1]).toContain('background:#000000;color:#800000;');
expect(consoleLogCalls[0][2]).toContain('Test error message');
});
tap.test('should log info level messages with appropriate styling', async () => {
consoleLogCalls = [];
const logPackage = createMockLogPackage('info', 'Test info message');
await testDestination.handleLog(logPackage);
expect(consoleLogCalls.length).toEqual(1);
expect(consoleLogCalls[0][0]).toContain('Info:');
expect(consoleLogCalls[0][1]).toContain('background:#EC407A;color:#ffffff;');
expect(consoleLogCalls[0][2]).toContain('Test info message');
});
tap.test('should log ok level messages with appropriate styling', async () => {
consoleLogCalls = [];
const logPackage = createMockLogPackage('ok', 'Test ok message');
await testDestination.handleLog(logPackage);
expect(consoleLogCalls.length).toEqual(1);
expect(consoleLogCalls[0][0]).toContain('OK:');
expect(consoleLogCalls[0][2]).toContain('Test ok message');
});
tap.test('should log success level messages with appropriate styling', async () => {
consoleLogCalls = [];
const logPackage = createMockLogPackage('success', 'Test success message');
await testDestination.handleLog(logPackage);
expect(consoleLogCalls.length).toEqual(1);
expect(consoleLogCalls[0][0]).toContain('Success:');
expect(consoleLogCalls[0][2]).toContain('Test success message');
});
tap.test('should log warn level messages with appropriate styling', async () => {
consoleLogCalls = [];
const logPackage = createMockLogPackage('warn', 'Test warning message');
await testDestination.handleLog(logPackage);
expect(consoleLogCalls.length).toEqual(1);
expect(consoleLogCalls[0][0]).toContain('Warn:');
expect(consoleLogCalls[0][2]).toContain('Test warning message');
});
tap.test('should log note level messages with appropriate styling', async () => {
consoleLogCalls = [];
const logPackage = createMockLogPackage('note', 'Test note message');
await testDestination.handleLog(logPackage);
expect(consoleLogCalls.length).toEqual(1);
expect(consoleLogCalls[0][0]).toContain('Note:');
expect(consoleLogCalls[0][2]).toContain('Test note message');
});
tap.test('should clean up test environment', async () => {
// Restore the original console.log
console.log = originalConsoleLog;
});
export default tap.start();

View File

@ -0,0 +1,10 @@
import { expect, tap } from '@push.rocks/tapbundle';
import { SmartlogDestinationDevtools } from '../ts_destination_devtools/index.js';
// Test we can create a destination instance
tap.test('should create a DevTools destination instance', async () => {
const devtoolsDestination = new SmartlogDestinationDevtools();
expect(devtoolsDestination).toBeTruthy();
});
export default tap.start();

View File

@ -0,0 +1,87 @@
import { expect, tap } from '@push.rocks/tapbundle';
import { SmartlogDestinationFile } from '../ts_destination_file/index.js';
import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';
let testLogDir: string;
let testLogFile: string;
let testDestination: SmartlogDestinationFile;
// Setup and teardown helpers
const createTempLogDir = () => {
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'smartlog-test-'));
return tempDir;
};
const removeTempDir = (dirPath: string) => {
if (fs.existsSync(dirPath)) {
const files = fs.readdirSync(dirPath);
for (const file of files) {
fs.unlinkSync(path.join(dirPath, file));
}
fs.rmdirSync(dirPath);
}
};
// Tests
tap.test('should prepare test environment', async () => {
testLogDir = createTempLogDir();
testLogFile = path.join(testLogDir, 'test.log');
expect(fs.existsSync(testLogDir)).toBeTrue();
});
tap.test('should create a file destination instance with a valid path', async () => {
testDestination = new SmartlogDestinationFile(testLogFile);
expect(testDestination).toBeTruthy();
expect(fs.existsSync(testLogFile)).toBeTrue();
});
tap.test('should throw error when file path is not absolute', async () => {
let errorThrown = false;
try {
new SmartlogDestinationFile('relative/path/file.log');
} catch (error) {
errorThrown = true;
expect(error.message).toContain('filePath needs to be absolute');
}
expect(errorThrown).toBeTrue();
});
tap.test('should write log messages to file', async () => {
const testMessage = 'Test log message';
await testDestination.handleLog({
timestamp: Date.now(),
type: 'log',
level: 'info',
message: testMessage,
context: {
environment: 'test',
runtime: 'node'
},
correlation: {
id: '123',
type: 'none'
}
});
// Give file system a moment to write
await new Promise(resolve => setTimeout(resolve, 50));
const fileContent = fs.readFileSync(testLogFile, 'utf8');
expect(fileContent).toContain(testMessage);
});
tap.test('should clean up test resources', async () => {
// Close file handle before cleanup
testDestination.fileWriteStream.end();
// Small delay to ensure file is properly closed
await new Promise(resolve => setTimeout(resolve, 100));
removeTempDir(testLogDir);
expect(fs.existsSync(testLogDir)).toBeFalse();
});
export default tap.start();

View File

@ -0,0 +1,96 @@
import { expect, tap } from '@push.rocks/tapbundle';
import { DestinationLocal } from '../ts_destination_local/index.js';
import * as smartlogInterfaces from '../ts_interfaces/index.js';
let testDestination: DestinationLocal;
// Mock log package
const createMockLogPackage = (level: smartlogInterfaces.TLogLevel, message: string): smartlogInterfaces.ILogPackage => {
return {
timestamp: Date.now(),
type: 'log',
level,
message,
context: {
environment: 'test',
runtime: 'node'
},
correlation: {
id: '123',
type: 'none'
}
};
};
// Tests
tap.test('should create a local destination instance', async () => {
testDestination = new DestinationLocal();
expect(testDestination).toBeTruthy();
});
tap.test('should handle logs with different levels', async () => {
// Testing with a spy would be ideal, but since we don't have a mocking framework,
// we'll just verify the method runs without errors for different log levels
// Test info level
const logPackageInfo = createMockLogPackage('info', 'Info message');
await testDestination.handleLog(logPackageInfo);
// Test error level
const logPackageError = createMockLogPackage('error', 'Error message');
await testDestination.handleLog(logPackageError);
// Test warn level
const logPackageWarn = createMockLogPackage('warn', 'Warning message');
await testDestination.handleLog(logPackageWarn);
// Test silly level
const logPackageSilly = createMockLogPackage('silly', 'Silly message');
await testDestination.handleLog(logPackageSilly);
});
tap.test('should handle reduced logging', async () => {
testDestination = new DestinationLocal();
// Note: In a real test environment with a mocking framework,
// we would capture console output and verify it's only written
// according to the expected behavior. Here we just ensure
// the methods execute without errors.
// First call with message
testDestination.logReduced('Test message');
// Same message immediately after
testDestination.logReduced('Test message');
// Different message
testDestination.logReduced('Different message');
});
tap.test('should handle repeated logging with repeatEveryTimesArg', async () => {
testDestination = new DestinationLocal();
// First call with message
testDestination.logReduced('Repeated with count', 3);
// Second call
testDestination.logReduced('Repeated with count', 3);
// Third call
testDestination.logReduced('Repeated with count', 3);
// Fourth call (3rd repetition)
testDestination.logReduced('Repeated with count', 3);
});
tap.test('should create new line(s)', async () => {
testDestination = new DestinationLocal();
// Default 1 line
testDestination.newLine();
// Multiple lines
testDestination.newLine(3);
});
export default tap.start();

View File

@ -0,0 +1,72 @@
import { expect, tap } from '@push.rocks/tapbundle';
import { SmartlogDestinationReceiver } from '../ts_destination_receiver/index.js';
import { Smartlog } from '../ts/index.js';
import * as smartlogInterfaces from '../ts_interfaces/index.js';
let testDestination: SmartlogDestinationReceiver;
let testSmartlog: Smartlog;
// Mock log package
const createMockLogPackage = (level: smartlogInterfaces.TLogLevel, message: string): smartlogInterfaces.ILogPackage => {
return {
timestamp: Date.now(),
type: 'log',
level,
message,
context: {
environment: 'test',
runtime: 'node'
},
correlation: {
id: '123',
type: 'none'
}
};
};
// Tests
tap.test('should create a Smartlog instance', async () => {
testSmartlog = new Smartlog({
logContext: {
environment: 'test',
runtime: 'node',
zone: 'test-zone',
company: 'Test Company',
companyunit: 'Test Unit',
containerName: 'test-container',
},
});
expect(testSmartlog).toBeTruthy();
});
tap.test('should create a destination receiver instance with valid options', async () => {
testDestination = new SmartlogDestinationReceiver({
passphrase: 'test-passphrase',
receiverEndpoint: 'https://example.com/logs',
});
expect(testDestination).toBeTruthy();
});
tap.test('should attempt to send logs to the receiver endpoint', async () => {
// Create a mock version of the webrequest.postJson method to avoid actual HTTP calls
const originalPostJson = testDestination['webrequest'].postJson;
testDestination['webrequest'].postJson = async () => {
return {
body: { status: 'ok' },
statusCode: 200
};
};
try {
const logPackage = createMockLogPackage('info', 'Test receiver message');
const result = await testDestination.handleLog(logPackage);
expect(result).toEqual({ status: 'ok' });
} finally {
// Restore the original method
testDestination['webrequest'].postJson = originalPostJson;
}
});
export default tap.start();

115
test/test.receiver.node.ts Normal file
View File

@ -0,0 +1,115 @@
import { expect, tap } from '@push.rocks/tapbundle';
import { SmartlogReceiver } from '../ts_receiver/index.js';
import { Smartlog } from '../ts/index.js';
import * as smartlogInterfaces from '../ts_interfaces/index.js';
import * as smarthash from '@push.rocks/smarthash';
let testSmartlog: Smartlog;
let testReceiver: SmartlogReceiver;
const testPassphrase = 'test-secret-passphrase';
// Helper to create authenticated log package
const createAuthenticatedLogPackage = (
level: smartlogInterfaces.TLogLevel,
message: string
): smartlogInterfaces.ILogPackageAuthenticated => {
const logPackage: smartlogInterfaces.ILogPackage = {
timestamp: Date.now(),
type: 'log',
level,
message,
context: {
environment: 'test',
runtime: 'node'
},
correlation: {
id: '123',
type: 'none'
}
};
return {
auth: smarthash.sha256FromStringSync(testPassphrase),
logPackage
};
};
// Tests
tap.test('should create a Smartlog instance for receiver', async () => {
testSmartlog = new Smartlog({
logContext: {
environment: 'test',
runtime: 'node',
zone: 'test-zone',
company: 'Test Company',
companyunit: 'Test Unit',
containerName: 'test-container',
},
});
expect(testSmartlog).toBeTruthy();
});
tap.test('should create a SmartlogReceiver instance', async () => {
// Create a validator function that always returns true
const validatorFunction = async () => true;
testReceiver = new SmartlogReceiver({
smartlogInstance: testSmartlog,
passphrase: testPassphrase,
validatorFunction
});
expect(testReceiver).toBeTruthy();
expect(testReceiver.passphrase).toEqual(testPassphrase);
});
tap.test('should handle authenticated log with correct passphrase', async () => {
const authLogPackage = createAuthenticatedLogPackage('info', 'Test authenticated message');
const result = await testReceiver.handleAuthenticatedLog(authLogPackage);
expect(result).toBeTruthy();
expect(result.status).toEqual('ok');
});
tap.test('should reject authenticated log with incorrect passphrase', async () => {
const logPackage: smartlogInterfaces.ILogPackage = {
timestamp: Date.now(),
type: 'log',
level: 'info',
message: 'Test unauthorized message',
context: {
environment: 'test',
runtime: 'node'
},
correlation: {
id: '123',
type: 'none'
}
};
const badAuthPackage = {
auth: 'incorrect-hash',
logPackage
};
const result = await testReceiver.handleAuthenticatedLog(badAuthPackage);
expect(result).toBeTruthy();
expect(result.status).toEqual('error');
});
tap.test('should handle many authenticated logs', async () => {
const authLogPackage1 = createAuthenticatedLogPackage('info', 'Test batch message 1');
const authLogPackage2 = createAuthenticatedLogPackage('warn', 'Test batch message 2');
const authLogPackage3 = createAuthenticatedLogPackage('error', 'Test batch message 3');
const authLogPackages = [authLogPackage1, authLogPackage2, authLogPackage3];
await testReceiver.handleManyAuthenticatedLogs(authLogPackages);
// No assertions needed as we're just testing it doesn't throw errors
});
export default tap.start();

View File

@ -0,0 +1,75 @@
import { expect, tap } from '@push.rocks/tapbundle';
import { SmartlogSourceOra } from '../ts_source_ora/index.js';
let testSourceOra: SmartlogSourceOra;
tap.test('should create a SmartlogSourceOra instance', async () => {
testSourceOra = new SmartlogSourceOra();
expect(testSourceOra).toBeTruthy();
expect(testSourceOra.started).toBeFalse();
});
tap.test('should set text and start spinner', async () => {
const testText = 'Testing ora spinner';
testSourceOra.text(testText);
expect(testSourceOra.started).toBeTrue();
expect(testSourceOra.oraInstance.text).toEqual(testText);
});
tap.test('should update text', async () => {
const newText = 'Updated text';
testSourceOra.text(newText);
expect(testSourceOra.oraInstance.text).toEqual(newText);
expect(testSourceOra.started).toBeTrue();
});
tap.test('should stop spinner', async () => {
testSourceOra.stop();
// We can't easily test the visual state, but we can verify it doesn't throw errors
});
tap.test('should finish with success', async () => {
testSourceOra = new SmartlogSourceOra();
testSourceOra.text('Starting again');
const successText = 'Operation successful';
testSourceOra.finishSuccess(successText);
expect(testSourceOra.started).toBeFalse();
});
tap.test('should finish with failure', async () => {
testSourceOra = new SmartlogSourceOra();
testSourceOra.text('Starting again');
const failText = 'Operation failed';
testSourceOra.finishFail(failText);
expect(testSourceOra.started).toBeFalse();
});
tap.test('should handle success and next', async () => {
testSourceOra = new SmartlogSourceOra();
testSourceOra.text('Starting again');
const nextText = 'Next operation';
testSourceOra.successAndNext(nextText);
expect(testSourceOra.started).toBeTrue();
expect(testSourceOra.oraInstance.text).toEqual(nextText);
});
tap.test('should handle fail and next', async () => {
testSourceOra = new SmartlogSourceOra();
testSourceOra.text('Starting again');
const nextText = 'Next operation after failure';
testSourceOra.failAndNext(nextText);
expect(testSourceOra.started).toBeTrue();
expect(testSourceOra.oraInstance.text).toEqual(nextText);
});
export default tap.start();

View File

@ -1,8 +1,8 @@
/**
* autocreated commitinfo by @pushrocks/commitinfo
* autocreated commitinfo by @push.rocks/commitinfo
*/
export const commitinfo = {
name: '@push.rocks/smartlog',
version: '3.0.7',
version: '3.0.8',
description: 'A minimalistic, distributed, and extensible logging tool supporting centralized log management.'
}

View File

@ -8,7 +8,7 @@ export class ConsoleLog {
logLevelArg: plugins.smartlogInterfaces.TLogLevel,
logMessageArg: string,
dataArg?: any,
correlationArg?: plugins.smartlogInterfaces.ILogCorrelation
correlationArg?: plugins.smartlogInterfaces.ILogCorrelation,
) {
console.log(`__# ${logLevelArg}: ${logMessageArg}`);
}

View File

@ -14,7 +14,7 @@ export class LogGroup {
public log(
logLevelArg: plugins.smartlogInterfaces.TLogLevel,
logMessageArg: string,
logDataArg?: any
logDataArg?: any,
) {
this.smartlogRef.log(logLevelArg, logMessageArg, logDataArg, {
id: plugins.isounique.uni(),

View File

@ -10,10 +10,12 @@ export interface ISmartlogContructorOptions {
export class Smartlog implements plugins.smartlogInterfaces.ILogDestination {
// STATIC
public static createForCommitinfo(commitinfo: plugins.smartlogInterfaces.ILogContext['commitinfo']) {
public static createForCommitinfo(
commitinfo: plugins.smartlogInterfaces.ILogContext['commitinfo'],
) {
return new Smartlog({
logContext: {
commitinfo
commitinfo,
},
});
}
@ -95,7 +97,7 @@ export class Smartlog implements plugins.smartlogInterfaces.ILogDestination {
logLevelArg: plugins.smartlogInterfaces.TLogLevel,
logMessageArg: string,
logDataArg?: any,
correlationArg?: plugins.smartlogInterfaces.ILogCorrelation
correlationArg?: plugins.smartlogInterfaces.ILogCorrelation,
) {
correlationArg = {
...{
@ -131,7 +133,7 @@ export class Smartlog implements plugins.smartlogInterfaces.ILogDestination {
correlationArg: plugins.smartlogInterfaces.ILogCorrelation = {
id: plugins.isounique.uni(),
type: 'none',
}
},
) {
if (this.consoleEnabled) {
this.safeConsoleLog(`INCREMENT: ${logLevelArg}: ${logMessageArg}`);
@ -152,7 +154,7 @@ export class Smartlog implements plugins.smartlogInterfaces.ILogDestination {
private safeConsoleLog(logLine: string) {
console.log(
`LOG => ${new Date().getHours()}:${new Date().getMinutes()}:${new Date().getSeconds()} => ${logLine}`
`LOG => ${new Date().getHours()}:${new Date().getMinutes()}:${new Date().getSeconds()} => ${logLine}`,
);
}

View File

@ -1,4 +1,4 @@
import * as isounique from '@push.rocks/isounique';
import * as smartlogInterfaces from '@push.rocks/smartlog-interfaces';
import * as smartlogInterfaces from '../dist_ts_interfaces/index.js';
export { isounique, smartlogInterfaces };

3
ts_context/index.ts Normal file
View File

@ -0,0 +1,3 @@
import * as plugins from './smartlog-context.plugins.js';
export let standardExport = 'Hi there! :) This is an exported string';

View File

@ -0,0 +1,6 @@
// node native scope
import * as path from 'path';
export {
path
}

View File

@ -0,0 +1,8 @@
/**
* autocreated commitinfo by @push.rocks/commitinfo
*/
export const commitinfo = {
name: '@push.rocks/smartlog-destination-clickhouse',
version: '1.0.14',
description: 'A library to integrate Smartlog logging with ClickHouse database for efficient log storage and querying.'
}

View File

@ -0,0 +1,30 @@
import * as plugins from './slclick.plugins.js';
export class SmartlogDestinationClickhouse implements plugins.smartlogInterfaces.ILogDestination {
// STATIC
public static async createAndStart(
optionsArg: plugins.smartclickhouse.IClickhouseConstructorOptions
) {
const destinationClickhouse = new SmartlogDestinationClickhouse(optionsArg);
await destinationClickhouse.start();
return destinationClickhouse;
}
// INSTANCE
private smartclickhouseDb: plugins.smartclickhouse.SmartClickHouseDb;
private logTable: plugins.smartclickhouse.TimeDataTable;
constructor(options: plugins.smartclickhouse.IClickhouseConstructorOptions) {
this.smartclickhouseDb = new plugins.smartclickhouse.SmartClickHouseDb(options);
}
public async start() {
await this.smartclickhouseDb.start();
this.logTable = await this.smartclickhouseDb.getTable('logs');
}
public async handleLog(
logPackage: plugins.smartlogInterfaces.ILogPackage<unknown>
): Promise<void> {
await this.logTable.addData(logPackage);
}
}

View File

@ -0,0 +1,5 @@
// pushrocks scope
import * as smartlogInterfaces from '../dist_ts_interfaces/index.js';
import * as smartclickhouse from '@push.rocks/smartclickhouse';
export { smartlogInterfaces, smartclickhouse };

View File

@ -0,0 +1,8 @@
/**
* autocreated commitinfo by @push.rocks/commitinfo
*/
export const commitinfo = {
name: '@push.rocks/smartlog-destination-devtools',
version: '1.0.12',
description: 'A library enabling enhanced logging in browser development tools.'
}

View File

@ -0,0 +1,58 @@
import * as plugins from './plugins.js';
import type { ILogDestination, ILogPackage } from '../dist_ts_interfaces/index.js';
export class SmartlogDestinationDevtools implements ILogDestination {
public async handleLog(logPackageArg: ILogPackage) {
await this.logInBrowser(logPackageArg);
}
private async logInBrowser(logPackage: ILogPackage) {
switch (logPackage.level) {
case 'error':
console.log(
`%c Error: %c ${logPackage.message}`,
'background:#000000;color:#800000;',
'color:#000000;'
);
break;
case 'info':
console.log(
`%c Info: %c ${logPackage.message}`,
'background:#EC407A;color:#ffffff;',
'color:#EC407A;'
);
break;
case 'ok':
console.log(
`%c OK: %c ${logPackage.message}`,
'background:#000000;color:#8BC34A;',
'color:#000000;'
);
break;
case 'success':
console.log(
`%c Success: %c ${logPackage.message}`,
'background:#8BC34A;color:#ffffff;',
'color:#8BC34A;'
);
break;
case 'warn':
console.log(
`%c Warn: %c ${logPackage.message}`,
'background:#000000;color:#FB8C00;',
'color:#000000;'
);
break;
case 'note':
console.log(
`%c Note: %c ${logPackage.message}`,
'background:#42A5F5;color:#ffffff',
'color:#42A5F5;'
);
break;
default:
console.log(`unknown logType for "${logPackage.message}"`);
break;
}
}
}

View File

@ -0,0 +1,2 @@
import * as smartlogInterfaces from '../dist_ts_interfaces/index.js';
export { smartlogInterfaces };

View File

@ -0,0 +1,23 @@
import * as plugins from './smartfile-destination-file.plugins.js';
export class SmartlogDestinationFile implements plugins.smartlogInterfaces.ILogDestination {
public fileWriteStream: plugins.fs.WriteStream;
public async handleLog(logPackageArg: plugins.smartlogInterfaces.ILogPackage) {
this.fileWriteStream.write(`${new plugins.smarttime.ExtendedDate(Date.now()).toISOString()}: ${logPackageArg.message} \n`);
}
constructor(filePathArg: string) {
const extendedDate = new plugins.smarttime.ExtendedDate(Date.now());
if (!plugins.path.isAbsolute(filePathArg)) {
throw new Error(`filePath needs to be absolute but is not: "${filePathArg}"`);
}
plugins.smartfile.fs.ensureFileSync(filePathArg, `# Smartlogfile. Created at ${extendedDate.toISOString()}\n`);
this.fileWriteStream = plugins.fs.createWriteStream(
filePathArg,
{
flags: 'a+',
}
);
}
}

View File

@ -0,0 +1,19 @@
// node native scope
import * as fs from 'fs';
import * as path from 'path';
export {
fs,
path
};
// pushrocks scope
import * as smartfile from '@push.rocks/smartfile';
import * as smartlogInterfaces from '../dist_ts_interfaces/index.js';
import * as smarttime from '@push.rocks/smarttime';
export {
smartfile,
smartlogInterfaces,
smarttime
};

View File

@ -0,0 +1,8 @@
/**
* autocreated commitinfo by @push.rocks/commitinfo
*/
export const commitinfo = {
name: '@push.rocks/smartlog-destination-local',
version: '9.0.2',
description: 'a smartlog destination targeting the local console'
}

View File

@ -0,0 +1,135 @@
import * as plugins from './plugins.js';
import type { ILogDestination, ILogPackage, TLogLevel } from '../dist_ts_interfaces/index.js';
// other beautylog classes
import { type TColorName } from '@push.rocks/consolecolor';
export class DestinationLocal implements ILogDestination {
/**
* handles a log according to the smartlog standard
* @param logPackage
*/
public async handleLog(logPackage: ILogPackage) {
this.logToConsole(logPackage);
}
/**
* creates a new empty line
* @param linesArg
* @returns void
*/
public newLine(linesArg: number = 1) {
for (let i = 0; i < linesArg; i++) {
console.log('\n');
}
}
/**
* logs a reduced log that only logs changes of consequential log messages
*/
public logReduced(logTextArg: string, repeatEveryTimesArg: number = 0) {
if (
logTextArg === this.previousMessage &&
(repeatEveryTimesArg === 0 || this.sameMessageCounter !== repeatEveryTimesArg)
) {
this.sameMessageCounter++;
} else {
this.sameMessageCounter = 0;
this.previousMessage = logTextArg;
this.logToConsole({
timestamp: Date.now(),
type: 'log',
level: 'info',
context: {
company: 'undefined',
companyunit: 'undefined',
containerName: 'undefined',
environment: 'test',
runtime: 'node',
zone: 'undefined',
},
message: logTextArg,
correlation: {
id: 'none',
type: 'none',
},
});
}
}
private previousMessage: string = '';
private sameMessageCounter: number = 0;
// default logging
private logToConsole(logPackageArg: ILogPackage) {
let logString: string;
try {
logString =
this.localBl[logPackageArg.level].prefix +
plugins.consolecolor.coloredString(
logPackageArg.message,
this.localBl[logPackageArg.level].textColor
);
console.log(logString);
return true;
} catch (error) {
console.log(
this.localBl.errorPrefix + 'You seem to have tried logging something strange' + error
);
return false;
}
}
private localBl: {
[key: string]: {
prefix: string;
textColor: TColorName;
};
} = {
silly: {
prefix: plugins.consolecolor.coloredString(' silly ', 'white', 'blue') + ' ',
textColor: 'blue',
},
error: {
prefix:
plugins.consolecolor.coloredString(' ', 'red', 'red') +
plugins.consolecolor.coloredString(' ERROR! ', 'red', 'black') +
' ',
textColor: 'red',
},
info: {
prefix:
plugins.consolecolor.coloredString(' ', 'blue', 'blue') +
plugins.consolecolor.coloredString(' info: ', 'blue', 'black') +
' ',
textColor: 'white',
},
note: {
prefix:
plugins.consolecolor.coloredString(' ', 'pink', 'pink') +
plugins.consolecolor.coloredString(' note -> ', 'pink', 'black') +
' ',
textColor: 'pink',
},
ok: {
prefix:
plugins.consolecolor.coloredString(' ', 'green', 'green') +
plugins.consolecolor.coloredString(' ok ', 'green', 'black') +
' ',
textColor: 'green',
},
success: {
prefix:
plugins.consolecolor.coloredString(' ', 'green', 'green') +
plugins.consolecolor.coloredString(' SUCCESS! ', 'green', 'black') +
' ',
textColor: 'green',
},
warn: {
prefix:
plugins.consolecolor.coloredString(' ', 'orange', 'orange') +
plugins.consolecolor.coloredString(' WARN -> ', 'orange', 'black') +
' ',
textColor: 'orange',
},
};
}

View File

@ -0,0 +1,2 @@
// export classes
export { DestinationLocal } from './classes.destinationlocal.js';

View File

@ -0,0 +1,5 @@
import * as consolecolor from '@push.rocks/consolecolor';
import * as smartlogInterfaces from '../dist_ts_interfaces/index.js';
import * as smartpromise from '@push.rocks/smartpromise';
export { consolecolor, smartlogInterfaces, smartpromise };

View File

@ -0,0 +1,8 @@
/**
* autocreated commitinfo by @push.rocks/commitinfo
*/
export const commitinfo = {
name: '@push.rocks/smartlog-destination-receiver',
version: '2.0.6',
description: 'A package providing a destination handler for smartlog logging packages'
}

View File

@ -0,0 +1,35 @@
import * as plugins from './smartlog-destination-receiver.plugins.js';
import {
type ILogDestination,
type ILogPackageAuthenticated,
type ILogPackage,
} from '../dist_ts_interfaces/index.js';
export interface ISmartlogDestinationReceiverConstructorOptions {
passphrase: string;
receiverEndpoint: string;
}
export class SmartlogDestinationReceiver implements ILogDestination {
private options: ISmartlogDestinationReceiverConstructorOptions;
private webrequest = new plugins.webrequest.WebRequest();
constructor(optionsArg: ISmartlogDestinationReceiverConstructorOptions) {
this.options = optionsArg;
}
private errorCounter = 0;
public async handleLog(logPackageArg: ILogPackage) {
const response = await this.webrequest.postJson(this.options.receiverEndpoint, {
auth: plugins.smarthash.sha256FromStringSync(this.options.passphrase),
logPackage: logPackageArg,
}).catch(err => {
if (this.errorCounter % 100 === 0) {
console.error(`There seems to be an error with logging.`);
console.error(`Accumulated ${this.errorCounter} errors so far`)
}
this.errorCounter++;
});
return response.body;
}
}

View File

@ -0,0 +1,5 @@
import * as smarthash from '@push.rocks/smarthash';
import * as smartlogInterfaces from '../dist_ts_interfaces/index.js';
import * as webrequest from '@push.rocks/webrequest';
export { smarthash, smartlogInterfaces, webrequest };

View File

@ -0,0 +1,8 @@
/**
* autocreated commitinfo by @push.rocks/commitinfo
*/
export const commitinfo = {
name: '@push.rocks/smartlog-interfaces',
version: '3.0.2',
description: 'Defines interfaces for the smartlog ecosystem.'
}

126
ts_interfaces/index.ts Normal file
View File

@ -0,0 +1,126 @@
import * as plugins from './smartlog-interfaces.plugins.js';
import * as requestInterfaces from './smartlog-interfaces.requests.js';
export { requestInterfaces as request };
/**
* the different available log types
*/
export type TLogType =
| 'log'
| 'increment'
| 'gauge'
| 'error'
| 'success'
| 'value'
| 'finance'
| 'compliance';
/**
* the available log levels
*/
export type TLogLevel =
| 'silly'
| 'info'
| 'debug'
| 'note'
| 'ok'
| 'success'
| 'warn'
| 'error'
| 'lifecycle';
/**
* the available environments
*/
export type TEnvironment = 'local' | 'test' | 'staging' | 'production';
/**
* the available runtimes
*/
export type TRuntime = 'node' | 'chrome' | 'rust' | 'deno' | 'cloudflare_workers';
/**
* the log context e.g. what app in what version on what server
*/
export interface ILogContext {
commitinfo?: plugins.tsclass.code.ICommitInfo;
company?: string;
companyunit?: string;
containerName?: string;
environment?: TEnvironment;
runtime?: TRuntime;
zone?: string;
}
export interface ILogCorrelation {
/**
* a unique id for this log
*/
id: string;
/**
* the type of this log
*/
type: 'none' | 'service' | 'build' | 'infrastructure' | 'cdn';
/**
* the instance on which the log is created
* use it for pinning logs to a certain instance in a cluster
*/
instance?: string;
/**
* a series of logs
*/
group?: string;
/**
* a log that belongs to a transaction. E.g. a Payment or a request traveling through multiple backend instances
*/
transaction?: string;
}
/**
* the main logpackage
*/
export interface ILogPackage<T = unknown> {
/**
* a unix timestamp in milliseconds
*/
timestamp: number;
type: TLogType;
context: ILogContext;
level: TLogLevel;
/**
* allows grouping of log messages
*/
correlation: ILogCorrelation;
/**
* the message to log
*/
message: string;
data?: T;
}
export interface ILogPackageDataRequest {
requestCorrelationId: string;
url: string;
pathname: string;
method: string;
status: string;
}
export interface ILogPackageAuthenticated {
auth: string;
logPackage: ILogPackage;
}
export interface ILogPackageArrayAuthenticated {
auth: string;
logPackages: ILogPackage[];
}
/**
* a destination interface for extending smartlog modules
*/
export interface ILogDestination {
handleLog: (logPackage: ILogPackage) => Promise<void>;
}

View File

@ -0,0 +1,10 @@
import * as typedrequestInterfaces from '@api.global/typedrequest-interfaces';
export { typedrequestInterfaces };
// tsclass scope
import * as tsclass from '@tsclass/tsclass';
export {
tsclass
}

View File

@ -0,0 +1,9 @@
import { type ILogPackageAuthenticated } from './index.js';
export interface IRequest_SmartlogDestinationReceiver_Any_PostLogPackages {
method: 'postLogPackages';
request: {
logPackages: ILogPackageAuthenticated[];
};
response: {};
}

View File

@ -0,0 +1,8 @@
/**
* autocreated commitinfo by @push.rocks/commitinfo
*/
export const commitinfo = {
name: '@push.rocks/smartlog-receiver',
version: '2.0.0',
description: 'a receiver for smartlog-destination-receiver'
}

1
ts_receiver/index.ts Normal file
View File

@ -0,0 +1 @@
export * from './sl.classes.smartlogreceiver.js';

View File

@ -0,0 +1,73 @@
import * as plugins from './sl.receiver.plugins.js';
import type {
ILogPackage,
ILogPackageAuthenticated,
ILogDestination,
} from '../dist_ts_interfaces/index.js';
export type TValidatorFunction = (logPackage: ILogPackage) => Promise<boolean>;
export interface ISmartlogReceiverOptions {
smartlogInstance: plugins.smartlog.Smartlog;
passphrase: string;
validatorFunction: TValidatorFunction;
}
/**
* a class that receives smartlog packages
*/
export class SmartlogReceiver {
public passphrase: string;
public validatorFunction: TValidatorFunction;
public smartlogInstance: plugins.smartlog.Smartlog;
constructor(smartlogReceiverOptions: ISmartlogReceiverOptions) {
this.passphrase = smartlogReceiverOptions.passphrase;
this.validatorFunction =
smartlogReceiverOptions.validatorFunction ||
(async (logpackageArg) => {
return true;
});
this.smartlogInstance = smartlogReceiverOptions.smartlogInstance;
}
/**
* handles a authenticated log
*/
public async handleAuthenticatedLog(authenticatedLogPackageArg: ILogPackageAuthenticated) {
const authString = authenticatedLogPackageArg.auth;
const logPackage = authenticatedLogPackageArg.logPackage;
if (
authString === plugins.smarthash.sha256FromStringSync(this.passphrase) &&
(await this.validatorFunction(logPackage))
) {
// Message authenticated lets clean up.
logPackage.correlation ? null : (logPackage.correlation = { id: '123', type: 'none' });
logPackage.correlation.id ? null : (logPackage.correlation.id = '123');
logPackage.correlation.type ? null : (logPackage.correlation.type = 'none');
this.smartlogInstance.handleLog(logPackage);
return { status: 'ok' };
} else {
this.smartlogInstance.log('error', 'Message rejected because of bad passphrase');
return { status: 'error' };
// console.log(plugins.smarthash.sha256FromStringSync(this.passphrase));
}
}
/**
* handles an array of authenticated logs
* @param authenticatedLogsPackageArrayArg
*/
public async handleManyAuthenticatedLogs(
authenticatedLogsPackageArrayArg: ILogPackageAuthenticated[]
) {
const promiseArray: Array<Promise<any>> = [];
for (const logPackage of authenticatedLogsPackageArrayArg) {
promiseArray.push(this.handleAuthenticatedLog(logPackage));
}
await Promise.all(promiseArray);
}
}

View File

@ -0,0 +1,4 @@
import * as smarthash from '@push.rocks/smarthash';
import * as smartlog from '../dist_ts/index.js';
export { smartlog, smarthash };

40
ts_source_ora/index.ts Normal file
View File

@ -0,0 +1,40 @@
import * as plugins from './smartlog-source-ora.plugins.js';
export class SmartlogSourceOra {
public oraInstance = plugins.ora('loading');
public started = false;
constructor() {}
public text(textArg: string) {
this.oraInstance.text = textArg;
if (!this.started) {
this.started = true;
this.oraInstance.start();
}
}
public stop() {
this.oraInstance.stop();
}
public finishSuccess(textArg?: string) {
this.oraInstance.succeed(textArg);
this.started = false;
}
public finishFail(textArg?: string) {
this.oraInstance.fail(textArg);
this.started = false;
}
public successAndNext(textArg: string) {
this.finishSuccess();
this.text(textArg);
}
public failAndNext(textArg: string) {
this.finishFail();
this.text(textArg);
}
}

View File

@ -0,0 +1,9 @@
// pushrocks scope
import * as smartlogInterfaces from '../dist_ts_interfaces/index.js';
export { smartlogInterfaces };
// third party scope
import ora from 'ora';
export { ora };

View File

@ -6,7 +6,9 @@
"module": "NodeNext",
"moduleResolution": "NodeNext",
"esModuleInterop": true,
"verbatimModuleSyntax": true
"verbatimModuleSyntax": true,
"baseUrl": ".",
"paths": {}
},
"exclude": [
"dist_*/**/*.d.ts"