Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
126 commits
Select commit Hold shift + click to select a range
b692d74
docs: fix little typo in package.json
mountaindude Oct 21, 2025
b7cd020
chore: update Node.js version requirements to 20.10.0
mountaindude Oct 21, 2025
5fff1a0
chore(deps): do minor dep updates
mountaindude Oct 21, 2025
3672d3f
chore(deps): do major dep updates
mountaindude Oct 21, 2025
cc3c05e
test: Add code coverage to test runs
mountaindude Oct 21, 2025
90e0e68
chore: Add GitHub Copilot instructions for qvd4js
mountaindude Oct 21, 2025
8020818
Initial plan
Copilot Oct 21, 2025
e8ab135
Implement metadata exposure and modification for QVD files
Copilot Oct 21, 2025
35cfbb2
Add comprehensive documentation for metadata features
Copilot Oct 21, 2025
cb8fb62
Merge pull request #2 from mountaindude/copilot/expose-file-field-met…
mountaindude Oct 21, 2025
cadacc3
Initial plan
Copilot Oct 21, 2025
79e91ed
Split qvd.js into smaller, more manageable files
Copilot Oct 21, 2025
3de2b06
Add comprehensive backwards compatibility test
Copilot Oct 21, 2025
ecef670
refactor: Split qvd.js into smaller, more manageable files
mountaindude Oct 21, 2025
018d77d
Merge pull request #15 from mountaindude/copilot/split-qvd-js-into-sm…
mountaindude Oct 21, 2025
640e2ee
Initial plan
Copilot Oct 21, 2025
17659ff
Add custom error classes with comprehensive tests
Copilot Oct 21, 2025
fce5785
feat: Add better error handling when working with QVD files
mountaindude Oct 21, 2025
009f661
Merge pull request #16 from mountaindude/copilot/add-custom-error-cla…
mountaindude Oct 21, 2025
4f3b871
Initial plan
Copilot Oct 21, 2025
2a84581
docs: add Conventional Commits guidelines to Copilot instructions
Copilot Oct 21, 2025
1cd984f
Merge pull request #18 from mountaindude/copilot/setup-copilot-instru…
mountaindude Oct 21, 2025
4138d92
Initial plan
Copilot Oct 21, 2025
ed52e84
feat: add comprehensive input validation to QvdDataFrame methods
Copilot Oct 21, 2025
5434b70
Merge pull request #19 from mountaindude/copilot/add-input-validation…
mountaindude Oct 21, 2025
f8f201d
docs: add contributors section to README and package.json
mountaindude Oct 21, 2025
9342225
Merge pull request #20 from mountaindude/copilot/add-input-validation…
mountaindude Oct 21, 2025
ae14365
Initial plan
Copilot Oct 21, 2025
1c5952f
feat: implement lazy loading with maxRows parameter for QVD files
Copilot Oct 21, 2025
018bd7f
Improve formatting in QvdFileReader methods
mountaindude Oct 21, 2025
2f4842c
feat: implement true lazy loading from disk with maxRows parameter
Copilot Oct 21, 2025
00dbf0a
feat: enhance lazy loading in QvdFileReader to use streaming for head…
mountaindude Oct 21, 2025
5f9b1fe
Merge pull request #21 from mountaindude/copilot/implement-lazy-loadi…
mountaindude Oct 21, 2025
b75e2f9
docs: add note on xml2js protection against XXE attacks in QvdFileReader
mountaindude Oct 22, 2025
54825c3
Initial plan
Copilot Oct 22, 2025
ef1d459
feat: add path traversal protection for QVD file operations
Copilot Oct 22, 2025
5fa3295
docs: add comprehensive security documentation for path validation
Copilot Oct 22, 2025
99cdaec
Initial plan
Copilot Oct 22, 2025
ec1bc01
docs: add comprehensive multi-platform test solution design
Copilot Oct 22, 2025
8db059f
docs: add testing summary and integrate with main README
Copilot Oct 22, 2025
84863da
feat: add path traversal protection
mountaindude Oct 22, 2025
1b6ea22
Merge pull request #23 from mountaindude/copilot/add-input-validation…
mountaindude Oct 22, 2025
2c536f2
docs: add deliverables summary document
Copilot Oct 22, 2025
316aa0e
Initial plan
Copilot Oct 22, 2025
4db8f04
docs: finalize documentation structure and navigation
Copilot Oct 22, 2025
75f6874
feat: add comprehensive buffer bounds checking to prevent overflow vu…
Copilot Oct 22, 2025
e32b376
enhance test execution flow with Node.js version support for self-hos…
mountaindude Oct 22, 2025
ce3096e
improve formatting and clarity in Multi-Platform Test Solution Design…
mountaindude Oct 22, 2025
1e1ab14
enhance validation for QVD file parsing to prevent corruption errors
mountaindude Oct 22, 2025
2755a33
Merge pull request #27 from mountaindude/copilot/add-buffer-bounds-ch…
mountaindude Oct 22, 2025
17cef8c
Initial plan
Copilot Oct 22, 2025
90e95bb
update Node.js version strategy and expand test matrix for compatibility
mountaindude Oct 22, 2025
6ea17d7
fix: correct null check in _parseHeader() to handle valid index 0
Copilot Oct 22, 2025
672938a
ci: add GitHub Actions workflows for multi-platform testing
Copilot Oct 22, 2025
b807c4c
docs: add explanatory comment for indexOf check in _parseHeader()
Copilot Oct 22, 2025
040580e
Merge pull request #28 from mountaindude/copilot/fix-null-check-in-pa…
mountaindude Oct 22, 2025
f2756e1
Initial plan
Copilot Oct 22, 2025
deea450
fix: correct falsy value handling in QvdSymbol.toByteRepresentation()…
Copilot Oct 22, 2025
3f17375
Initial plan
Copilot Oct 22, 2025
4199b7c
Merge pull request #30 from mountaindude/copilot/fix-tobyterepresenta…
mountaindude Oct 22, 2025
2210063
Initial plan
Copilot Oct 22, 2025
fef1ac2
fix: properly close file descriptor in _readData() with try-finally
Copilot Oct 22, 2025
b93b033
fix: ensure path validation works on Windows, macOS, and Linux
Copilot Oct 22, 2025
7fc226c
Merge pull request #32 from mountaindude/copilot/fix-resource-leak-in…
mountaindude Oct 22, 2025
0f1468e
Initial plan
Copilot Oct 22, 2025
49643d3
perf: replace synchronous file operations with async in _writeData()
Copilot Oct 22, 2025
7a1f621
test: robust platform mocking using Object.defineProperty with restor…
mountaindude Oct 22, 2025
98cf076
test: enhance Windows path validation with drive-letter and UNC path …
mountaindude Oct 22, 2025
d3a3081
Merge pull request #31 from mountaindude/copilot/analyze-file-path-co…
mountaindude Oct 22, 2025
9e3b01c
Merge pull request #33 from mountaindude/copilot/optimize-write-data-…
mountaindude Oct 22, 2025
7f900e1
refactor: update multi-platform test workflow to support additional N…
mountaindude Oct 22, 2025
5e73589
Merge pull request #26 from mountaindude/copilot/design-multi-platfor…
mountaindude Oct 22, 2025
bdb8866
refactor: update Eslint config to v9, update tests accordingly
mountaindude Oct 22, 2025
80d60d3
Merge pull request #34 from ptarmiganlabs/actions
mountaindude Oct 22, 2025
62c1819
refactor: restrict branches for push events to main only
mountaindude Oct 22, 2025
23eb3f2
Merge pull request #35 from ptarmiganlabs/actions
mountaindude Oct 22, 2025
1b64fd5
fix: Make test GH Actions workflow work on Windows too
mountaindude Oct 22, 2025
60a034f
Merge pull request #36 from ptarmiganlabs/actions
mountaindude Oct 22, 2025
44bd957
refactor: reduce retention days for build artifacts and clarify shell…
mountaindude Oct 22, 2025
0f1712c
Merge pull request #37 from ptarmiganlabs/actions
mountaindude Oct 22, 2025
12e7119
Initial plan
Copilot Oct 22, 2025
5b47090
test: remove flaky timing assertions from test files
Copilot Oct 22, 2025
a989987
feat: add tinybench-based benchmark suite for performance tracking
Copilot Oct 22, 2025
a565ece
ci: add GitHub Actions workflow for performance benchmarking across p…
Copilot Oct 22, 2025
e466689
feat: integrate benchmark tracking and GitHub Pages setup for perform…
mountaindude Oct 22, 2025
0ee9ca5
Merge branch 'copilot/replace-flaky-timing-tests' of https://github.c…
mountaindude Oct 22, 2025
76d2218
feat: enhance performance benchmarking configuration in GitHub Actions
mountaindude Oct 22, 2025
4869a6f
Merge pull request #38 from ptarmiganlabs/copilot/replace-flaky-timin…
mountaindude Oct 22, 2025
e15d34f
refactor: remove performance benchmarks from workflows and update ben…
mountaindude Oct 22, 2025
7b4233f
Merge pull request #39 from ptarmiganlabs/copilot/replace-flaky-timin…
mountaindude Oct 22, 2025
6212f72
feat: add workflow to create and update benchmark overview page
mountaindude Oct 22, 2025
84b76da
Merge pull request #40 from ptarmiganlabs/copilot/replace-flaky-timin…
mountaindude Oct 22, 2025
a01f902
fix: update build script to use npx for babel command
mountaindude Oct 22, 2025
150a5c3
feat: update benchmark workflow to upload results as artifacts and pu…
mountaindude Oct 22, 2025
739f934
Merge pull request #41 from ptarmiganlabs/copilot/replace-flaky-timin…
mountaindude Oct 22, 2025
e55478d
feat: Switch to dual ESM/CJS output for npm lib, using tsup rather th…
mountaindude Oct 22, 2025
e0d668f
docs: update documentation for multi-platform testing solution, inclu…
mountaindude Oct 22, 2025
73f6ef4
Merge pull request #42 from ptarmiganlabs/copilot/replace-flaky-timin…
mountaindude Oct 22, 2025
ea3981e
feat: add cross-env to test script for consistent environment variabl…
mountaindude Oct 22, 2025
5acf48d
feat: open benchmark links in a new tab
mountaindude Oct 22, 2025
caf2d68
Merge pull request #43 from ptarmiganlabs/copilot/replace-flaky-timin…
mountaindude Oct 22, 2025
e5130ec
feat: use npx to run tsup in build script for consistency
mountaindude Oct 22, 2025
5b87b50
Merge pull request #44 from ptarmiganlabs/copilot/replace-flaky-timin…
mountaindude Oct 22, 2025
0c7efbc
feat: enhance benchmark publishing workflow with matrix configuration…
mountaindude Oct 22, 2025
1629fc6
feat: add Windows-specific workspace cleanup and installation verific…
mountaindude Oct 22, 2025
689dbfe
Merge pull request #45 from ptarmiganlabs/copilot/replace-flaky-timin…
mountaindude Oct 22, 2025
afa0748
feat: remove Windows-specific workspace cleanup step from test workflow
mountaindude Oct 22, 2025
f72c21b
Merge pull request #46 from ptarmiganlabs/copilot/replace-flaky-timin…
mountaindude Oct 22, 2025
742d53c
Refactor testing documentation: Update README and TESTING.md for clar…
mountaindude Oct 22, 2025
9ba6f33
Merge pull request #47 from ptarmiganlabs/copilot/replace-flaky-timin…
mountaindude Oct 22, 2025
a056737
feat: streamline test workflow by consolidating coverage and test res…
mountaindude Oct 22, 2025
8af78c2
feat: add benchmark-debug workflow for fast feedback on benchmark issues
mountaindude Oct 22, 2025
f831a06
Merge pull request #48 from ptarmiganlabs/copilot/replace-flaky-timin…
mountaindude Oct 22, 2025
e568c4e
fix: update job dependencies and strategy in test workflow
mountaindude Oct 22, 2025
fe6b951
Merge pull request #49 from ptarmiganlabs/copilot/replace-flaky-timin…
mountaindude Oct 22, 2025
1090701
feat: update benchmark processing workflow to reduce retention and st…
mountaindude Oct 22, 2025
0480f1d
Merge pull request #50 from ptarmiganlabs/copilot/replace-flaky-timin…
mountaindude Oct 22, 2025
159c134
fix: reduce benchmark artifact retention period and streamline gh-pag…
mountaindude Oct 22, 2025
c82935a
Merge pull request #51 from ptarmiganlabs/copilot/replace-flaky-timin…
mountaindude Oct 22, 2025
ee465ac
fix: correct handling of large numbers and int32 boundaries in when c…
mountaindude Oct 22, 2025
b7b2336
Merge pull request #52 from ptarmiganlabs/bugfix
mountaindude Oct 22, 2025
a951eeb
feat: add support for empty QVD files with detailed documentation and…
mountaindude Oct 23, 2025
01c7a87
Initial plan
Copilot Oct 23, 2025
e89a0ac
feat: add progress callbacks and performance improvements for large Q…
Copilot Oct 23, 2025
5e1eee5
chore: add implementation summary and fix prettier formatting
Copilot Oct 23, 2025
48133f0
Merge pull request #54 from ptarmiganlabs/copilot/add-progress-callba…
mountaindude Oct 23, 2025
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
12 changes: 0 additions & 12 deletions .babelrc

