Implement `--refresh` CLI Command To Fetch And Persist JSON-LD Contexts
Background
In our mission to crawl public data and generate OWL ontologies, we require a mechanism to refresh and cache remote JSON-LD context files locally. Currently, the main
function in src/lib/main.js
only logs input arguments. We have a refresh
script (npm run refresh
→ node src/lib/main.js --refresh
) defined in package.json
, but no implementation.
Goal
To support our mission, we aim to add a --refresh
flag to the CLI that:
- Loads a list of remote JSON-LD context IRIs (hardcoded or read from a small config object).
- Fetches each context via HTTP (using Node's built-in
fetch
API in Node 20+). - Writes the fetched JSON content to a local
contexts/
directory under the project root (creating the directory if necessary). - Logs summary output (
Fetched X contexts, saved to contexts/
).
Scope
1. Source (src/lib/main.js
)
To implement the --refresh
flag, we need to:
- Parse
--refresh
fromargs
. - Implement an async
refreshContexts()
helper:- Define an array of context IRIs (e.g., two example IRIs).
- Use
fetch
to GET each context. - Write files named by a safe filename (e.g., last path segment) under
contexts/
. - Use
fs.promises
APIs for directory creation and file writing.
- Call
refreshContexts()
when flag is passed and exit gracefully.
2. Tests (tests/unit/main.test.js
)
To verify the implementation, we need to:
- Inject a mock global
fetch
that returns a synthetic JSON context. - Spy on
fs.promises.writeFile
andfs.promises.mkdir
to verify calls. - Add a new unit test for
main(["--refresh"])
to assert it returns a resolved promise and logs the expected summary.
3. Documentation
To document the new feature, we need to:
- Add a
## --refresh
section describing usage examples indocs/USAGE.md
. - Under "Features", add a bullet for Refresh Contexts and update the
npm run refresh
description inREADME.md
.
4. Dependencies (package.json
)
No new external dependencies are required, as Node 20+ has a global fetch
API.
Verification
To verify the implementation, we need to:
- Run
npm run refresh
and observe creation ofcontexts/
directory with JSON files. - Unit tests should pass with the new mock tests.
- Documentation reflects the new command.
Notes
- Keep the list of context IRIs minimal (2–3 examples) for demonstration.
- Ensure the feature does not block regular
main
behavior when no flag is passed.
Implementation
// src/lib/main.js
const fs = require('fs').promises;
const path = require('path');
async function refreshContexts() {
const contextIris = [
'https://example.com/context1',
'https://example.com/context2',
];
for (const iri of contextIris) {
try {
const response = await fetch(iri);
const json = await response.json();
const safeFilename = path.basename(iri);
await fs.writeFile(path.join('contexts', safeFilename), JSON.stringify(json));
} catch (error) {
console.error(`Error fetching context: ${error.message}`);
}
}
}
async function main(args) {
if (args.includes('--refresh')) {
await refreshContexts();
console.log(`Fetched ${contextIris.length} contexts, saved to contexts/`);
process.exit(0);
}
// Regular main function implementation
}
module.exports = main;
// tests/unit/main.test.js
const fetchMock = require('jest-fetch-mock');
fetchMock.enableMocks();
describe('main', () => {
beforeEach(() => {
jest.spyOn(fs.promises, 'writeFile');
jest.spyOn(fs.promises, 'mkdir');
});
afterEach(() => {
jest.restoreAllMocks();
});
it('should call refreshContexts when --refresh flag is passed', async () => {
const main = require('../src/lib/main');
const args = ['--refresh'];
await main(args);
expect(fs.promises.writeFile).toHaveBeenCalledTimes(2);
expect(fs.promises.mkdir).toHaveBeenCalledTimes(1);
});
it('should log summary output when --refresh flag is passed', async () => {
const main = require('../src/lib/main');
const args = ['--refresh'];
const consoleLogSpy = jest.spyOn(console, 'log');
await main(args);
expect(consoleLogSpy).toHaveBeenCalledWith('Fetched 2 contexts, saved to contexts/');
});
});
# Usage
-----
## --refresh
The `--refresh` flag is used to fetch and persist remote JSON-LD context files locally.
### Example
```bash
npm run refresh
This will fetch the remote JSON-LD context files and save them to a local contexts/
directory under the project root.
Features
- Refresh Contexts: Fetch and persist remote JSON-LD context files locally.
```markdown
# Features
------------
* **Refresh Contexts**: Fetch and persist remote JSON-LD context files locally.
* **npm run refresh**: Run the `refresh` script to fetch and persist remote JSON-LD context files locally.
// package.json
{
"scripts": {
"refresh": "node src/lib/main.js --refresh"
}
}
```<br/>
**Q&A: Implementing `--refresh` CLI Command to Fetch and Persist JSON-LD Contexts**
=====================================================================================
**Q: What is the purpose of the `--refresh` CLI command?**
---------------------------------------------------
A: The `--refresh` CLI command is used to fetch and persist remote JSON-LD context files locally. This is an essential feature for our mission to crawl public data and generate OWL ontologies.
**Q: How does the `--refresh` CLI command work?**
------------------------------------------------
A: The `--refresh` CLI command works by:
1. Loading a list of remote JSON-LD context IRIs (hardcoded or read from a small config object).
2. Fetching each context via HTTP (using Node's built-in `fetch` API in Node 20+).
3. Writing the fetched JSON content to a local `contexts/` directory under the project root (creating the directory if necessary).
4. Logging summary output (`Fetched X contexts, saved to contexts/`).
**Q: What are the benefits of implementing the `--refresh` CLI command?**
-------------------------------------------------------------------
A: The benefits of implementing the `--refresh` CLI command include:
* Improved data freshness: By regularly refreshing remote JSON-LD context files, we can ensure that our data is up-to-date and accurate.
* Enhanced data consistency: By persisting remote JSON-LD context files locally, we can ensure that our data is consistent across different systems and environments.
* Simplified data management: By providing a simple CLI command to refresh remote JSON-LD context files, we can simplify data management and reduce the risk of errors.
**Q: How do I implement the `--refresh` CLI command?**
---------------------------------------------------
A: To implement the `--refresh` CLI command, you need to:
1. Parse `--refresh` from `args`.
2. Implement an async `refreshContexts()` helper:
* Define an array of context IRIs (e.g., two example IRIs).
* Use `fetch` to GET each context.
* Write files named by a safe filename (e.g., last path segment) under `contexts/`.
* Use `fs.promises` APIs for directory creation and file writing.
3. Call `refreshContexts()` when flag is passed and exit gracefully.
**Q: How do I test the `--refresh` CLI command?**
------------------------------------------------
A: To test the `--refresh` CLI command, you need to:
1. Inject a mock global `fetch` that returns a synthetic JSON context.
2. Spy on `fs.promises.writeFile` and `fs.promises.mkdir` to verify calls.
3. Add a new unit test for `main(["--refresh"])` to assert it returns a resolved promise and logs the expected summary.
**Q: How do I document the `--refresh` CLI command?**
---------------------------------------------------
A: To document the `--refresh` CLI command, you need to:
1. Add a `## --refresh` section describing usage examples in `docs/USAGE.md`.
2. Under "Features", add a bullet for **Refresh Contexts** and update the `npm run refresh` description in `README.md`.
**Q: What are the dependencies required to implement the `--refresh` CLI command?**
A: No new external dependencies are required, as Node 20+ has a global `fetch` API.
**Q: How do I verify the implementation of the `--refresh` CLI command?**
---------------------------------------------------------------------
A: To verify the implementation of the `--refresh` CLI command, you need to:
1. Run `npm run refresh` and observe creation of `contexts/` directory with JSON files.
2. Unit tests should pass with the new mock tests.
3. Documentation reflects the new command.
**Q: What are the notes for implementing the `--refresh` CLI command?**
-------------------------------------------------------------------
A: Keep the list of context IRIs minimal (2–3 examples) for demonstration. Ensure the feature does not block regular `main` behavior when no flag is passed.