Skip to content
This repository was archived by the owner on Jun 4, 2025. It is now read-only.

Commit a38553e

Browse files
authored
Updates Destination Data Per edX Spec (#5)
* Updates Per edX Spec * Updates StringMapper Test
1 parent 49d8243 commit a38553e

9 files changed

Lines changed: 309 additions & 1138 deletions

File tree

package-lock.json

Lines changed: 85 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"license": "MIT",
2424
"devDependencies": {
2525
"@types/chai": "^4.2.22",
26+
"@types/md5": "^2.3.1",
2627
"@types/mocha": "^9.0.0",
2728
"@types/node": "^16.11.19",
2829
"@typescript-eslint/eslint-plugin": "^5.3.1",
@@ -42,6 +43,7 @@
4243
},
4344
"dependencies": {
4445
"axios": "^0.22.0",
45-
"jsonschema": "^1.4.0"
46+
"jsonschema": "^1.4.0",
47+
"md5": "^2.3.0"
4648
}
4749
}

src/app.ts

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { exit } from "process";
88
import sourceSchema from './schema/jsonapi.json';
99
import mapping from './schema/mapping.json';
1010
import destinationSchema from './schema/p2881.json';
11+
import md5 from 'md5';
1112

1213
class App {
1314

@@ -41,9 +42,6 @@ class App {
4142
let url: string|undefined = process.env.SOURCE_ENDPOINT;
4243
const sourceSchema = await this.getSourceSchema();
4344
const transformationMapping = this.getTransformationMapping();
44-
// Set up the destination object.
45-
let destinationData: MappedItem = {"learning_experience_sets": []};
46-
4745
// Loop through JSON:API pages. This will download the a single page,
4846
// then transforms the data by adding all of the included data,
4947
// then maps each source object within the page to a learning experience.
@@ -59,21 +57,26 @@ class App {
5957
this.outputToConsole(sourceValidated.errors, 'error');
6058
exit(1);
6159
}
60+
6261
const jsonApiData = new JsonAPIDeserializer(sourceJSONData as JsonApi);
63-
destinationData = await this.transformSourceData(jsonApiData.data, transformationMapping, destinationData);
62+
const destinationData: MappedItem = await this.transformSourceData(jsonApiData.data, transformationMapping, {});
63+
// Get the destination schema.
64+
const destinationSchema = await this.getDestinationSchema();
65+
const values = Object.values(destinationData);
66+
for (let i = 0; i < values.length; i++) {
67+
let value = values[i];
68+
value = this.addHashes(value);
69+
// Validate the destination data against the schema.
70+
const destinationValidated = this.validateData(value, destinationSchema);
71+
if (!destinationValidated.valid) {
72+
this.outputToConsole(destinationValidated.errors, 'error');
73+
exit(2);
74+
}
75+
await this.sendDestinationData(destinationData);
76+
}
6477
url = jsonApiData.nextPage;
6578
url = url?.replace(this.sourceWebService.host, '');
6679
}
67-
68-
// Get the destination schema.
69-
const destinationSchema = await this.getDestinationSchema();
70-
// Validate the destination data against the schema.
71-
const destinationValidated = this.validateData(destinationData, destinationSchema);
72-
if (!destinationValidated.valid) {
73-
this.outputToConsole(destinationValidated.errors, 'error');
74-
exit(2);
75-
}
76-
await this.sendDestinationData(destinationData);
7780
}
7881

7982
/**
@@ -135,17 +138,16 @@ class App {
135138
private transformSourceData(sourceData: DataItem[], mapFile: Mapper, destinationItem: MappedItem): MappedItem {
136139
// Transform
137140
this.outputToConsole('transforming source to destination');
138-
const indexOffset = (destinationItem.learning_experience_sets as MappedItem[]).length;
139141
// Map destination structure
140142
sourceData.forEach((sourceItem, index) => {
141-
(destinationItem.learning_experience_sets as MappedItem[])[index + indexOffset] = {};
143+
destinationItem[index] = {};
142144
Object.keys(mapFile).forEach((mapKey) => {
143145
const sourceKey = mapFile[mapKey];
144146
const value = JsonMapper.getValueFromSource(sourceKey, (sourceItem as unknown) as MappedItem);
145147
if (!value) {
146148
return;
147149
}
148-
JsonMapper.mapValueToDestinationObject(mapKey, value, (destinationItem.learning_experience_sets as MappedItem[])[index + indexOffset]);
150+
JsonMapper.mapValueToDestinationObject(mapKey, value, destinationItem[index] as MappedItem);
149151
});
150152
});
151153

@@ -164,6 +166,17 @@ class App {
164166
return destinationSchema;
165167
}
166168

169+
/**
170+
* Adds metadata_key and metadata_key_hash.
171+
* @param value The destination data.
172+
* @returns The destination data with hash.
173+
*/
174+
private addHashes(value: MappedItem): MappedItem {
175+
value["metadata_key_hash"] = md5(value.metadata as string);
176+
value["metadata_hash"] = md5(value.metadata_key as string);
177+
return value;
178+
}
179+
167180
/**
168181
* Outputs and/or sends the destination data.
169182
* @param data The formatted data.

src/mapper.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export default class JsonMapper {
2525
sourceKey :
2626
{
2727
"type": "string",
28-
"value": sourceKey
28+
"key": sourceKey
2929
};
3030
const className = source.type[0].toUpperCase() + source.type.slice(1);
3131
const mapType = `${className}Mapping`;

src/mapping/string.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { MappingInterface, MappedItem, MapSourceKey, BaseMapping } from './inter
22

33
export class StringMapping extends BaseMapping implements MappingInterface {
44
getValue(sourceKey: MapSourceKey, sourceItem: MappedItem): string[]|string|undefined {
5-
return this.getValueFromKey(sourceKey.value as string, sourceItem);
5+
const value = this.getValueFromKey(sourceKey.key as string, sourceItem);
6+
return sourceKey.prefix && value ? `${sourceKey.prefix}${value}` : value;
67
}
78
}

0 commit comments

Comments
 (0)