This file was deleted.

2 changes: 0 additions & 2 deletions .eslintignore

This file was deleted.

15 changes: 0 additions & 15 deletions .eslintrc

This file was deleted.

215 changes: 215 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
# GitHub Copilot Instructions for qvd4js

## Project Overview

qvd4js is a Node.js utility library for reading and writing Qlik View Data (QVD) files in JavaScript. The library provides a simple API to parse the proprietary binary QVD file format and convert it to JavaScript objects and vice versa.

## Technology Stack

- **Language**: JavaScript (ES6+)
- **Runtime**: Node.js
- **Build Tool**: Babel (transpilation from src/ to dist/)
- **Testing**: Jest with coverage reporting
- **Linting**: ESLint with Google config and Prettier
- **Dependencies**:
- `xml2js` - for parsing QVD XML headers
- Standard Node.js modules: `fs`, `path`, `crypto`, `assert`

## Project Structure

```
qvd4js/
├── src/ # Source code
│ ├── index.js # Main entry point (exports)
│ └── qvd.js # Core implementation
├── __tests__/ # Jest test files
│ ├── reader.test.js # Reader tests
│ ├── writer.test.js # Writer tests
│ └── data/ # Test QVD files
├── dist/ # Compiled output (generated)
├── coverage/ # Test coverage reports
├── package.json # NPM configuration
├── jest.config.js # Jest configuration
└── README.md # Documentation
```

