@opentermsarchive/engine 0.26.1 → 0.27.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.
Files changed (60) hide show
  1. package/README.md +1 -3
  2. package/bin/ota-track.js +3 -3
  3. package/bin/ota-validate.js +2 -2
  4. package/bin/ota.js +1 -1
  5. package/config/default.json +1 -1
  6. package/package.json +3 -4
  7. package/scripts/dataset/export/index.js +4 -4
  8. package/scripts/dataset/export/index.test.js +11 -17
  9. package/scripts/declarations/lint/index.mocha.js +1 -1
  10. package/scripts/declarations/utils/index.js +12 -12
  11. package/scripts/declarations/validate/definitions.js +1 -1
  12. package/scripts/declarations/validate/index.mocha.js +30 -34
  13. package/scripts/declarations/validate/service.history.schema.js +11 -11
  14. package/scripts/declarations/validate/service.schema.js +13 -13
  15. package/scripts/history/migrate-services.js +4 -4
  16. package/scripts/history/update-to-full-hash.js +2 -2
  17. package/scripts/import/index.js +14 -14
  18. package/scripts/rewrite/rewrite-snapshots.js +3 -3
  19. package/scripts/rewrite/rewrite-versions.js +14 -14
  20. package/scripts/utils/renamer/README.md +3 -3
  21. package/scripts/utils/renamer/index.js +13 -13
  22. package/src/archivist/errors.js +1 -1
  23. package/src/archivist/extract/exports.js +3 -0
  24. package/src/archivist/{filter → extract}/index.js +23 -27
  25. package/src/archivist/extract/index.test.js +516 -0
  26. package/src/archivist/index.js +101 -140
  27. package/src/archivist/index.test.js +178 -166
  28. package/src/archivist/recorder/index.js +11 -55
  29. package/src/archivist/recorder/index.test.js +310 -356
  30. package/src/archivist/recorder/record.js +18 -7
  31. package/src/archivist/recorder/repositories/git/dataMapper.js +41 -31
  32. package/src/archivist/recorder/repositories/git/index.js +11 -15
  33. package/src/archivist/recorder/repositories/git/index.test.js +1058 -463
  34. package/src/archivist/recorder/repositories/interface.js +8 -6
  35. package/src/archivist/recorder/repositories/mongo/dataMapper.js +21 -14
  36. package/src/archivist/recorder/repositories/mongo/index.js +8 -8
  37. package/src/archivist/recorder/repositories/mongo/index.test.js +898 -479
  38. package/src/archivist/recorder/snapshot.js +5 -0
  39. package/src/archivist/recorder/snapshot.test.js +65 -0
  40. package/src/archivist/recorder/version.js +14 -0
  41. package/src/archivist/recorder/version.test.js +65 -0
  42. package/src/archivist/services/index.js +60 -51
  43. package/src/archivist/services/index.test.js +63 -83
  44. package/src/archivist/services/service.js +26 -22
  45. package/src/archivist/services/service.test.js +46 -68
  46. package/src/archivist/services/{pageDeclaration.js → sourceDocument.js} +11 -9
  47. package/src/archivist/services/{pageDeclaration.test.js → sourceDocument.test.js} +21 -21
  48. package/src/archivist/services/terms.js +26 -0
  49. package/src/archivist/services/{documentDeclaration.test.js → terms.test.js} +15 -15
  50. package/src/exports.js +2 -2
  51. package/src/index.js +16 -13
  52. package/src/logger/index.js +35 -36
  53. package/src/notifier/index.js +8 -8
  54. package/src/tracker/index.js +6 -6
  55. package/src/archivist/filter/exports.js +0 -3
  56. package/src/archivist/filter/index.test.js +0 -564
  57. package/src/archivist/recorder/record.test.js +0 -91
  58. package/src/archivist/services/documentDeclaration.js +0 -26
  59. /package/scripts/utils/renamer/rules/{documentTypes.json → termsTypes.json} +0 -0
  60. /package/scripts/utils/renamer/rules/{documentTypesByService.json → termsTypesByService.json} +0 -0
