Skip to content

Commit 33f9d29

Browse files
committed
fix docs and examples
1 parent d7eba6f commit 33f9d29

6 files changed

Lines changed: 74 additions & 51 deletions

File tree

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ This repository is designed to be used with file-based data programmatically; fo
1010
📦common-identifier-algorithm-shared
1111
┣ 📂src
1212
┃ ┣ 📂config # functions related to the handling of configuration files
13+
┃ ┣ 📂crypto # functions related to encryption & signing of files
1314
┃ ┣ 📂decoding # reading and decoding files - CSV or XLSX
1415
┃ ┣ 📂encoding # encoding and writing files - CSV or XLSX
1516
┃ ┣ 📂hashing # base hashing logic and supporting utilities
@@ -46,4 +47,8 @@ This repository is designed to be used with file-based data programmatically; fo
4647
- The `src/processing` processing function identifies if the target is a mapping document based on the current configuration and the data in the file. Using the active configuration it collects data into `static` `to_translate` and `reference` buckets per-row and passes it to the active algorithm for processing
4748
- The active algorithm takes the `{ static:[...], to_translate:[...], reference: [...] }` per-row data and returns a map with the columns it wants to add -- ex: `{ USCADI: "....", DOCUMENT_HASH: "..." }`
4849
- The data returned by the algorithm is merged into the source rows so the encoders can package multiple different outputs
49-
- The `src/encoding` Encoders (CSV and XLSX) write the output based on the relevant `[destination]` / `[destination_map]` section of the active configuration.
50+
- The `src/encoding` Encoders (CSV and XLSX) write the output based on the relevant `[destination]` / `[destination_map]` section of the active configuration.
51+
52+
### Post-processing
53+
54+
- Any post-processing steps (e.g. encryption, signing, etc.) are handled after the encoding step, using the relevant classes in `src/crypto` (e.g. `GpgWrapper` for GPG encryption/signing)

docs/configuration-files.md

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,24 @@ Look in any of the existing algorithm implementation repositories for examples o
1010

1111
The meta section of the file contains information related to application versioning.
1212

13-
```
13+
```toml
1414
[meta]
15-
region="ABC" # application installations are region dependent, the value specified here MUST match the built-in region.
15+
id="ABC" # application installations are typically region dependent, the value specified here MUST match the built-in region.
1616
version="1.0.0" # the version information is shown in the top-right of the desktop UI for user visibility.
1717
signature = "aaabbb"
1818
```
19-
The signature is the calculated `md5` hash value of the configuration file itself, computed using the `src/config/generateConfigHash.ts` utility. This feature exists to reduce the likelihood of accidental changes to the config file causing issues in the deterministic processing of input data.
19+
The signature is the calculated `md5` hash value of the configuration file itself, computed using the [`generateConfigHash`](../src/config/utils.ts) utility. This feature exists to reduce the likelihood of accidental changes to the config file causing issues in the deterministic processing of input data.
2020

2121
When a change is made to the configuration file, a new signature value must be created to reflect its new content.
2222

23-
> TODO: git pre-commit hook to validate the config file on commit and throw an error if values don't match.
24-
2523
### Messages
2624

2725
> [!IMPORTANT]
2826
> If you are intending on using the UI component of this application, the messages section in the configuration file is NOT optional. The values for `terms_and_conditions`, `error_in_config`, and `error_in_salt` MUST be defined.
2927
3028
Messages are an optional field used to set the default error and terms & conditions messages within the UI application. Each of these fields supports `HTML` tag syntax.
3129

32-
```
30+
```toml
3331
[messages]
3432
# terms and conditions are shown to the user on first start and upon configuration file changes.
3533
terms_and_conditions="""
@@ -46,9 +44,7 @@ error_in_salt=""
4644

4745
The `source` sections defines the expected input columns in the source dataset. The `name` key is the human readable name in the header of the CSV file, `alias` is the more machine-friendly name used by the application internally, and `default` is the default value to use for empty cells where necessary.
4846

49-
> TODO: make `alias` an optional parameter - it is not relevant for programmatic usage.
50-
51-
```
47+
```toml
5248
[source]
5349
# an array of column names, their aliases, and default values where necessary.
5450
columns = [
@@ -62,7 +58,7 @@ columns = [
6258

6359
This file section details which validation rules to apply to which columns in the input file.
6460

65-
```
61+
```toml
6662
[validations]
6763
# per column name to apply validation rules to, define an array of validation rules
6864
column_name = [
@@ -74,7 +70,7 @@ column_name = [
7470
]
7571
```
7672