## Core Architecture

### Main Classes

1. **QvdSymbol**: Represents a single value in a QVD file
- Can contain integer, double, or string values
- Supports dual types (integer+string or double+string)
- Has methods for conversion to primary value and byte representation

2. **QvdDataFrame**: High-level data frame class for working with QVD data
- Static methods: `fromQvd()`, `fromDict()`
- Data manipulation: `head()`, `tail()`, `rows()`, `at()`, `select()`
- Export methods: `toDict()`, `toQvd()`

3. **QvdFileReader**: Handles reading and parsing QVD files
- Parses XML header, symbol table, and index table

4. **QvdFileWriter**: Handles writing QVD files
- Generates proper QVD binary format

### QVD File Format

A QVD file consists of three parts:

1. **XML Header**: Meta information (field names, data types, record count)
2. **Symbol Table**: Distinct values for each column
3. **Index Table**: Binary indices referencing symbol table values

### Symbol Types (Type Byte Prefixes)

| Code | Type | Description |
| ---- | ------------ | ------------------------------ |
| 1 | Integer | 4-byte signed int (LE) |
| 2 | Float | 8-byte IEEE float (LE) |
| 4 | String | Null-terminated string |
| 5 | Dual Integer | Int + null-terminated string |
| 6 | Dual Float | Float + null-terminated string |

