Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# These are supported funding model platforms

github: [kevinelliott]
patreon: Airframes
patreon: Airframes
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
Expand Down
12 changes: 6 additions & 6 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
- package-ecosystem: 'github-actions'
directory: '/'
schedule:
interval: "weekly"
- package-ecosystem: "npm"
directory: "/"
interval: 'weekly'
- package-ecosystem: 'npm'
directory: '/'
schedule:
interval: "weekly"
interval: 'weekly'
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
id: scan
uses: anchore/scan-action@v7
with:
path: "."
path: '.'
- name: upload Anchore scan SARIF report
uses: github/codeql-action/upload-sarif@v4
with:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ on:
types: [published]

permissions:
id-token: write # Required for OIDC
contents: read
id-token: write # Required for OIDC
contents: read

jobs:
build:
Expand Down
6 changes: 6 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "all"
}
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
- TypeScript development uses the latest stable Node types (currently v24) without forcing consumers to use a specific Node types version, since `@types/node` is a devDependency.
- The published builds are compiled targeting Node 18 runtime via `tsup` so they remain compatible across supported Node versions.


# @airframes/acars-decoder

This is a no-op documentation tweak to verify repository access, build/lint, tests, and PR workflow. No functional code changes are included.

# acars-decoder-typescript

[![NPM Version](https://badge.fury.io/js/@airframes%2Facars-decoder.svg)](https://badge.fury.io/js/@airframes%2Facars-decoder)
Expand All @@ -32,11 +32,13 @@ You are welcome to contribute (please see https://github.com/airframesio/acars-m
Add the `@airframes/acars-decoder` library to your JavaScript or TypeScript project.

With `yarn`:

```
yarn add @airframes/acars-decoder
```

With `npm`:

```
npm install @airframes/acars-decoder
```
Expand All @@ -51,8 +53,8 @@ Contributions are welcome! Please follow the [ACARS Message Documentation](https

# Contributors

| Contributor | Description |
| ----------- | ----------- |
| [Kevin Elliott](https://github.com/kevinelliott) | Primary Airframes contributor |
| [Michael Johnson](https://github.com/johnsom) | Decoder plugins, testing framework |
| [Mark Bumiller](https://github.com/makrsmark) | Decoder plugins, tests, utilities |
| Contributor | Description |
| ------------------------------------------------ | ---------------------------------- |
| [Kevin Elliott](https://github.com/kevinelliott) | Primary Airframes contributor |
| [Michael Johnson](https://github.com/johnsom) | Decoder plugins, testing framework |
| [Mark Bumiller](https://github.com/makrsmark) | Decoder plugins, tests, utilities |
2 changes: 1 addition & 1 deletion babel.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module.exports = {
presets: [
['@babel/preset-env', {targets: {node: 'current'}}],
['@babel/preset-env', { targets: { node: 'current' } }],
'@babel/preset-typescript',
],
};
42 changes: 42 additions & 0 deletions eslint.config.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import tseslint from '@typescript-eslint/eslint-plugin';
import tsparser from '@typescript-eslint/parser';
import prettierPlugin from 'eslint-plugin-prettier';
import prettierConfig from 'eslint-config-prettier';
import importPlugin from 'eslint-plugin-import';
import stylistic from '@stylistic/eslint-plugin';

export default [
{
files: ['**/*.ts'],

languageOptions: {
parser: tsparser,
sourceType: 'module',
},

plugins: {
'@typescript-eslint': tseslint,
prettier: prettierPlugin,
import: importPlugin,
'@stylistic': stylistic
},

rules: {
...tseslint.configs.recommended.rules,
...prettierConfig.rules,
'@typescript-eslint/no-unused-vars': 'warn',
'no-console': 'warn',
semi: ['error', 'always'],
'@stylistic/indent': ['error', 2],
'prettier/prettier': 'error',
'import/no-cycle': [
'error',
{
maxDepth: Infinity,
ignoreExternal: true,
allowUnsafeDynamicCyclicDependency: false,
},
],
},
},
];
4 changes: 2 additions & 2 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ export default {
// collectCoverageFrom: undefined,

// The directory where Jest should output its coverage files
coverageDirectory: "coverage",
coverageDirectory: 'coverage',

// An array of regexp pattern strings used to skip coverage collection
// coveragePathIgnorePatterns: [
// "/node_modules/"
// ],

// Indicates which provider should be used to instrument code for coverage
coverageProvider: "v8",
coverageProvider: 'v8',

// A list of reporter names that Jest uses when writing coverage reports
// coverageReporters: [
Expand Down
43 changes: 27 additions & 16 deletions lib/DateTimeUtils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export class DateTimeUtils {

// Expects a four digit UTC time string (HHMM)
public static UTCToString(UTCString: string) {
let utcDate = new Date();
Expand All @@ -17,31 +16,39 @@ export class DateTimeUtils {
utcDate.setUTCFullYear(2000 + +dateString.substr(4, 2));
}
if (timeString.length === 6) {
utcDate.setUTCHours(+timeString.substr(0, 2), +timeString.substr(2, 2), +timeString.substr(4, 2));
utcDate.setUTCHours(
+timeString.substr(0, 2),
+timeString.substr(2, 2),
+timeString.substr(4, 2),
);
} else {
utcDate.setUTCHours(+timeString.substr(0, 2), +timeString.substr(2, 2), 0);
utcDate.setUTCHours(
+timeString.substr(0, 2),
+timeString.substr(2, 2),
0,
);
}
return utcDate.toUTCString();
}

/**
*
*
* @param time HHMMSS or HHMM
* @returns seconds since midnight
*/
public static convertHHMMSSToTod(time: string): number {
if(time.length === 4) {
if (time.length === 4) {
time += '00';
}
const h = Number(time.substring(0, 2));
const m = Number(time.substring(2, 4));
const s = Number(time.substring(4, 6));
const tod = (h * 3600) + (m * 60) + s;
const tod = h * 3600 + m * 60 + s;
return tod;
}

/**
*
*
* @param time HHMMSS
* @param date MMDDYY or MMDDYYYY
* @returns seconds since epoch
Expand All @@ -51,25 +58,29 @@ export class DateTimeUtils {
if (date.length === 6) {
date = date.substring(0, 4) + `20${date.substring(4, 6)}`;
}
const timestamp = `${date.substring(4, 8)}-${date.substring(0, 2)}-${date.substring(2, 4)}T${time.substring(0, 2)}:${time.substring(2, 4)}:${time.substring(4, 6)}.000Z`
const timestamp = `${date.substring(4, 8)}-${date.substring(0, 2)}-${date.substring(2, 4)}T${time.substring(0, 2)}:${time.substring(2, 4)}:${time.substring(4, 6)}.000Z`;
const millis = Date.parse(timestamp);
return millis / 1000;
}

/**
* Converts a timestamp to a string
*
*
* ISO-8601 format for 'epoch'
* HH:MM:SS for 'tod'
* @param time
* @param format
* @returns
* @param time
* @param format
* @returns
*/
public static timestampToString(time: number, format: 'tod' | 'epoch'): string {
const date = new Date(time * 1000); if (format == 'tod') {
public static timestampToString(
time: number,
format: 'tod' | 'epoch',
): string {
const date = new Date(time * 1000);
if (format == 'tod') {
return date.toISOString().slice(11, 19);
}
//strip off millis
return date.toISOString().slice(0, -5) + "Z";
return date.toISOString().slice(0, -5) + 'Z';
}
}
}
61 changes: 34 additions & 27 deletions lib/DecoderPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { DecodeResult, DecoderPluginInterface, Message, Options } from './DecoderPluginInterface';
import {
DecodeResult,
DecoderPluginInterface,
Message,
Options,
Qualifiers,
} from './DecoderPluginInterface';
import { MessageDecoder } from './MessageDecoder';

export abstract class DecoderPlugin implements DecoderPluginInterface {
Expand All @@ -7,54 +13,55 @@ export abstract class DecoderPlugin implements DecoderPluginInterface {
name: string = 'unknown';

defaultResult(): DecodeResult {
return {
decoded: false,
decoder: {
name: 'unknown',
type: 'pattern-match',
decodeLevel: 'none',
},
formatted: {
description: 'Unknown',
items: [],
},
raw: {},
remaining: {},
};
};

options: Object;

constructor(decoder : MessageDecoder, options : Options = {}) {
return {
decoded: false,
decoder: {
name: 'unknown',
type: 'pattern-match',
decodeLevel: 'none',
},
formatted: {
description: 'Unknown',
items: [],
},
raw: {},
remaining: {},
};
}

options: object;

constructor(decoder: MessageDecoder, options: Options = {}) {
this.decoder = decoder;
this.options = options;
}

id() : string { // eslint-disable-line class-methods-use-this
console.log('DecoderPlugin subclass has not overriden id() to provide a unique ID for this plugin!');
id(): string {
console.log(
'DecoderPlugin subclass has not overriden id() to provide a unique ID for this plugin!',
);
return 'abstract_decoder_plugin';
}

meetsStateRequirements() : boolean { // eslint-disable-line class-methods-use-this
meetsStateRequirements(): boolean {
return true;
}

// onRegister(store: Store<any>) {
// this.store = store;
// }

qualifiers() : any { // eslint-disable-line class-methods-use-this
const labels : Array<string> = [];
qualifiers(): Qualifiers {
const labels: Array<string> = [];

return {
labels,
};
}

decode(message: Message) : DecodeResult { // eslint-disable-line class-methods-use-this
decode(message: Message): DecodeResult {
const decodeResult = this.defaultResult();
decodeResult.remaining.text = message.text;
return decodeResult;
}
}

Loading