@magda/connector-sdk 2.3.1 → 2.3.2-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -218,6 +218,9 @@ export declare class ConnectionResult {
218
218
  distributionsConnected: number;
219
219
  recordsTrimmed: number;
220
220
  trimStillProcessing: boolean;
221
+ organizationsSkiped: number;
222
+ datasetsSkiped: number;
223
+ distributionsSkiped: number;
221
224
  aspectDefinitionFailures: AspectCreationFailure[];
222
225
  organizationFailures: RecordCreationFailure[];
223
226
  datasetFailures: RecordCreationFailure[];
@@ -255,6 +258,11 @@ export declare interface ConnectorSource {
255
258
  * before use ConnectorSource.presetRecordAspects as backup --- more for test cases
256
259
  */
257
260
  readonly presetRecordAspects?: JsonConnectorConfigPresetAspect[];
261
+ /**
262
+ * This field is not compulsory and JsonConnector will try to locate its value from commandline parameters
263
+ * before use ConnectorSource.customJsFilterCode as backup --- more for test cases
264
+ */
265
+ readonly customJsFilterCode?: string;
258
266
  /**
259
267
  * Get all of the datasets as pages of objects.
260
268
  *
@@ -398,7 +406,9 @@ export declare class JsonConnector {
398
406
  readonly maxConcurrency: number;
399
407
  readonly sourceTag?: string;
400
408
  readonly configData?: JsonConnectorConfig;
409
+ private readonly recordFilterFunction;
401
410
  constructor({ source, transformer, registry, maxConcurrency, sourceTag }: JsonConnectorOptions);
411
+ createRecordFilterFunction(): RecordFilterFunctionType;
402
412
  readConfigData(): JsonConnectorConfig;
403
413
  createAspectDefinitions(): Promise<ConnectionResult>;
404
414
  createOrganization(organizationJson: object): Promise<Record_2 | Error>;
@@ -437,6 +447,13 @@ export declare interface JsonConnectorConfig {
437
447
  ignoreOrganisationNames?: string[];
438
448
  extras?: JsonConnectorConfigExtraMetaData;
439
449
  presetRecordAspects?: JsonConnectorConfigPresetAspect[];
450
+ /**
451
+ * Custom JS code to filter out records
452
+ * The the following variables are available in scope:
453
+ * - jsonData: the original record json data before transformation
454
+ * - type: a string represent the type of the record. e.g. "Organization" | "Dataset" | "Distribution"
455
+ */
456
+ customJsFilterCode?: string;
440
457
  }
441
458
 
442
459
  /**
@@ -740,6 +757,8 @@ declare class RecordCreationFailure {
740
757
  constructor(id: ConnectorRecordId, parentId: ConnectorRecordId, error: Error);
741
758
  }
742
759
 
760
+ declare type RecordFilterFunctionType = (jsonData: any, type: "Dataset" | "Distribution" | "Organization") => boolean;
761
+
743
762
  declare class RecordHistoryApi {
744
763
  protected basePath: string;
745
764
  protected defaultHeaders: any;
@@ -839,9 +858,10 @@ declare class RecordsApi {
839
858
  * @param orderByDir Specify the order by direction. Either &#x60;asc&#x60; or &#x60;desc&#x60;
840
859
  * @param orderNullFirst Specify whether nulls appear before (&#x60;true&#x60;) or after (&#x60;false&#x60;) non-null values in the sort ordering.
841
860
  * @param reversePageTokenOrder When pagination via pageToken, by default, records with smaller pageToken (i.e. older records) will be returned first. When this parameter is set to &#x60;true&#x60;, higher pageToken records (newer records) will be returned.
861
+ * @param q full text search query
842
862
  * @param xMagdaSession Magda internal session id
843
863
  */
844
- getAll(xMagdaTenantId: number, aspect?: Array<string>, optionalAspect?: Array<string>, pageToken?: string, start?: number, limit?: number, dereference?: boolean, aspectQuery?: Array<string>, aspectOrQuery?: Array<string>, orderBy?: string, orderByDir?: string, orderNullFirst?: boolean, reversePageTokenOrder?: boolean, xMagdaSession?: string): Promise<{
864
+ getAll(xMagdaTenantId: number, aspect?: Array<string>, optionalAspect?: Array<string>, pageToken?: string, start?: number, limit?: number, dereference?: boolean, aspectQuery?: Array<string>, aspectOrQuery?: Array<string>, orderBy?: string, orderByDir?: string, orderNullFirst?: boolean, reversePageTokenOrder?: boolean, q?: string, xMagdaSession?: string): Promise<{
845
865
  response: http.IncomingMessage;
846
866
  body: Array<Record_2>;
847
867
  }>;
@@ -853,9 +873,10 @@ declare class RecordsApi {
853
873
  * @param start The index of the first record to retrieve. When possible, specify pageToken instead as it will result in better performance. If this parameter and pageToken are both specified, this parameter is interpreted as the index after the pageToken of the first record to retrieve.
854
874
  * @param limit The maximum number of records to receive. The response will include a token that can be passed as the pageToken parameter to a future request to continue receiving results where this query leaves off.
855
875
  * @param reversePageTokenOrder When pagination via pageToken, by default, records with smaller pageToken (i.e. older records) will be returned first. When this parameter is set to &#x60;true&#x60;, higher pageToken records (newer records) will be returned.
876
+ * @param q full text search query
856
877
  * @param xMagdaSession Magda internal session id
857
878
  */
858
- getAllSummary(xMagdaTenantId: number, pageToken?: string, start?: number, limit?: number, reversePageTokenOrder?: boolean, xMagdaSession?: string): Promise<{
879
+ getAllSummary(xMagdaTenantId: number, pageToken?: string, start?: number, limit?: number, reversePageTokenOrder?: boolean, q?: string, xMagdaSession?: string): Promise<{
859
880
  response: http.IncomingMessage;
860
881
  body: Array<RecordSummary>;
861
882
  }>;
@@ -902,9 +923,10 @@ declare class RecordsApi {
902
923
  * @param aspect The aspects for which to retrieve data, specified as multiple occurrences of this query parameter. Only records that have all of these aspects will be included in the response.
903
924
  * @param aspectQuery Filter the records returned by a value within the aspect JSON. Expressed as &#39;aspectId.path.to.field:value&#39;, url encoded. NOTE: This is an early stage API and may change greatly in the future
904
925
  * @param aspectOrQuery Filter the records returned by a value within the aspect JSON. Expressed as &#39;aspectId.path.to.field:value&#39;, url encoded. Queries passing via this parameter will be grouped with OR logic.
926
+ * @param q full text search query
905
927
  * @param xMagdaSession Magda internal session id
906
928
  */
907
- getCount(xMagdaTenantId: number, aspect?: Array<string>, aspectQuery?: Array<string>, aspectOrQuery?: Array<string>, xMagdaSession?: string): Promise<{
929
+ getCount(xMagdaTenantId: number, aspect?: Array<string>, aspectQuery?: Array<string>, aspectOrQuery?: Array<string>, q?: string, xMagdaSession?: string): Promise<{
908
930
  response: http.IncomingMessage;
909
931
  body: CountResponse;
910
932
  }>;
@@ -1035,7 +1057,7 @@ declare class RegistryClient {
1035
1057
  getRecord(id: string, aspect?: Array<string>, optionalAspect?: Array<string>, dereference?: boolean): Promise<Record_2 | ServerError>;
1036
1058
  getRecordAspect(id: string, aspectId: string): Promise<any | ServerError>;
1037
1059
  getRecordInFull(id: string): Promise<Record_2>;
1038
- getRecords<I extends Record_2>(aspect?: Array<string>, optionalAspect?: Array<string>, pageToken?: string, dereference?: boolean, limit?: number, aspectQueries?: string[], aspectOrQuery?: string[], orderBy?: string, orderByDir?: string, orderNullFirst?: boolean, reversePageTokenOrder?: boolean): Promise<RecordsPage<I> | ServerError>;
1060
+ getRecords<I extends Record_2>(aspect?: Array<string>, optionalAspect?: Array<string>, pageToken?: string, dereference?: boolean, limit?: number, aspectQueries?: string[], aspectOrQuery?: string[], orderBy?: string, orderByDir?: string, orderNullFirst?: boolean, reversePageTokenOrder?: boolean, q?: string): Promise<RecordsPage<I> | ServerError>;
1039
1061
  getRecordsPageTokens(aspect?: Array<string>, limit?: number): Promise<string[] | ServerError>;
1040
1062
  }
1041
1063
 
package/dist/index.js CHANGED
@@ -16906,9 +16906,10 @@ class RecordsApi {
16906
16906
  * @param orderByDir Specify the order by direction. Either &#x60;asc&#x60; or &#x60;desc&#x60;
16907
16907
  * @param orderNullFirst Specify whether nulls appear before (&#x60;true&#x60;) or after (&#x60;false&#x60;) non-null values in the sort ordering.
16908
16908
  * @param reversePageTokenOrder When pagination via pageToken, by default, records with smaller pageToken (i.e. older records) will be returned first. When this parameter is set to &#x60;true&#x60;, higher pageToken records (newer records) will be returned.
16909
+ * @param q full text search query
16909
16910
  * @param xMagdaSession Magda internal session id
16910
16911
  */
16911
- getAll(xMagdaTenantId, aspect, optionalAspect, pageToken, start, limit, dereference, aspectQuery, aspectOrQuery, orderBy, orderByDir, orderNullFirst, reversePageTokenOrder, xMagdaSession) {
16912
+ getAll(xMagdaTenantId, aspect, optionalAspect, pageToken, start, limit, dereference, aspectQuery, aspectOrQuery, orderBy, orderByDir, orderNullFirst, reversePageTokenOrder, q, xMagdaSession) {
16912
16913
  const localVarPath = this.basePath + '/records';
16913
16914
  let queryParameters = {};
16914
16915
  let headerParams = Object.assign({}, this.defaultHeaders);
@@ -16953,6 +16954,9 @@ class RecordsApi {
16953
16954
  if (reversePageTokenOrder !== undefined) {
16954
16955
  queryParameters['reversePageTokenOrder'] = reversePageTokenOrder;
16955
16956
  }
16957
+ if (q !== undefined) {
16958
+ queryParameters['q'] = q;
16959
+ }
16956
16960
  headerParams['X-Magda-Tenant-Id'] = xMagdaTenantId;
16957
16961
  headerParams['X-Magda-Session'] = xMagdaSession;
16958
16962
  let useFormData = false;
@@ -16997,9 +17001,10 @@ class RecordsApi {
16997
17001
  * @param start The index of the first record to retrieve. When possible, specify pageToken instead as it will result in better performance. If this parameter and pageToken are both specified, this parameter is interpreted as the index after the pageToken of the first record to retrieve.
16998
17002
  * @param limit The maximum number of records to receive. The response will include a token that can be passed as the pageToken parameter to a future request to continue receiving results where this query leaves off.
16999
17003
  * @param reversePageTokenOrder When pagination via pageToken, by default, records with smaller pageToken (i.e. older records) will be returned first. When this parameter is set to &#x60;true&#x60;, higher pageToken records (newer records) will be returned.
17004
+ * @param q full text search query
17000
17005
  * @param xMagdaSession Magda internal session id
17001
17006
  */
17002
- getAllSummary(xMagdaTenantId, pageToken, start, limit, reversePageTokenOrder, xMagdaSession) {
17007
+ getAllSummary(xMagdaTenantId, pageToken, start, limit, reversePageTokenOrder, q, xMagdaSession) {
17003
17008
  const localVarPath = this.basePath + '/records/summary';
17004
17009
  let queryParameters = {};
17005
17010
  let headerParams = Object.assign({}, this.defaultHeaders);
@@ -17020,6 +17025,9 @@ class RecordsApi {
17020
17025
  if (reversePageTokenOrder !== undefined) {
17021
17026
  queryParameters['reversePageTokenOrder'] = reversePageTokenOrder;
17022
17027
  }
17028
+ if (q !== undefined) {
17029
+ queryParameters['q'] = q;
17030
+ }
17023
17031
  headerParams['X-Magda-Tenant-Id'] = xMagdaTenantId;
17024
17032
  headerParams['X-Magda-Session'] = xMagdaSession;
17025
17033
  let useFormData = false;
@@ -17246,9 +17254,10 @@ class RecordsApi {
17246
17254
  * @param aspect The aspects for which to retrieve data, specified as multiple occurrences of this query parameter. Only records that have all of these aspects will be included in the response.
17247
17255
  * @param aspectQuery Filter the records returned by a value within the aspect JSON. Expressed as &#39;aspectId.path.to.field:value&#39;, url encoded. NOTE: This is an early stage API and may change greatly in the future
17248
17256
  * @param aspectOrQuery Filter the records returned by a value within the aspect JSON. Expressed as &#39;aspectId.path.to.field:value&#39;, url encoded. Queries passing via this parameter will be grouped with OR logic.
17257
+ * @param q full text search query
17249
17258
  * @param xMagdaSession Magda internal session id
17250
17259
  */
17251
- getCount(xMagdaTenantId, aspect, aspectQuery, aspectOrQuery, xMagdaSession) {
17260
+ getCount(xMagdaTenantId, aspect, aspectQuery, aspectOrQuery, q, xMagdaSession) {
17252
17261
  const localVarPath = this.basePath + '/records/count';
17253
17262
  let queryParameters = {};
17254
17263
  let headerParams = Object.assign({}, this.defaultHeaders);
@@ -17266,6 +17275,9 @@ class RecordsApi {
17266
17275
  if (aspectOrQuery !== undefined) {
17267
17276
  queryParameters['aspectOrQuery'] = aspectOrQuery;
17268
17277
  }
17278
+ if (q !== undefined) {
17279
+ queryParameters['q'] = q;
17280
+ }
17269
17281
  headerParams['X-Magda-Tenant-Id'] = xMagdaTenantId;
17270
17282
  headerParams['X-Magda-Session'] = xMagdaSession;
17271
17283
  let useFormData = false;
@@ -23535,6 +23547,12 @@ class ConnectionResult {
23535
23547
  this.distributionsConnected = 0;
23536
23548
  this.recordsTrimmed = 0;
23537
23549
  this.trimStillProcessing = false;
23550
+ // skipped organizations due to user supplied record filter function
23551
+ this.organizationsSkiped = 0;
23552
+ // skipped dataset records due to user supplied record filter function
23553
+ this.datasetsSkiped = 0;
23554
+ // skipped distribution records due to user supplied record filter function
23555
+ this.distributionsSkiped = 0;
23538
23556
  this.aspectDefinitionFailures = Array();
23539
23557
  this.organizationFailures = Array();
23540
23558
  this.datasetFailures = Array();
@@ -23551,6 +23569,9 @@ class ConnectionResult {
23551
23569
  "Distributions Connected: " + this.distributionsConnected + "\n";
23552
23570
  result +=
23553
23571
  "Organizations Connected: " + this.organizationsConnected + "\n";
23572
+ result += "Datasets Skipped: " + this.datasetsSkiped + "\n";
23573
+ result += "Distributions Skipped: " + this.distributionsSkiped + "\n";
23574
+ result += "Organizations Skipped: " + this.organizationsSkiped + "\n";
23554
23575
  result += "Records Trimmed: " + this.recordsTrimmed + "\n";
23555
23576
  if (this.trimStillProcessing) {
23556
23577
  result += "(trim still processing) \n";
@@ -23589,6 +23610,9 @@ class ConnectionResult {
23589
23610
  total.organizationsConnected += result.organizationsConnected;
23590
23611
  total.datasetsConnected += result.datasetsConnected;
23591
23612
  total.distributionsConnected += result.distributionsConnected;
23613
+ total.organizationsSkiped += result.organizationsSkiped;
23614
+ total.datasetsSkiped += result.datasetsSkiped;
23615
+ total.distributionsSkiped += result.distributionsSkiped;
23592
23616
  total.recordsTrimmed += result.recordsTrimmed;
23593
23617
  total.trimStillProcessing =
23594
23618
  result.trimStillProcessing || total.trimStillProcessing;
@@ -29850,8 +29874,8 @@ class RegistryClient {
29850
29874
  }
29851
29875
  });
29852
29876
  }
29853
- getRecords(aspect, optionalAspect, pageToken, dereference, limit, aspectQueries, aspectOrQuery, orderBy, orderByDir, orderNullFirst, reversePageTokenOrder) {
29854
- const operation = (pageToken) => () => this.recordsApi.getAll(this.tenantId, aspect, optionalAspect, pageToken, undefined, limit, dereference, aspectQueries, aspectOrQuery, orderBy, orderByDir, orderNullFirst, reversePageTokenOrder, this.jwt);
29877
+ getRecords(aspect, optionalAspect, pageToken, dereference, limit, aspectQueries, aspectOrQuery, orderBy, orderByDir, orderNullFirst, reversePageTokenOrder, q) {
29878
+ const operation = (pageToken) => () => this.recordsApi.getAll(this.tenantId, aspect, optionalAspect, pageToken, undefined, limit, dereference, aspectQueries, aspectOrQuery, orderBy, orderByDir, orderNullFirst, reversePageTokenOrder, q, this.jwt);
29855
29879
  return retry_1.default(operation(pageToken), this.secondsBetweenRetries, this.maxRetries, (e, retriesLeft) => console.log(formatServiceError_1.default("Failed to GET records.", e, retriesLeft)))
29856
29880
  .then((result) => result.body)
29857
29881
  .catch(exports.toServerError("getRecords"));
@@ -54134,8 +54158,19 @@ class JsonConnector {
54134
54158
  this.maxConcurrency = maxConcurrency;
54135
54159
  this.sourceTag = sourceTag;
54136
54160
  this.configData = this.readConfigData();
54161
+ this.recordFilterFunction = this.createRecordFilterFunction();
54162
+ }
54163
+ createRecordFilterFunction() {
54164
+ var _a;
54165
+ if (!((_a = this.configData) === null || _a === void 0 ? void 0 : _a.customJsFilterCode)) {
54166
+ return () => true;
54167
+ }
54168
+ const code = this.configData.customJsFilterCode;
54169
+ const filterFunction = new Function("jsonData", "type", code);
54170
+ return filterFunction;
54137
54171
  }
54138
54172
  readConfigData() {
54173
+ var _a, _b;
54139
54174
  try {
54140
54175
  const argv = yargs_1.parse(process_1.default.argv);
54141
54176
  if (!argv) {
@@ -54154,6 +54189,9 @@ class JsonConnector {
54154
54189
  if (this.source.presetRecordAspects) {
54155
54190
  configData.presetRecordAspects = this.source.presetRecordAspects;
54156
54191
  }
54192
+ if ((_a = this.source) === null || _a === void 0 ? void 0 : _a.customJsFilterCode) {
54193
+ configData.customJsFilterCode = (_b = this.source) === null || _b === void 0 ? void 0 : _b.customJsFilterCode;
54194
+ }
54157
54195
  }
54158
54196
  else {
54159
54197
  configData = {
@@ -54166,6 +54204,9 @@ class JsonConnector {
54166
54204
  if (argv.presetRecordAspects) {
54167
54205
  configData.presetRecordAspects = argv.presetRecordAspects;
54168
54206
  }
54207
+ if (argv.customJsFilterCode) {
54208
+ configData.customJsFilterCode = argv.customJsFilterCode;
54209
+ }
54169
54210
  }
54170
54211
  }
54171
54212
  else {
@@ -54233,6 +54274,10 @@ class JsonConnector {
54233
54274
  if (!organization) {
54234
54275
  return;
54235
54276
  }
54277
+ if (this.recordFilterFunction(organization, "Organization") === false) {
54278
+ result.organizationsSkiped++;
54279
+ return;
54280
+ }
54236
54281
  const recordOrError = yield this.createOrganization(organization);
54237
54282
  if (recordOrError instanceof Error) {
54238
54283
  result.organizationFailures.push(new RecordCreationFailure_1.default(this.transformer.getIdFromJsonOrganization(organization, this.source.id), undefined, recordOrError));
@@ -54250,11 +54295,19 @@ class JsonConnector {
54250
54295
  const result = new ConnectionResult_1.default();
54251
54296
  const datasets = this.source.getJsonDatasets();
54252
54297
  yield AsyncPage_1.forEachAsync(datasets, this.maxConcurrency, (dataset) => __awaiter(this, void 0, void 0, function* () {
54298
+ if (this.recordFilterFunction(dataset, "Dataset") === false) {
54299
+ result.datasetsSkiped++;
54300
+ return;
54301
+ }
54253
54302
  const record = this.transformer.datasetJsonToRecord(dataset);
54254
54303
  const distributions = this.source.getJsonDistributions(dataset);
54255
54304
  if (distributions) {
54256
54305
  const distributionIds = [];
54257
54306
  yield AsyncPage_1.forEachAsync(distributions, 1, (distribution) => __awaiter(this, void 0, void 0, function* () {
54307
+ if (this.recordFilterFunction(distribution, "Distribution") === false) {
54308
+ result.distributionsSkiped++;
54309
+ return;
54310
+ }
54258
54311
  const recordOrError = yield this.createDistribution(distribution, dataset);
54259
54312
  if (recordOrError instanceof Error) {
54260
54313
  result.distributionFailures.push(new RecordCreationFailure_1.default(this.transformer.getIdFromJsonDistribution(distribution, dataset, this.source.id), this.transformer.getIdFromJsonDataset(dataset, this.source.id), recordOrError));
@@ -54281,15 +54334,20 @@ class JsonConnector {
54281
54334
  if (publisher) {
54282
54335
  const publisherId = this.transformer.getIdFromJsonOrganization(publisher, this.source.id);
54283
54336
  if (publisherId) {
54284
- const recordOrError = yield this.createOrganization(publisher);
54285
- if (recordOrError instanceof Error) {
54286
- result.organizationFailures.push(new RecordCreationFailure_1.default(publisherId, undefined, recordOrError));
54337
+ if (this.recordFilterFunction(publisher, "Organization") === false) {
54338
+ result.distributionsSkiped++;
54287
54339
  }
54288
54340
  else {
54289
- record.aspects["dataset-publisher"] = {
54290
- publisher: publisherId.toString()
54291
- };
54292
- ++result.organizationsConnected;
54341
+ const recordOrError = yield this.createOrganization(publisher);
54342
+ if (recordOrError instanceof Error) {
54343
+ result.organizationFailures.push(new RecordCreationFailure_1.default(publisherId, undefined, recordOrError));
54344
+ }
54345
+ else {
54346
+ record.aspects["dataset-publisher"] = {
54347
+ publisher: publisherId.toString()
54348
+ };
54349
+ ++result.organizationsConnected;
54350
+ }
54293
54351
  }
54294
54352
  }
54295
54353
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@magda/connector-sdk",
3
3
  "description": "MAGDA Connector SDK",
4
- "version": "2.3.1",
4
+ "version": "2.3.2-alpha.1",
5
5
  "scripts": {
6
6
  "prebuild": "rimraf dist tsconfig.tsbuildinfo",
7
7
  "compile": "webpack && webpack --env.target=web",
@@ -14,7 +14,7 @@
14
14
  "main": "dist/index.js",
15
15
  "browser": "dist/index-web.js",
16
16
  "devDependencies": {
17
- "@magda/typescript-common": "^2.3.1",
17
+ "@magda/typescript-common": "^2.3.2-alpha.1",
18
18
  "@microsoft/api-extractor": "7.15.2",
19
19
  "ts-loader": "^6.2.1",
20
20
  "typescript": "~4.2.4",