@@ -1,60 +1,64 @@
1
1
  export default class Service {
2
- documents = new Map();
2
+ terms = new Map();
3
3
 
4
4
  constructor({ id, name }) {
5
5
  this.id = id;
6
6
  this.name = name;
7
7
  }
8
8
 
9
- getDocumentDeclaration(documentType, date) {
10
- if (!this.documents[documentType]) {
9
+ getTerms(termsType, date) {
10
+ if (!this.terms[termsType]) {
11
11
  return null;
12
12
  }
13
13
 
14
- const { latest: currentlyValidDocumentDeclaration, history } = this.documents[documentType];
14
+ const { latest: currentlyValidTerms, history } = this.terms[termsType];
15
15
 
16
16
  if (!date) {
17
- return currentlyValidDocumentDeclaration;
17
+ return currentlyValidTerms;
18
18
  }
19
19
 
20
20
  return (
21
21
  history?.find(entry => new Date(date) <= new Date(entry.validUntil))
22
- || currentlyValidDocumentDeclaration
22
+ || currentlyValidTerms
23
23
  );
24
24
  }
25
25
 
26
- getDocumentTypes() {
27
- return Object.keys(this.documents);
26
+ getTermsTypes() {
27
+ return Object.keys(this.terms);
28
28
  }
29
29
 
30
- addDocumentDeclaration(document) {
31
- if (!document.service) {
32
- document.service = this;
30
+ addTerms(terms) {
31
+ if (!terms.service) {
32
+ terms.service = this;
33
33
  }
34
34
 
35
- this.documents[document.type] = this.documents[document.type] || {};
35
+ this.terms[terms.type] = this.terms[terms.type] || {};
36
36
 
37
- if (!document.validUntil) {
38
- this.documents[document.type].latest = document;
37
+ if (!terms.validUntil) {
38
+ this.terms[terms.type].latest = terms;
39
39
 
40
40
  return;
41
41
  }
42
42
 
43
- this.documents[document.type].history = this.documents[document.type].history || [];
44
- this.documents[document.type].history.push(document);
45
- this.documents[document.type].history.sort((a, b) => new Date(a.validUntil) - new Date(b.validUntil));
43
+ this.terms[terms.type].history = this.terms[terms.type].history || [];
44
+ this.terms[terms.type].history.push(terms);
45
+ this.terms[terms.type].history.sort((a, b) => new Date(a.validUntil) - new Date(b.validUntil));
46
46
  }
47
47
 
48
- getHistoryDates(documentType) {
49
- return this.documents[documentType].history.map(entry => entry.validUntil);
48
+ getHistoryDates(termsType) {
49
+ return this.terms[termsType].history.map(entry => entry.validUntil);
50
50
  }
51
51
 
52
- getNumberOfDocuments() {
53
- return this.getDocumentTypes().length;
52
+ getNumberOfTerms() {
53
+ return this.getTermsTypes().length;
54
54
  }
55
55
 
56
56
  hasHistory() {
57
57
  // If a service is loaded without its history it could return false even if a history declaration file exists.
58
- return Boolean(Object.keys(this.documents).find(documentType => this.documents[documentType].history));
58
+ return Boolean(Object.keys(this.terms).find(termsType => this.terms[termsType].history));
59
+ }
60
+
61
+ static getNumberOfTerms(services, servicesIds) {
62
+ return servicesIds.reduce((acc, serviceId) => acc + services[serviceId].getNumberOfTerms(), 0);
59
63
  }
60
64
  }
@@ -1,135 +1,119 @@
1
1
  import chai from 'chai';
2
2
 
3
- import DocumentDeclaration from './documentDeclaration.js';
4
3
  import Service from './service.js';
4
+ import Terms from './terms.js';
5
5
 
6
6
  const { expect } = chai;
7
7
 
8
8
  describe('Service', () => {
9
9
  let subject;
10
- const DOCUMENT_TYPE = 'Terms of Service';
10
+ const TERMS_TYPE = 'Terms of Service';
11
11
 
12
- describe('#addDocumentDeclaration', () => {
13
- let documentDeclaration;
12
+ describe('#addTerms', () => {
13
+ let terms;
14
14
 
15
15
  before(async () => {
16
- documentDeclaration = new DocumentDeclaration({
17
- type: DOCUMENT_TYPE,
16
+ terms = new Terms({
17
+ type: TERMS_TYPE,
18
18
  service: subject,
19
- pages: [{
20
- location: 'https://www.service.example/tos',
21
- contentSelectors: 'body',
22
- }],
23
19
  });
24
20
  });
25
21
 
26
- context('when document declaration has no validity date', () => {
22
+ context('when terms declaration has no validity date', () => {
27
23
  before(async () => {
28
24
  subject = new Service({ id: 'serviceID', name: 'serviceName' });
29
- subject.addDocumentDeclaration(documentDeclaration);
25
+ subject.addTerms(terms);
30
26
  });
31
27
 
32
- it('adds the document as the last valid document declaration', async () => {
33
- expect(subject.getDocumentDeclaration(DOCUMENT_TYPE)).to.deep.eql(documentDeclaration);
28
+ it('adds the terms as the last valid terms declaration', async () => {
29
+ expect(subject.getTerms(TERMS_TYPE)).to.deep.eql(terms);
34
30
  });
35
31
  });
36
32
 
37
- context('when document declaration has a validity date', () => {
38
- let expiredDocumentDeclaration;
33
+ context('when terms declaration has a validity date', () => {
34
+ let expiredTerms;
39
35
  const VALIDITY_DATE = new Date('2020-07-22T11:30:21.000Z');
40
36
 
41
37
  before(async () => {
42
38
  subject = new Service({ id: 'serviceID', name: 'serviceName' });
43
- expiredDocumentDeclaration = new DocumentDeclaration({
44
- type: 'Terms of Service',
39
+ expiredTerms = new Terms({
40
+ type: TERMS_TYPE,
45
41
  service: subject,
46
42
  validUntil: VALIDITY_DATE,
47
- pages: [{
48
- location: 'https://www.service.example/terms',
49
- contentSelectors: 'main',
50
- }],
51
43
  });
52
- subject.addDocumentDeclaration(expiredDocumentDeclaration);
53
- subject.addDocumentDeclaration(documentDeclaration);
44
+ subject.addTerms(expiredTerms);
45
+ subject.addTerms(terms);
54
46
  });
55
47
 
56
- it('adds the document with the proper validity date', async () => {
57
- expect(subject.getDocumentDeclaration(DOCUMENT_TYPE, VALIDITY_DATE)).to.deep.eql(expiredDocumentDeclaration);
48
+ it('adds the terms with the proper validity date', async () => {
49
+ expect(subject.getTerms(TERMS_TYPE, VALIDITY_DATE)).to.deep.eql(expiredTerms);
58
50
  });
59
51
  });
60
52
  });
61
53
 
62
- describe('#getDocumentDeclaration', () => {
54
+ describe('#getTerms', () => {
63
55
  let subject;
64
56
 
65
- const lastDeclaration = new DocumentDeclaration({
66
- type: 'Terms of Service',
67
- location: 'https://www.service.example/tos',
68
- contentSelectors: 'body',
69
- });
57
+ const lastDeclaration = new Terms({ type: TERMS_TYPE });
70
58
 
71
59
  context('when there is no history', () => {
72
60
  before(async () => {
73
61
  subject = new Service({ id: 'serviceID', name: 'serviceName' });
74
- subject.addDocumentDeclaration(lastDeclaration);
62
+ subject.addTerms(lastDeclaration);
75
63
  });
76
64
 
77
65
  context('without given date', () => {
78
- it('returns the last document declaration', async () => {
79
- expect(subject.getDocumentDeclaration(DOCUMENT_TYPE)).to.eql(lastDeclaration);
66
+ it('returns the last terms declaration', async () => {
67
+ expect(subject.getTerms(TERMS_TYPE)).to.eql(lastDeclaration);
80
68
  });
81
69
  });
82
70
 
83
71
  context('with a date', () => {
84
- it('returns the last document declaration', async () => {
85
- expect(subject.getDocumentDeclaration(DOCUMENT_TYPE, '2020-08-21T11:30:21.000Z')).to.eql(lastDeclaration);
72
+ it('returns the last terms declaration', async () => {
73
+ expect(subject.getTerms(TERMS_TYPE, '2020-08-21T11:30:21.000Z')).to.eql(lastDeclaration);
86
74
  });
87
75
  });
88
76
  });
89
77
 
90
- context('when the document has a history', () => {
91
- const firstDeclaration = new DocumentDeclaration({
92
- type: 'Terms of Service',
93
- location: 'https://www.service.example/terms',
94
- contentSelectors: 'main',
78
+ context('when the terms have a history', () => {
79
+ const firstDeclaration = new Terms({
80
+ type: TERMS_TYPE,
95
81
  validUntil: '2020-07-22T11:30:21.000Z',
96
82
  });
97
83
 
98
- const secondDeclaration = new DocumentDeclaration({
99
- type: 'Terms of Service',
100
- location: 'https://www.service.example/terms-of-service',
101
- contentSelectors: 'main',
84
+ const secondDeclaration = new Terms({
85
+ type: TERMS_TYPE,
102
86
  validUntil: '2020-08-22T11:30:21.000Z',
103
87
  });
104
88
 
105
89
  before(async () => {
106
90
  subject = new Service({ id: 'serviceID', name: 'serviceName' });
107
- subject.addDocumentDeclaration(lastDeclaration);
108
- subject.addDocumentDeclaration(firstDeclaration);
109
- subject.addDocumentDeclaration(secondDeclaration);
91
+ subject.addTerms(lastDeclaration);
92
+ subject.addTerms(firstDeclaration);
93
+ subject.addTerms(secondDeclaration);
110
94
  });
111
95
 
112
96
  context('without given date', () => {
113
- it('returns the last document declaration', async () => {
114
- expect(subject.getDocumentDeclaration(DOCUMENT_TYPE)).to.eql(lastDeclaration);
97
+ it('returns the last terms declaration', async () => {
98
+ expect(subject.getTerms(TERMS_TYPE)).to.eql(lastDeclaration);
115
99
  });
116
100
  });
117
101
 
118
102
  context('with a date', () => {
119
- it('returns the document declaration according to the given date', async () => {
120
- expect(subject.getDocumentDeclaration(DOCUMENT_TYPE, '2020-08-21T11:30:21.000Z')).to.eql(secondDeclaration);
103
+ it('returns the terms declaration according to the given date', async () => {
104
+ expect(subject.getTerms(TERMS_TYPE, '2020-08-21T11:30:21.000Z')).to.eql(secondDeclaration);
121
105
  });
122
106
 
123
- context('strictly equal to a document declaration validity date', () => {
124
- it('returns the document declaration with the validity date equal to the given date', async () => {
125
- expect(subject.getDocumentDeclaration(DOCUMENT_TYPE, secondDeclaration.validUntil)).to.eql(secondDeclaration);
107
+ context('strictly equal to a terms declaration validity date', () => {
108
+ it('returns the terms declaration with the validity date equal to the given date', async () => {
109
+ expect(subject.getTerms(TERMS_TYPE, secondDeclaration.validUntil)).to.eql(secondDeclaration);
126
110
  });
127
111
  });
128
112
  });
129
113
  });
130
114
  });
131
115
 
132
- describe('#getDocumentTypes', () => {
116
+ describe('#getTermsTypes', () => {
133
117
  let subject;
134
118
  let termsOfServiceDeclaration;
135
119
  let privacyPolicyDeclaration;
@@ -137,25 +121,19 @@ describe('Service', () => {
137
121
  before(async () => {
138
122
  subject = new Service({ id: 'serviceID', name: 'serviceName' });
139
123
 
140
- termsOfServiceDeclaration = new DocumentDeclaration({
141
- type: 'Terms of Service',
142
- location: 'https://www.service.example/tos',
143
- contentSelectors: 'body',
144
- });
124
+ termsOfServiceDeclaration = new Terms({ type: TERMS_TYPE });
145
125
 
146
- privacyPolicyDeclaration = new DocumentDeclaration({
126
+ privacyPolicyDeclaration = new Terms({
147
127
  type: 'Privacy Policy',
148
- location: 'https://www.service.example/terms',
149
- contentSelectors: 'main',
150
128
  validUntil: '2020-07-22T11:30:21.000Z',
151
129
  });
152
130
 
153
- subject.addDocumentDeclaration(termsOfServiceDeclaration);
154
- subject.addDocumentDeclaration(privacyPolicyDeclaration);
131
+ subject.addTerms(termsOfServiceDeclaration);
132
+ subject.addTerms(privacyPolicyDeclaration);
155
133
  });
156
134
 
157
135
  it('returns the service terms types', async () => {
158
- expect(subject.getDocumentTypes()).to.have.members([
136
+ expect(subject.getTermsTypes()).to.have.members([
159
137
  termsOfServiceDeclaration.type,
160
138
  privacyPolicyDeclaration.type,
161
139
  ]);
@@ -1,19 +1,21 @@
1
- export default class PageDeclaration {
2
- constructor({ location, executeClientScripts, contentSelectors, noiseSelectors, filters }) {
1
+ export default class SourceDocument {
2
+ constructor({ location, executeClientScripts, contentSelectors, insignificantContentSelectors, filters, content, mimeType }) {
3
3
  this.location = location;
4
4
  this.executeClientScripts = executeClientScripts;
5
5
  this.contentSelectors = contentSelectors;
6
- this.noiseSelectors = noiseSelectors;
6
+ this.insignificantContentSelectors = insignificantContentSelectors;
7
7
  this.filters = filters;
8
+ this.content = content;
9
+ this.mimeType = mimeType;
8
10
  this.id = new URL(location).pathname.split('/').filter(Boolean).join('-');
9
11
  }
10
12
 
11
13
  get cssSelectors() {
12
- const { contentSelectors, noiseSelectors } = this;
14
+ const { contentSelectors, insignificantContentSelectors } = this;
13
15
 
14
16
  const result = [
15
- ...PageDeclaration.extractCssSelectorsFromProperty(contentSelectors),
16
- ...PageDeclaration.extractCssSelectorsFromProperty(noiseSelectors),
17
+ ...SourceDocument.extractCssSelectorsFromProperty(contentSelectors),
18
+ ...SourceDocument.extractCssSelectorsFromProperty(insignificantContentSelectors),
17
19
  ];
18
20
 
19
21
  return result.filter(selector => selector);
@@ -23,10 +25,10 @@ export default class PageDeclaration {
23
25
  if (Array.isArray(property)) {
24
26
  return []
25
27
  .concat(property)
26
- .flatMap(selector => PageDeclaration.extractCssSelectorsFromSelector(selector));
28
+ .flatMap(selector => SourceDocument.extractCssSelectorsFromSelector(selector));
27
29
  }
28
30
 
29
- return PageDeclaration.extractCssSelectorsFromSelector(property);
31
+ return SourceDocument.extractCssSelectorsFromSelector(property);
30
32
  }
31
33
 
32
34
  static extractCssSelectorsFromSelector(selector) {
@@ -43,7 +45,7 @@ export default class PageDeclaration {
43
45
  return {
44
46
  fetch: this.location,
45
47
  select: this.contentSelectors,
46
- remove: this.noiseSelectors,
48
+ remove: this.insignificantContentSelectors,
47
49
  filter: this.filters ? this.filters.map(filter => filter.name) : undefined,
48
50
  executeClientScripts: this.executeClientScripts,
49
51
  };
@@ -1,17 +1,17 @@
1
1
  import chai from 'chai';
2
2
 
3
- import PageDeclaration from './pageDeclaration.js';
3
+ import SourceDocument from './sourceDocument.js';
4
4
 
5
5
  const { expect } = chai;
6
6
 
7
- describe('PageDeclaration', () => {
7
+ describe('SourceDocument', () => {
8
8
  const URL = 'https://www.service.example/terms';
9
9
 
10
10
  describe('#getCssSelectors', () => {
11
11
  context('with "select" property', () => {
12
12
  context('with string selector', () => {
13
13
  it('extracts selectors', async () => {
14
- const result = new PageDeclaration({ location: URL, contentSelectors: 'body' }).cssSelectors;
14
+ const result = new SourceDocument({ location: URL, contentSelectors: 'body' }).cssSelectors;
15
15
 
16
16
  expect(result).to.deep.equal(['body']);
17
17
  });
@@ -19,7 +19,7 @@ describe('PageDeclaration', () => {
19
19
 
20
20
  context('with range selector', () => {
21
21
  it('extracts selectors', async () => {
22
- const result = new PageDeclaration({
22
+ const result = new SourceDocument({
23
23
  location: URL,
24
24
  contentSelectors: {
25
25
  startBefore: '#startBefore',
@@ -33,7 +33,7 @@ describe('PageDeclaration', () => {
33
33
 
34
34
  context('with an array of mixed selectors', () => {
35
35
  it('extracts selectors', async () => {
36
- const result = new PageDeclaration({
36
+ const result = new SourceDocument({
37
37
  location: URL,
38
38
  contentSelectors: [
39
39
  {
@@ -52,7 +52,7 @@ describe('PageDeclaration', () => {
52
52
  context('with "remove" property', () => {
53
53
  context('with string selector', () => {
54
54
  it('extracts selectors', async () => {
55
- const result = new PageDeclaration({ location: URL, noiseSelectors: 'body' }).cssSelectors;
55
+ const result = new SourceDocument({ location: URL, insignificantContentSelectors: 'body' }).cssSelectors;
56
56
 
57
57
  expect(result).to.deep.equal(['body']);
58
58
  });
@@ -60,9 +60,9 @@ describe('PageDeclaration', () => {
60
60
 
61
61
  context('with range selector', () => {
62
62
  it('extracts selectors', async () => {
63
- const result = new PageDeclaration({
63
+ const result = new SourceDocument({
64
64
  location: URL,
65
- noiseSelectors: {
65
+ insignificantContentSelectors: {
66
66
  startBefore: '#startBefore',
67
67
  endBefore: '#endBefore',
68
68
  },
@@ -74,9 +74,9 @@ describe('PageDeclaration', () => {
74
74
 
75
75
  context('with an array of mixed selectors', () => {
76
76
  it('extracts selectors', async () => {
77
- const result = new PageDeclaration({
77
+ const result = new SourceDocument({
78
78
  location: URL,
79
- noiseSelectors: [
79
+ insignificantContentSelectors: [
80
80
  {
81
81
  startBefore: '#startBefore',
82
82
  endBefore: '#endBefore',
@@ -93,10 +93,10 @@ describe('PageDeclaration', () => {
93
93
  context('with both "select" and "remove" property', () => {
94
94
  context('with string selector', () => {
95
95
  it('extracts selectors', async () => {
96
- const result = new PageDeclaration({
96
+ const result = new SourceDocument({
97
97
  location: URL,
98
98
  contentSelectors: 'body',
99
- noiseSelectors: 'h1',
99
+ insignificantContentSelectors: 'h1',
100
100
  }).cssSelectors;
101
101
 
102
102
  expect(result).to.deep.equal([ 'body', 'h1' ]);
@@ -105,13 +105,13 @@ describe('PageDeclaration', () => {
105
105
 
106
106
  context('with range selector', () => {
107
107
  it('extracts selectors', async () => {
108
- const result = new PageDeclaration({
108
+ const result = new SourceDocument({
109
109
  location: URL,
110
110
  contentSelectors: {
111
111
  startBefore: '#startBefore',
112
112
  endBefore: '#endBefore',
113
113
  },
114
- noiseSelectors: {
114
+ insignificantContentSelectors: {
115
115
  startBefore: '#startBefore',
116
116
  endBefore: '#endBefore',
117
117
  },
@@ -128,7 +128,7 @@ describe('PageDeclaration', () => {
128
128
 
129
129
  context('with an array of mixed selectors', () => {
130
130
  it('extracts selectors', async () => {
131
- const result = new PageDeclaration({
131
+ const result = new SourceDocument({
132
132
  location: URL,
133
133
  contentSelectors: [
134
134
  {
@@ -137,7 +137,7 @@ describe('PageDeclaration', () => {
137
137
  },
138
138
  'body',
139
139
  ],
140
- noiseSelectors: [
140
+ insignificantContentSelectors: [
141
141
  {
142
142
  startBefore: '#startBefore',
143
143
  endBefore: '#endBefore',
@@ -160,8 +160,8 @@ describe('PageDeclaration', () => {
160
160
  });
161
161
 
162
162
  describe('#toPersistence', () => {
163
- it('converts basic page declaration into JSON representation', async () => {
164
- const result = new PageDeclaration({
163
+ it('converts basic source document declarations into JSON representation', async () => {
164
+ const result = new SourceDocument({
165
165
  location: URL,
166
166
  contentSelectors: 'body',
167
167
  }).toPersistence();
@@ -177,8 +177,8 @@ describe('PageDeclaration', () => {
177
177
  expect(result).to.deep.equal(expectedResult);
178
178
  });
179
179
 
180
- it('converts page declaration with all fields to JSON representation', async () => {
181
- const result = new PageDeclaration({
180
+ it('converts full source document declarations to JSON representation', async () => {
181
+ const result = new SourceDocument({
182
182
  location: URL,
183
183
  contentSelectors: [
184
184
  {
@@ -187,7 +187,7 @@ describe('PageDeclaration', () => {
187
187
  },
188
188
  'body',
189
189
  ],
190
- noiseSelectors: [
190
+ insignificantContentSelectors: [
191
191
  {
192
192
  startBefore: '#startBefore',
193
193
  endBefore: '#endBefore',
@@ -0,0 +1,26 @@
1
+ export default class Terms {
2
+ constructor({ service, type, sourceDocuments, validUntil }) {
3
+ this.service = service;
4
+ this.type = type;
5
+ this.sourceDocuments = sourceDocuments;
6
+
7
+ if (validUntil) {
8
+ this.validUntil = validUntil;
9
+ }
10
+ }
11
+
12
+ get hasMultipleSourceDocuments() {
13
+ return this.sourceDocuments.length > 1;
14
+ }
15
+
16
+ toPersistence() {
17
+ return {
18
+ name: this.service.name,
19
+ documents: {
20
+ [this.type]: this.hasMultipleSourceDocuments
21
+ ? { combine: this.sourceDocuments.map(sourceDocument => sourceDocument.toPersistence()) }
22
+ : this.sourceDocuments[0].toPersistence(),
23
+ },
24
+ };
25
+ }
26
+ }
@@ -1,15 +1,15 @@
1
1
  import chai from 'chai';
2
2
 
3
- import DocumentDeclaration from './documentDeclaration.js';
4
- import PageDeclaration from './pageDeclaration.js';
3
+ import SourceDocument from './sourceDocument.js';
4
+ import Terms from './terms.js';
5
5
 
6
6
  const { expect } = chai;
7
7
 
8
- describe('DocumentDeclaration', () => {
8
+ describe('Terms', () => {
9
9
  const service = { name: 'Service' };
10
- const type = 'Terms of Service';
10
+ const termsType = 'Terms of Service';
11
11
  const URL = 'https://www.service.example/terms';
12
- const page1 = new PageDeclaration({
12
+ const document1 = new SourceDocument({
13
13
  location: URL,
14
14
  contentSelectors: [
15
15
  {
@@ -18,7 +18,7 @@ describe('DocumentDeclaration', () => {
18
18
  },
19
19
  'body',
20
20
  ],
21
- noiseSelectors: [
21
+ insignificantContentSelectors: [
22
22
  {
23
23
  startBefore: '#startBefore',
24
24
  endBefore: '#endBefore',
@@ -26,7 +26,7 @@ describe('DocumentDeclaration', () => {
26
26
  'body',
27
27
  ],
28
28
  });
29
- const page1AsJSON = {
29
+ const document1AsJSON = {
30
30
  fetch: URL,
31
31
  select: [
32
32
  {
@@ -46,12 +46,12 @@ describe('DocumentDeclaration', () => {
46
46
  executeClientScripts: undefined,
47
47
  };
48
48
 
49
- const page2 = new PageDeclaration({
49
+ const document2 = new SourceDocument({
50
50
  location: URL,
51
51
  contentSelectors: 'body',
52
52
  });
53
53
 
54
- const page2AsJSON = {
54
+ const document2AsJSON = {
55
55
  fetch: URL,
56
56
  select: 'body',
57
57
  remove: undefined,
@@ -60,23 +60,23 @@ describe('DocumentDeclaration', () => {
60
60
  };
61
61
 
62
62
  describe('#toPersistence', () => {
63
- it('converts one page document to JSON representation', async () => {
64
- const result = new DocumentDeclaration({ service, type, pages: [page1] }).toPersistence();
63
+ it('converts terms with single source document to JSON representation', async () => {
64
+ const result = new Terms({ service, type: termsType, sourceDocuments: [document1] }).toPersistence();
65
65
 
66
66
  const expectedResult = {
67
67
  name: service.name,
68
- documents: { [type]: page1AsJSON },
68
+ documents: { [termsType]: document1AsJSON },
69
69
  };
70
70
 
71
71
  expect(result).to.deep.equal(expectedResult);
72
72
  });
73
73
 
74
- it('converts multipage document to JSON representation', async () => {
75
- const result = new DocumentDeclaration({ service, type, pages: [ page1, page2 ] }).toPersistence();
74
+ it('converts terms with multiple source documents to JSON representation', async () => {
75
+ const result = new Terms({ service, type: termsType, sourceDocuments: [ document1, document2 ] }).toPersistence();
76
76
 
77
77
  const expectedResult = {
78
78
  name: service.name,
79
- documents: { [type]: { combine: [ page1AsJSON, page2AsJSON ] } },
79
+ documents: { [termsType]: { combine: [ document1AsJSON, document2AsJSON ] } },
80
80
  };
81
81
 
82
82
  expect(result).to.deep.equal(expectedResult);
package/src/exports.js CHANGED
@@ -1,3 +1,3 @@
1
- export { default as pageDeclaration } from './archivist/services/pageDeclaration.js';
2
- export { default as filter } from './archivist/filter/exports.js';
1
+ export { default as sourceDocument } from './archivist/services/sourceDocument.js';
2
+ export { default as extract } from './archivist/extract/exports.js';
3
3
  export { default as fetch } from './archivist/fetcher/exports.js';