## Coding Guidelines

### Style and Conventions

- Use ES6+ features (import/export, async/await, arrow functions)
- Follow Google JavaScript Style Guide
- Use Prettier for code formatting
- Add JSDoc comments for all public methods and classes
- Include type annotations in JSDoc (`@param`, `@return`)
- Use `// @ts-check` at the top of files for basic type checking

### Patterns to Follow

1. **Error Handling**: Use assertions for validation

```javascript
assert(condition, 'Error message');
```

2. **Async Operations**: Use async/await for file operations

```javascript
const df = await QvdDataFrame.fromQvd('path/to/file.qvd');
```

3. **Buffer Operations**: Use Node.js Buffer for binary data
- Little-endian byte order for integers and floats
- Null-terminated strings for text data

4. **Method Chaining**: Support fluent API where appropriate
```javascript
df.select('field1', 'field2').head(10);
```

### Testing

- Write tests using Jest
- Place test files in `__tests__/` directory
- Use descriptive test names
- Maintain high test coverage (aim for >80%)
- Include test data files in `__tests__/data/`

### Build and Development

- **Build**: `npm run build` - Transpile src/ to dist/
- **Test**: `npm run test` - Run Jest with coverage
- **Lint**: `npm run lint` - Run ESLint
- **Clean**: `npm run clean` - Remove dist/ folder

