-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
72a4836
commit 787ecc3
Showing
20 changed files
with
528 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{ | ||
"extends": ["../../../.eslintrc.base.json"], | ||
"ignorePatterns": ["!**/*"], | ||
"overrides": [ | ||
{ | ||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"], | ||
"rules": {} | ||
}, | ||
{ | ||
"files": ["*.ts", "*.tsx"], | ||
"rules": {} | ||
}, | ||
{ | ||
"files": ["*.js", "*.jsx"], | ||
"rules": {} | ||
}, | ||
{ | ||
"files": ["*.json"], | ||
"parser": "jsonc-eslint-parser", | ||
"rules": { | ||
"@nx/dependency-checks": "error" | ||
} | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# ingestion | ||
|
||
This library was generated with [Nx](https://nx.dev). | ||
|
||
## Building | ||
|
||
Run `nx build ingestion` to build the library. | ||
|
||
## Running unit tests | ||
|
||
Run `nx test ingestion` to execute the unit tests via [Jest](https://jestjs.io). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/* eslint-disable */ | ||
export default { | ||
displayName: 'ingestion', | ||
preset: '../../../jest.preset.js', | ||
testEnvironment: 'node', | ||
transform: { | ||
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }], | ||
}, | ||
moduleFileExtensions: ['ts', 'js', 'html'], | ||
coverageDirectory: '../../../coverage/libs/report/ingestion', | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"name": "@herodevs/report-ingestion", | ||
"version": "0.0.1", | ||
"dependencies": { | ||
"tslib": "^2.3.0" | ||
}, | ||
"type": "commonjs", | ||
"main": "./src/index.js", | ||
"typings": "./src/index.d.ts", | ||
"private": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"name": "report-ingestion", | ||
"$schema": "../../../node_modules/nx/schemas/project-schema.json", | ||
"sourceRoot": "libs/report/ingestion/src", | ||
"projectType": "library", | ||
"tags": [], | ||
"targets": { | ||
"build": { | ||
"executor": "@nx/js:tsc", | ||
"outputs": ["{options.outputPath}"], | ||
"options": { | ||
"outputPath": "dist/libs/report/ingestion", | ||
"main": "libs/report/ingestion/src/index.ts", | ||
"tsConfig": "libs/report/ingestion/tsconfig.lib.json", | ||
"assets": ["libs/report/ingestion/*.md"] | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './lib/ingestion'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import { readFileSync, statSync } from 'node:fs'; | ||
import { promptToProceedUploadFile } from './prompts'; | ||
import { findManifestFiles } from './send-manifest'; | ||
|
||
jest.mock('node:fs', () => ({ | ||
readFileSync: jest.fn(), | ||
statSync: jest.fn(), | ||
})); | ||
|
||
jest.mock('./prompts', () => ({ | ||
promptToProceedUploadFile: jest.fn(), | ||
})); | ||
|
||
describe('Telemetry Functions', () => { | ||
it('should find manifest files correctly', async () => { | ||
const mockFileName = 'package.json'; | ||
const mockFileData = '{"name": "test package"}'; | ||
const mockFileStat = { size: 1024 }; | ||
|
||
(statSync as jest.Mock).mockReturnValue(mockFileStat); | ||
(readFileSync as jest.Mock).mockReturnValue(mockFileData); | ||
(promptToProceedUploadFile as jest.Mock).mockResolvedValue(true); | ||
|
||
const result = await findManifestFiles(); | ||
|
||
expect(result).toEqual({ name: mockFileName, data: mockFileData }); | ||
expect(promptToProceedUploadFile).toHaveBeenCalledWith(mockFileName); | ||
}); | ||
|
||
it('should warn if manifest file is empty', async () => { | ||
const mockFileName = 'package.json'; | ||
const mockFileStat = { size: 0 }; | ||
(statSync as jest.Mock).mockReturnValue(mockFileStat); | ||
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(); | ||
const result = await findManifestFiles(); | ||
|
||
expect(result).toBeUndefined(); | ||
expect(consoleWarnSpy).toHaveBeenCalledWith(`File ${mockFileName} is empty`); | ||
consoleWarnSpy.mockRestore(); | ||
}); | ||
|
||
it('should warn if manifest file is too large', async () => { | ||
const mockFileStat = { size: 6e6 }; // 6MB file, larger than the 5MB max size | ||
(statSync as jest.Mock).mockReturnValue(mockFileStat); | ||
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(); | ||
const result = await findManifestFiles(); | ||
const mockFileName = 'package.json'; | ||
expect(result).toBeUndefined(); | ||
expect(consoleWarnSpy).toHaveBeenCalledWith(`File ${mockFileName} is too large`); | ||
consoleWarnSpy.mockRestore(); | ||
}); | ||
|
||
it('should not proceed with upload if user rejects', async () => { | ||
const mockFileName = 'package.json'; | ||
const mockFileStat = { size: 1024 }; | ||
(statSync as jest.Mock).mockReturnValue(mockFileStat); | ||
(promptToProceedUploadFile as jest.Mock).mockResolvedValue(false); | ||
const result = await findManifestFiles(); | ||
expect(result).toBeUndefined(); | ||
expect(promptToProceedUploadFile).toHaveBeenCalledWith(mockFileName); | ||
}); | ||
|
||
it('should return undefined if no manifest file is found', async () => { | ||
(statSync as jest.Mock).mockReturnValueOnce(undefined); | ||
const result = await findManifestFiles(); | ||
expect(result).toBeUndefined(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import { input, confirm } from '@inquirer/prompts'; | ||
import { askConsent, promptClientName, promptToProceedUploadFile } from './prompts'; | ||
|
||
jest.mock('@inquirer/prompts', () => ({ | ||
input: jest.fn(), | ||
confirm: jest.fn(), | ||
})); | ||
|
||
describe('askConsent', () => { | ||
it('should return true if args.consent is true', async () => { | ||
const args = { consent: true } as any; | ||
const consoleSpy = jest.spyOn(console, 'log').mockImplementation(); | ||
|
||
const result = await askConsent(args); | ||
|
||
expect(consoleSpy).toHaveBeenCalledWith( | ||
'Data may contain sensitive data, please review before sharing it.' | ||
); | ||
expect(result).toBe(true); | ||
|
||
consoleSpy.mockRestore(); | ||
}); | ||
|
||
it('should prompt for consent and return true if user agrees', async () => { | ||
const args = { consent: false } as any; | ||
(confirm as jest.Mock).mockResolvedValue(true); | ||
|
||
const result = await askConsent(args); | ||
|
||
expect(confirm).toHaveBeenCalledWith({ | ||
message: 'Data may contain sensitive data, please review before sharing it. Continue?', | ||
}); | ||
expect(result).toBe(true); | ||
}); | ||
|
||
it('should prompt for consent and return false if user disagrees', async () => { | ||
const args = { consent: false } as any; | ||
(confirm as jest.Mock).mockResolvedValue(false); | ||
|
||
const result = await askConsent(args); | ||
|
||
expect(confirm).toHaveBeenCalledWith({ | ||
message: 'Data may contain sensitive data, please review before sharing it. Continue?', | ||
}); | ||
expect(result).toBe(false); | ||
}); | ||
}); | ||
|
||
describe('promptClientName', () => { | ||
it('should return the entered name if valid', async () => { | ||
const mockName = 'John Doe'; | ||
(input as jest.Mock).mockResolvedValue(mockName); | ||
|
||
const result = await promptClientName(); | ||
|
||
expect(input).toHaveBeenCalledWith({ | ||
message: 'Please enter your name:', | ||
validate: expect.any(Function), | ||
}); | ||
expect(result).toBe(mockName); | ||
}); | ||
|
||
it('should validate the input and reject empty names', async () => { | ||
const validateFn = (input as jest.Mock).mock.calls[0][0].validate; | ||
expect(validateFn('')).toBe('Name cannot be empty!'); | ||
expect(validateFn(' ')).toBe('Name cannot be empty!'); | ||
expect(validateFn('Valid Name')).toBe(true); | ||
}); | ||
}); | ||
|
||
describe('promptToProceedUploadFile', () => { | ||
it('should return true if the user confirms the upload', async () => { | ||
const fileName = 'test-file.txt'; | ||
(confirm as jest.Mock).mockResolvedValue(true); // mock the confirm response as true | ||
|
||
const result = await promptToProceedUploadFile(fileName); | ||
|
||
expect(result).toBe(true); | ||
expect(confirm).toHaveBeenCalledWith({ | ||
message: `Found ${fileName}, this file will be uploaded. Continue?`, | ||
}); | ||
}); | ||
|
||
it('should return false if the user denies the upload', async () => { | ||
const fileName = 'test-file.txt'; | ||
(confirm as jest.Mock).mockResolvedValue(false); // mock the confirm response as false | ||
|
||
const result = await promptToProceedUploadFile(fileName); | ||
|
||
expect(result).toBe(false); | ||
expect(confirm).toHaveBeenCalledWith({ | ||
message: `Found ${fileName}, this file will be uploaded. Continue?`, | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { type ArgumentsCamelCase, type CommandModule } from 'yargs'; | ||
import { askConsent, promptClientName, promptToProceedUploadFile } from './prompts'; | ||
import { findManifestFiles, getClientToken, sendManifest } from './send-manifest'; | ||
import { type Options } from './types'; | ||
|
||
export const reportIngestionCommand: CommandModule<object, Options> = { | ||
command: 'ingestion', | ||
describe: 'send manifest files information', | ||
aliases: ['ingest', 'i'], | ||
builder: { | ||
consent: { | ||
describe: 'Agree to understanding that sensitive data may be outputted', | ||
required: false, | ||
default: false, | ||
boolean: true, | ||
}, | ||
}, | ||
handler: run, | ||
}; | ||
|
||
async function run(args: ArgumentsCamelCase<Options>): Promise<void> { | ||
const consent = await askConsent(args); | ||
if (!consent) { | ||
return; | ||
} | ||
// Prompt the user to insert their name | ||
const clientName = await promptClientName(); | ||
// First we need to get a short lived token | ||
const oid = await getClientToken(clientName); | ||
|
||
// Manifest is a list of files that we have found | ||
const manifest = await findManifestFiles(); | ||
if (!manifest) { | ||
console.log('No manifest files found'); | ||
return; | ||
} | ||
|
||
await sendManifest(oid, manifest, { clientName }); | ||
console.log('Manifest sent correctly!'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { confirm, input } from '@inquirer/prompts'; | ||
import { ArgumentsCamelCase } from 'yargs'; | ||
import { type Options } from './types'; | ||
|
||
export async function askConsent(args: ArgumentsCamelCase<Options>): Promise<boolean> { | ||
const consentPrompt = 'Data may contain sensitive data, please review before sharing it.'; | ||
if (!args.consent) { | ||
const answer = await confirm({ | ||
message: `${consentPrompt} Continue?`, | ||
}); | ||
if (!answer) { | ||
return false; | ||
} | ||
} else { | ||
console.log(consentPrompt); | ||
} | ||
return true; | ||
} | ||
|
||
export async function promptClientName() { | ||
const name = await input({ | ||
message: 'Please enter your name:', | ||
validate: (value) => (value.trim() === '' ? 'Name cannot be empty!' : true), | ||
}); | ||
return name; | ||
} | ||
|
||
export async function promptToProceedUploadFile(fileName: string): Promise<boolean> { | ||
const consentPrompt = `Found ${fileName}, this file will be uploaded.`; | ||
const answer = await confirm({ | ||
message: `${consentPrompt} Continue?`, | ||
}); | ||
if (!answer) { | ||
return false; | ||
} | ||
return true; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { gql } from '@apollo/client/core'; | ||
|
||
export const TELEMETRY_INITIALIZE_MUTATION = gql` | ||
mutation Telemetry($clientName: String!) { | ||
telemetry { | ||
initialize(input: { context: { client: { id: $clientName } } }) { | ||
success | ||
oid | ||
message | ||
} | ||
} | ||
} | ||
`; | ||
|
||
export const TELEMETRY_REPORT_MUTATION = gql` | ||
mutation Report($key: String!, $report: JSON!, $metadata: JSON) { | ||
telemetry { | ||
report(input: { key: $key, report: $report, metadata: $metadata }) { | ||
txId | ||
success | ||
message | ||
diagnostics | ||
} | ||
} | ||
} | ||
`; |
Oops, something went wrong.