77-
```
73+
```toml
7874
# the structure of a validation rule is as follows:
7975
{
8076
# the name of the validation rule, from the supported list.
@@ -107,7 +103,7 @@ This is the list of currently supported validation rules, these are further desc
107103

108104
### Algorithm
109105

110-
```
106+
```toml
111107
[algorithm]
112108
# the aliased columns to use as part of the algo implementation.
113109
[algorithm.columns]
@@ -119,7 +115,7 @@ static = [ "col_b" ]
119115
reference = [ "col_c" ]
120116
```
121117

122-
```
118+
```toml
123119
[algorithm.hash]
124120
# the hashing algorithm to use, currently only SHA256 is supported
125121
strategy = "SHA256"
@@ -146,7 +142,7 @@ darwin = "$APPDATA/<path_to_file>/file.asc"
146142

147143
Define the columns to include in the output file, including the human-readable names to convert to where necessary.
148144

149-
```
145+
```toml
150146
[destination]
151147
# array of column names and aliases to include in the output file
152148
columns = [
@@ -163,7 +159,7 @@ postfix = "_OUTPUT"
163159

164160
Define the columns to include in the output mapping file, including the human-readable names to convert to where necessary.
165161

166-
```
162+
```toml
167163
[destination_map]
168164
# array of column names and aliases to include in the output mapping file
169165
columns = [
@@ -183,7 +179,7 @@ Define the columns to include in the error report, including the human-readable
183179
> [!IMPORTANT]
184180
> Make sure to include the `Errors | errors` column in the output configuration, otherwise they will not be included in the output file.
185181
186-
```
182+
```toml
187183
[destination_errors]
188184
# array of column names and aliases to include in the errors file
189185
columns = [
@@ -195,4 +191,15 @@ columns = [
195191
# suffix that is appended to the errors filename -> <input_file_name><postfix>.csv
196192
# for XLSX, this is also the name of the sheet containing the final data
197193
postfix = "_ERRORS"
194+
```
195+
196+
### Post-processing
197+
198+
#### Encryption / Signing
199+
200+
```toml
201+
[post_processing]
202+
[post_processing.encryption]
203+
recipient = "QWERTY" # the fingerprint or identifier of the recipient to encrypt the file for
204+
gpgBinaryPath = "" # optional path to gpg binary, overrides system path lookup
198205
```

examples/example_algorithm/config.toml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[meta]
22
id="ANY"
33
version="1.0.0"
4-
signature="a36d008f81060928709a6704da61bbd6"
4+
signature="f2789d9afdb774d88be5998aa37bdb78"
55

66
[source]
77
columns = [
@@ -35,18 +35,25 @@ strategy = "SHA256"
3535
columns = [
3636
{ name = "Common Identifier", alias = "hashed_id" },
3737
]
38-
postfix = "-OUTPUT-{{yyyy-MM-dd--HH-mm-ss}}"
38+
prefix = "OUTPUT-"
39+
postfix = "-{{yyyyMMddHHmm}}"
3940

4041
[destination_map]
4142
columns = [
4243
{ name = "ID", alias = "id" },
4344
{ name = "Common Identifier", alias = "hashed_id" }
4445
]
45-
postfix = "-MAPPING-{{yyyy-MM-dd--HH-mm-ss}}"
46+
prefix = "MAPPING-"
47+
postfix = "-{{yyyyMMddHHmm}}"
4648

4749
[destination_errors]
4850
columns = [
4951
{ name = "Errors", alias = "errors" },
5052
{ name = "ID", alias = "id" },
5153
]
52-
postfix = "-ERRORS-{{yyyy-MM-dd--HH-mm-ss}}"
54+
prefix = "ERRORS-"
55+
postfix = "-{{yyyyMMddHHmm}}"
56+
57+
# [post_processing]
58+
# [post_processing.encryption]
59+
# recipient = "SOME_PUBLIC_KEY_FINGERPRINT"

examples/file_based_usage.ts

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
// REPLACE ALL REFERENCES TO "_generic_hasher" WITH THE DESIRED ALGORITHM IN THE ALGORITHMS DIRECTORY.
22

33
import { existsSync, rmSync } from 'node:fs';
4-
import { encryptFileWithGpg } from '../src/crypto/gpg';
5-
import { loadConfig, preprocessFile, processFile } from '../src/index';
4+
import { loadConfig, postprocessFile, preprocessFile, processFile } from '../src/index';
65
import { makeHasher, ALGORITHM_ID } from './example_algorithm/_generic_hasher';
7-
import { dirname, join, resolve } from 'node:path';
6+
import { dirname, join, parse, resolve } from 'node:path';
87
import { fileURLToPath } from 'node:url';
98

109
const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -16,45 +15,50 @@ const VALIDATION_ERRORS_PATH = join(__dirname, 'output', 'validation_errors.csv'
1615

1716
if (existsSync(resolve(__dirname, "output"))) rmSync(join(__dirname, "output"), { recursive: true, force: true});
1817

19-
// load configuration from file
18+
// 1. load configuration from file
2019
const configLoadResult = loadConfig({
2120
configPath: CONFIG_PATH,
2221
algorithmId: ALGORITHM_ID,
2322
validateConfig: true,
2423
embeddedSalt: { source: "STRING", value: "SOME_SALT_VALUE" }
2524
});
26-
if (!configLoadResult.success) throw new Error(`ERROR: Unable to load configuration file >> ${configLoadResult.error}`);
25+
if (!configLoadResult.success)
26+
throw new Error(`ERROR: Unable to load configuration file >> ${configLoadResult.error}`);
2727

28-
// validate the input file against all configured validation rules.
28+
// 2. validate the input file against all configured validation rules.
2929
const preprocessResult = await preprocessFile({
3030
config: configLoadResult.config,
3131
inputFilePath: INPUT_PATH,
3232
errorFileOutputPath: VALIDATION_ERRORS_PATH,
3333
});
3434

3535
if (!preprocessResult.isValid)
36-
throw new Error('Validation errors found in input file, review error file output.');
36+
throw new Error('ERROR: Validation errors found in input file, review error file output.');
3737

38-
// validate the input file against all configured validation rules.
38+
// 3. process the input file according to the configuration.
3939
const processFileResult = await processFile({
4040
config: configLoadResult.config,
4141
inputFilePath: INPUT_PATH,
4242
outputPath: OUTPUT_PATH,
4343
hasherFactory: makeHasher,
4444
});
45-
// print the result, save the result, etc.
46-
// console.dir(processFileResult, { depth: 3 });
47-
48-
49-
const result = await encryptFileWithGpg({
50-
inputPath: processFileResult.outputFilePath!,
51-
outputPath: processFileResult.outputFilePath! + '.gpg',
52-
gpgPath: "gpg",
53-
recipient: '5A42A8421D19427562C5DEBE0CC75DCC440E1B46',
54-
// recipient: "9463D5547670C915D23671A8DA57DA502A841FEF",
55-
homedir: process.env.HOMEDIR,
56-
// signer: "5A42A8421D19427562C5DEBE0CC75DCC440E1B46"
57-
signer: "9463D5547670C915D23671A8DA57DA502A841FEF",
58-
trustAlways: true,
45+
if (!processFileResult.outputFilePath)
46+
throw new Error(`ERROR: Unable to process input file`);
47+
48+
// 4. print the result, save the result, etc.
49+
console.dir(processFileResult, { depth: 3 });
50+
51+
52+
// 5. postprocess the output file according to the configuration.
53+
const postprocessResult = await postprocessFile({
54+
config: configLoadResult.config,
55+
inputPath: processFileResult.outputFilePath,
56+
outputPath: join(parse(processFileResult.outputFilePath).dir, "ENCRYPTED.gpg"),
57+
options: {
58+
signer: "" // OPTIONAL: Signing key
59+
}
5960
});
60-
console.log(result)
61+
if (!postprocessResult.success) {
62+
const errors = postprocessResult.steps.filter(step => !step.success);
63+
throw new Error(`ERROR: Postprocessing failed, one or more steps failed >> ${JSON.stringify(errors)}`);
64+
}

examples/programmatic_usage.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// REPLACE ALL REFERENCES TO "_generic_hasher" WITH THE DESIRED ALGORITHM IN THE ALGORITHMS DIRECTORY.
2-
import { generateHashesForDocument, validateConfigCore, validateDocument, type CidDocument, type Config } from '../src/index';
3-
import { SUPPORTED_VALIDATORS } from '../src/validation/Validation';
2+
import { generateHashesForDocument, validateConfigCore, validateDocument, type CidDocument, type Config } from '@/index';
3+
import { SUPPORTED_VALIDATORS } from '@/validation/Validation';
44
import { makeHasher } from './example_algorithm/_generic_hasher';
55

66
/*
@@ -39,9 +39,6 @@ const config: Config.CoreConfiguration = {
3939
reference: [],
4040
static: [ "id" ]
4141
},
42-
},
43-
post_processing: {
44-
4542
}
4643
}
4744

@@ -57,7 +54,7 @@ const doc: CidDocument = {
5754
]
5855
}
5956

60-
function main() {
57+
async function main() {
6158
const configValidationResult = validateConfigCore(config, "UNKNOWN");
6259
if (!!configValidationResult) {
6360
console.log(`ERROR: ${configValidationResult}`);
@@ -78,6 +75,9 @@ function main() {
7875

7976
// print the results, save the results, up to you.
8077
console.dir(result, { depth: 5 });
78+
79+
// NOTE: do any postprocessing steps as required, e.g. encryption, signing, etc.
80+
// see the GpgWrapper class in src/crypto/gpg.ts for example usage.
8181
}
8282

8383
main();

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,6 @@
2626

2727
"noEmit": true
2828
},
29-
"include": ["src/**/*.ts", "tests/**/*.ts" ],
29+
"include": ["src/**/*.ts", "tests/**/*.ts", "examples/**/*.ts" ],
3030
"exclude": ["node_modules", "dist", "tmp", "**/tmp"]
3131
}

0 commit comments

Comments
 (0)