## Common Tasks

### Adding a New Method to QvdDataFrame

1. Add method implementation in `src/qvd.js` in the QvdDataFrame class
2. Include comprehensive JSDoc documentation
3. Add corresponding test in `__tests__/reader.test.js` or `__tests__/writer.test.js`
4. Update README.md API documentation section
5. Run tests and ensure coverage is maintained

### Handling Binary Data

- All binary operations use little-endian byte order
- Use Buffer methods: `writeInt32LE()`, `writeDoubleLE()`, `readInt32LE()`, `readDoubleLE()`
- Always null-terminate strings in binary format
- Type byte prefixes symbol values in the symbol table

### Working with XML Headers

- Use `xml2js` library for parsing and building XML
- XML header contains field metadata (name, type, offset, length)
- XML structure mirrors QVD specification

## Important Notes

- This library is designed exclusively for Node.js (not browser-compatible)
- QVD format is proprietary to Qlik but well-documented
- Performance considerations: QVD files can be large, use streaming where possible
- Maintain backward compatibility with existing QVD files
- The main export point is `src/index.js` - all public APIs export from there

## Repository Information

- **Repository**: https://github.com/MuellerConstantin/qvd4js.git
- **License**: MIT
- **Version**: 1.0.5
- **Author**: Constantin Müller

## Commit Message Guidelines

All commits made by agents **MUST** follow the [Conventional Commits](https://www.conventionalcommits.org/) specification.

### Commit Message Format

```
<type>[optional scope]: <description>

[optional body]

[optional footer(s)]
```

### Commit Types

Use the following commit types:

- **feat**: A new feature (triggers MINOR version bump)
- **fix**: A bug fix (triggers PATCH version bump)
- **docs**: Documentation changes only
- **style**: Code style changes (formatting, missing semi-colons, etc.) - no code change
- **refactor**: Code refactoring without changing functionality
- **perf**: Performance improvements
- **test**: Adding or updating tests
- **build**: Changes to build system or dependencies
- **ci**: Changes to CI configuration files and scripts
- **chore**: Other changes that don't modify src or test files

### Breaking Changes

Breaking changes must be indicated by:
- Adding `!` after the type/scope: `feat!: drop support for Node 14`
- Or including `BREAKING CHANGE:` in the footer

### Examples

```
feat(dataframe): add support for filtering rows
fix: correct symbol table parsing for dual types
docs: update installation instructions in README
test: add tests for QvdFileWriter edge cases
refactor: simplify buffer operations in QvdSymbol
chore: update dependencies to latest versions
```

## When Contributing

1. Ensure all tests pass: `npm run test`
2. Check linting: `npm run lint`
3. Build successfully: `npm run build`
4. Maintain or improve test coverage
5. Update documentation in README.md for any API changes
6. Follow existing code patterns and style
7. **All commits must follow Conventional Commits format** (see above)
68 changes: 68 additions & 0 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# GitHub Actions Workflows

This directory contains GitHub Actions workflows for the qvd4js project.

## Workflows

### `test.yml` - Multi-Platform Test Suite (Production)

The main CI/CD workflow that runs on pushes to `main` and on a weekly schedule.

**Features:**

- Runs linting, building, and testing across multiple platforms and Node.js versions
- Tests on: Linux (GitHub-hosted), Windows, macOS Intel, and macOS ARM (self-hosted)
- Tests with Node.js versions: 20.x, 22.x, 24.x
- Publishes benchmark results to GitHub Pages after ALL test matrix jobs complete
- Runs security scans

**When to use:** This is the production workflow that runs automatically. Don't modify this for debugging.

### `benchmark-debug.yml` - Benchmark Debug (Fast Feedback) ⚡

A lightweight workflow specifically designed for **fast debugging of benchmark GitHub Pages issues**.

**Key differences from production:**

- ✅ **Manual trigger only** - Run when you need it via workflow_dispatch
- ✅ **Single OS/Node combination** - Choose one platform and Node version
- ✅ **Immediate feedback** - Benchmarks are published as soon as the single job completes (not waiting for 12 jobs!)
- ✅ **Separate data directory** - Uses `benchmarks-debug/` to avoid interfering with production data
- ✅ **Job summaries** - Shows benchmark results directly in the GitHub Actions summary

**How to use:**

1. Go to **Actions** tab in GitHub
2. Select **"Benchmark Debug (Fast Feedback)"** workflow
3. Click **"Run workflow"**
4. Choose:
- Platform: Linux, Windows, macOS-Intel, or macOS-ARM
- Node.js version: 20.x, 22.x, or 24.x
5. Click **"Run workflow"**
6. Wait ~1-2 minutes (instead of waiting for all 12 matrix jobs to complete!)
7. View results at: `https://ptarmiganlabs.github.io/qvd4js/benchmarks-debug/{platform}-node{version}`

**Example:**

- Select: `Linux` + `20.x`
- Results appear at: `https://ptarmiganlabs.github.io/qvd4js/benchmarks-debug/Linux-node20.x`

**Why this workflow exists:**

The production workflow waits for all 12 OS/Node combinations to complete before publishing ANY benchmarks. This is correct for production (you want complete data), but makes debugging very slow. This debug workflow gives you immediate feedback on a single configuration, dramatically speeding up the debug cycle.

## Debugging Benchmark Issues

If you're seeing issues with benchmark data on GitHub Pages (e.g., only 2 data points per chart):

1. Use the `benchmark-debug.yml` workflow with a single platform
2. Check the Job Summary for the raw benchmark results
3. Visit the debug GitHub Pages URL immediately after the workflow completes
4. Iterate quickly without waiting for 12 jobs each time
5. Once fixed, verify with the full `test.yml` workflow

## Related Documentation

- [GitHub Pages Setup](../docs/GITHUB_PAGES_SETUP.md)
- [Testing Guide](../docs/TESTING.md)
- [Continuous Benchmark Action](https://github.com/marketplace/actions/continuous-benchmark)
Loading