@dhis2/app-service-data 3.4.3 → 3.4.4

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.
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.isSvgConversion = exports.isAppInstall = exports.isStaticContentUpload = exports.isMessageConversationAttachment = exports.isFileResourceUpload = exports.isDataValue = void 0;
6
+ exports.isAppInstall = exports.isStaticContentUpload = exports.isMessageConversationAttachment = exports.isFileResourceUpload = exports.isDataValue = void 0;
7
7
 
8
8
  /*
9
9
  * Requests that expect a "multipart/form-data" Content-Type have been collected by scanning
@@ -45,13 +45,6 @@ exports.isStaticContentUpload = isStaticContentUpload;
45
45
 
46
46
  const isAppInstall = (type, {
47
47
  resource
48
- }) => type === 'create' && resource === 'apps'; // POST to convert an SVG file
48
+ }) => type === 'create' && resource === 'apps';
49
49
 
50
-
51
- exports.isAppInstall = isAppInstall;
52
-
53
- const isSvgConversion = (type, {
54
- resource
55
- }) => type === 'create' && (resource === 'svg.png' || resource === 'svg.pdf');
56
-
57
- exports.isSvgConversion = isSvgConversion;
50
+ exports.isAppInstall = isAppInstall;
@@ -71,21 +71,4 @@ describe('isAppInstall', () => {
71
71
  resource: 'notApps'
72
72
  })).toEqual(false);
73
73
  });
74
- });
75
- describe('isSvgConversion', () => {
76
- it('returns true for a POST to "svg.png"', () => {
77
- expect((0, _multipartFormDataMatchers.isSvgConversion)('create', {
78
- resource: 'svg.png'
79
- })).toEqual(true);
80
- });
81
- it('returns true for a POST to "svg.pdf"', () => {
82
- expect((0, _multipartFormDataMatchers.isSvgConversion)('create', {
83
- resource: 'svg.pdf'
84
- })).toEqual(true);
85
- });
86
- it('retuns false for a POST to a different resource', () => {
87
- expect((0, _multipartFormDataMatchers.isSvgConversion)('create', {
88
- resource: 'notSvg'
89
- })).toEqual(false);
90
- });
91
74
  });
@@ -3,12 +3,14 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.requestBodyForContentType = exports.requestHeadersForContentType = exports.requestContentType = exports.FORM_DATA_ERROR_MSG = void 0;
6
+ exports.requestBodyForContentType = exports.requestHeadersForContentType = exports.requestContentType = exports.getConversionErrorMessage = void 0;
7
7
 
8
8
  var multipartFormDataMatchers = _interopRequireWildcard(require("./multipartFormDataMatchers"));
9
9
 
10
10
  var textPlainMatchers = _interopRequireWildcard(require("./textPlainMatchers"));
11
11
 
12
+ var xWwwFormUrlencodedMatchers = _interopRequireWildcard(require("./xWwwFormUrlencodedMatchers"));
13
+
12
14
  function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
13
15
 
14
16
  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
@@ -17,20 +19,23 @@ const resourceExpectsTextPlain = (type, query) => Object.values(textPlainMatcher
17
19
 
18
20
  const resourceExpectsMultipartFormData = (type, query) => Object.values(multipartFormDataMatchers).some(multipartFormDataMatcher => multipartFormDataMatcher(type, query));
19
21
 
20
- const FORM_DATA_ERROR_MSG = 'Could not convert data to FormData: object does not have own enumerable string-keyed properties';
21
- exports.FORM_DATA_ERROR_MSG = FORM_DATA_ERROR_MSG;
22
+ const resourceExpectsXWwwFormUrlencoded = (type, query) => Object.values(xWwwFormUrlencodedMatchers).some(xWwwFormUrlencodedMatcher => xWwwFormUrlencodedMatcher(type, query));
23
+
24
+ const getConversionErrorMessage = outputType => "Could not convert data to ".concat(outputType, ": object does not have own enumerable string-keyed properties");
22
25
 
23
- const convertToFormData = data => {
26
+ exports.getConversionErrorMessage = getConversionErrorMessage;
27
+
28
+ const convertData = (data, initialValue) => {
24
29
  const dataEntries = Object.entries(data);
25
30
 
26
31
  if (dataEntries.length === 0) {
27
- throw new Error(FORM_DATA_ERROR_MSG);
32
+ throw new Error(getConversionErrorMessage(initialValue.constructor.name));
28
33
  }
29
34
 
30
- return dataEntries.reduce((formData, [key, value]) => {
31
- formData.append(key, value);
32
- return formData;
33
- }, new FormData());
35
+ return dataEntries.reduce((convertedData, [key, value]) => {
36
+ convertedData.append(key, value);
37
+ return convertedData;
38
+ }, initialValue);
34
39
  };
35
40
 
36
41
  const requestContentType = (type, query) => {
@@ -50,6 +55,10 @@ const requestContentType = (type, query) => {
50
55
  return 'multipart/form-data';
51
56
  }
52
57
 
58
+ if (resourceExpectsXWwwFormUrlencoded(type, query)) {
59
+ return 'application/x-www-form-urlencoded';
60
+ }
61
+
53
62
  return 'application/json';
54
63
  };
55
64
 
@@ -86,7 +95,11 @@ const requestBodyForContentType = (contentType, {
86
95
  }
87
96
 
88
97
  if (contentType === 'multipart/form-data') {
89
- return convertToFormData(data);
98
+ return convertData(data, new FormData());
99
+ }
100
+
101
+ if (contentType === 'application/x-www-form-urlencoded') {
102
+ return convertData(data, new URLSearchParams());
90
103
  } // 'text/plain'
91
104
 
92
105
 
@@ -88,7 +88,28 @@ describe('requestBodyForContentType', () => {
88
88
  type: 'text/plain'
89
89
  })
90
90
  });
91
- }).toThrow(new Error(_requestContentType.FORM_DATA_ERROR_MSG));
91
+ }).toThrow(new Error('Could not convert data to FormData: object does not have own enumerable string-keyed properties'));
92
+ });
93
+ it('converts to URLSearchParams if contentType is "application/x-www-form-urlencoded"', () => {
94
+ const data = {
95
+ a: 'AAA'
96
+ };
97
+ const result = (0, _requestContentType.requestBodyForContentType)('application/x-www-form-urlencoded', {
98
+ resource: 'test',
99
+ data
100
+ });
101
+ expect(result instanceof URLSearchParams).toEqual(true);
102
+ expect(result.get('a')).toEqual('AAA');
103
+ });
104
+ it('throws an error if contentType is "application/x-www-form-urlencoded" and data does have own string-keyd properties', () => {
105
+ expect(() => {
106
+ (0, _requestContentType.requestBodyForContentType)('application/x-www-form-urlencoded', {
107
+ resource: 'test',
108
+ data: new File(['foo'], 'foo.txt', {
109
+ type: 'text/plain'
110
+ })
111
+ });
112
+ }).toThrow(new Error('Could not convert data to URLSearchParams: object does not have own enumerable string-keyed properties'));
92
113
  });
93
114
  it('returns the data as received if contentType is "text/plain"', () => {
94
115
  const data = 'Something';
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.isSvgConversion = void 0;
7
+
8
+ // POST to convert an SVG file
9
+ const isSvgConversion = (type, {
10
+ resource
11
+ }) => type === 'create' && (resource === 'svg.png' || resource === 'svg.pdf');
12
+
13
+ exports.isSvgConversion = isSvgConversion;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+
3
+ var _xWwwFormUrlencodedMatchers = require("./xWwwFormUrlencodedMatchers");
4
+
5
+ describe('isSvgConversion', () => {
6
+ it('returns true for a POST to "svg.png"', () => {
7
+ expect((0, _xWwwFormUrlencodedMatchers.isSvgConversion)('create', {
8
+ resource: 'svg.png'
9
+ })).toEqual(true);
10
+ });
11
+ it('returns true for a POST to "svg.pdf"', () => {
12
+ expect((0, _xWwwFormUrlencodedMatchers.isSvgConversion)('create', {
13
+ resource: 'svg.pdf'
14
+ })).toEqual(true);
15
+ });
16
+ it('retuns false for a POST to a different resource', () => {
17
+ expect((0, _xWwwFormUrlencodedMatchers.isSvgConversion)('create', {
18
+ resource: 'notSvg'
19
+ })).toEqual(false);
20
+ });
21
+ });
@@ -26,8 +26,4 @@ export const isStaticContentUpload = (type, {
26
26
 
27
27
  export const isAppInstall = (type, {
28
28
  resource
29
- }) => type === 'create' && resource === 'apps'; // POST to convert an SVG file
30
-
31
- export const isSvgConversion = (type, {
32
- resource
33
- }) => type === 'create' && (resource === 'svg.png' || resource === 'svg.pdf');
29
+ }) => type === 'create' && resource === 'apps';
@@ -1,4 +1,4 @@
1
- import { isFileResourceUpload, isMessageConversationAttachment, isStaticContentUpload, isAppInstall, isSvgConversion, isDataValue } from './multipartFormDataMatchers';
1
+ import { isFileResourceUpload, isMessageConversationAttachment, isStaticContentUpload, isAppInstall, isDataValue } from './multipartFormDataMatchers';
2
2
  describe('isDataValue', () => {
3
3
  it('returns true for a POST to "dataValues"', () => {
4
4
  expect(isDataValue('create', {
@@ -68,21 +68,4 @@ describe('isAppInstall', () => {
68
68
  resource: 'notApps'
69
69
  })).toEqual(false);
70
70
  });
71
- });
72
- describe('isSvgConversion', () => {
73
- it('returns true for a POST to "svg.png"', () => {
74
- expect(isSvgConversion('create', {
75
- resource: 'svg.png'
76
- })).toEqual(true);
77
- });
78
- it('returns true for a POST to "svg.pdf"', () => {
79
- expect(isSvgConversion('create', {
80
- resource: 'svg.pdf'
81
- })).toEqual(true);
82
- });
83
- it('retuns false for a POST to a different resource', () => {
84
- expect(isSvgConversion('create', {
85
- resource: 'notSvg'
86
- })).toEqual(false);
87
- });
88
71
  });
@@ -1,23 +1,26 @@
1
1
  import * as multipartFormDataMatchers from './multipartFormDataMatchers';
2
2
  import * as textPlainMatchers from './textPlainMatchers';
3
+ import * as xWwwFormUrlencodedMatchers from './xWwwFormUrlencodedMatchers';
3
4
 
4
5
  const resourceExpectsTextPlain = (type, query) => Object.values(textPlainMatchers).some(textPlainMatcher => textPlainMatcher(type, query));
5
6
 
6
7
  const resourceExpectsMultipartFormData = (type, query) => Object.values(multipartFormDataMatchers).some(multipartFormDataMatcher => multipartFormDataMatcher(type, query));
7
8
 
8
- export const FORM_DATA_ERROR_MSG = 'Could not convert data to FormData: object does not have own enumerable string-keyed properties';
9
+ const resourceExpectsXWwwFormUrlencoded = (type, query) => Object.values(xWwwFormUrlencodedMatchers).some(xWwwFormUrlencodedMatcher => xWwwFormUrlencodedMatcher(type, query));
9
10
 
10
- const convertToFormData = data => {
11
+ export const getConversionErrorMessage = outputType => "Could not convert data to ".concat(outputType, ": object does not have own enumerable string-keyed properties");
12
+
13
+ const convertData = (data, initialValue) => {
11
14
  const dataEntries = Object.entries(data);
12
15
 
13
16
  if (dataEntries.length === 0) {
14
- throw new Error(FORM_DATA_ERROR_MSG);
17
+ throw new Error(getConversionErrorMessage(initialValue.constructor.name));
15
18
  }
16
19
 
17
- return dataEntries.reduce((formData, [key, value]) => {
18
- formData.append(key, value);
19
- return formData;
20
- }, new FormData());
20
+ return dataEntries.reduce((convertedData, [key, value]) => {
21
+ convertedData.append(key, value);
22
+ return convertedData;
23
+ }, initialValue);
21
24
  };
22
25
 
23
26
  export const requestContentType = (type, query) => {
@@ -37,6 +40,10 @@ export const requestContentType = (type, query) => {
37
40
  return 'multipart/form-data';
38
41
  }
39
42
 
43
+ if (resourceExpectsXWwwFormUrlencoded(type, query)) {
44
+ return 'application/x-www-form-urlencoded';
45
+ }
46
+
40
47
  return 'application/json';
41
48
  };
42
49
  export const requestHeadersForContentType = contentType => {
@@ -67,7 +74,11 @@ export const requestBodyForContentType = (contentType, {
67
74
  }
68
75
 
69
76
  if (contentType === 'multipart/form-data') {
70
- return convertToFormData(data);
77
+ return convertData(data, new FormData());
78
+ }
79
+
80
+ if (contentType === 'application/x-www-form-urlencoded') {
81
+ return convertData(data, new URLSearchParams());
71
82
  } // 'text/plain'
72
83
 
73
84
 
@@ -1,4 +1,4 @@
1
- import { requestContentType, requestHeadersForContentType, requestBodyForContentType, FORM_DATA_ERROR_MSG } from './requestContentType';
1
+ import { requestContentType, requestHeadersForContentType, requestBodyForContentType } from './requestContentType';
2
2
  describe('requestContentType', () => {
3
3
  it('returns "application/json" for a normal resource', () => {
4
4
  expect(requestContentType('create', {
@@ -85,7 +85,28 @@ describe('requestBodyForContentType', () => {
85
85
  type: 'text/plain'
86
86
  })
87
87
  });
88
- }).toThrow(new Error(FORM_DATA_ERROR_MSG));
88
+ }).toThrow(new Error('Could not convert data to FormData: object does not have own enumerable string-keyed properties'));
89
+ });
90
+ it('converts to URLSearchParams if contentType is "application/x-www-form-urlencoded"', () => {
91
+ const data = {
92
+ a: 'AAA'
93
+ };
94
+ const result = requestBodyForContentType('application/x-www-form-urlencoded', {
95
+ resource: 'test',
96
+ data
97
+ });
98
+ expect(result instanceof URLSearchParams).toEqual(true);
99
+ expect(result.get('a')).toEqual('AAA');
100
+ });
101
+ it('throws an error if contentType is "application/x-www-form-urlencoded" and data does have own string-keyd properties', () => {
102
+ expect(() => {
103
+ requestBodyForContentType('application/x-www-form-urlencoded', {
104
+ resource: 'test',
105
+ data: new File(['foo'], 'foo.txt', {
106
+ type: 'text/plain'
107
+ })
108
+ });
109
+ }).toThrow(new Error('Could not convert data to URLSearchParams: object does not have own enumerable string-keyed properties'));
89
110
  });
90
111
  it('returns the data as received if contentType is "text/plain"', () => {
91
112
  const data = 'Something';
@@ -0,0 +1,4 @@
1
+ // POST to convert an SVG file
2
+ export const isSvgConversion = (type, {
3
+ resource
4
+ }) => type === 'create' && (resource === 'svg.png' || resource === 'svg.pdf');
@@ -0,0 +1,18 @@
1
+ import { isSvgConversion } from './xWwwFormUrlencodedMatchers';
2
+ describe('isSvgConversion', () => {
3
+ it('returns true for a POST to "svg.png"', () => {
4
+ expect(isSvgConversion('create', {
5
+ resource: 'svg.png'
6
+ })).toEqual(true);
7
+ });
8
+ it('returns true for a POST to "svg.pdf"', () => {
9
+ expect(isSvgConversion('create', {
10
+ resource: 'svg.pdf'
11
+ })).toEqual(true);
12
+ });
13
+ it('retuns false for a POST to a different resource', () => {
14
+ expect(isSvgConversion('create', {
15
+ resource: 'notSvg'
16
+ })).toEqual(false);
17
+ });
18
+ });
@@ -4,4 +4,3 @@ export declare const isFileResourceUpload: (type: FetchType, { resource }: Resol
4
4
  export declare const isMessageConversationAttachment: (type: FetchType, { resource }: ResolvedResourceQuery) => boolean;
5
5
  export declare const isStaticContentUpload: (type: FetchType, { resource }: ResolvedResourceQuery) => boolean;
6
6
  export declare const isAppInstall: (type: FetchType, { resource }: ResolvedResourceQuery) => boolean;
7
- export declare const isSvgConversion: (type: FetchType, { resource }: ResolvedResourceQuery) => boolean;
@@ -1,7 +1,7 @@
1
1
  import { ResolvedResourceQuery, FetchType } from '../../../engine';
2
- declare type RequestContentType = 'application/json' | 'application/json-patch+json' | 'text/plain' | 'multipart/form-data' | null;
3
- export declare const FORM_DATA_ERROR_MSG = "Could not convert data to FormData: object does not have own enumerable string-keyed properties";
2
+ declare type RequestContentType = 'application/json' | 'application/json-patch+json' | 'text/plain' | 'multipart/form-data' | 'application/x-www-form-urlencoded' | null;
3
+ export declare const getConversionErrorMessage: (outputType: string) => string;
4
4
  export declare const requestContentType: (type: FetchType, query: ResolvedResourceQuery) => null | RequestContentType;
5
5
  export declare const requestHeadersForContentType: (contentType: RequestContentType) => undefined | Record<'Content-Type', string>;
6
- export declare const requestBodyForContentType: (contentType: RequestContentType, { data }: ResolvedResourceQuery) => undefined | string | FormData;
6
+ export declare const requestBodyForContentType: (contentType: RequestContentType, { data }: ResolvedResourceQuery) => undefined | string | FormData | URLSearchParams;
7
7
  export {};
@@ -0,0 +1,2 @@
1
+ import { ResolvedResourceQuery, FetchType } from '../../../engine';
2
+ export declare const isSvgConversion: (type: FetchType, { resource }: ResolvedResourceQuery) => boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dhis2/app-service-data",
3
- "version": "3.4.3",
3
+ "version": "3.4.4",
4
4
  "main": "./build/cjs/index.js",
5
5
  "module": "./build/es/index.js",
6
6
  "types": "build/types/index.d.ts",
@@ -22,7 +22,7 @@
22
22
  "build/**"
23
23
  ],
24
24
  "peerDependencies": {
25
- "@dhis2/app-service-config": "3.4.3",
25
+ "@dhis2/app-service-config": "3.4.4",
26
26
  "@dhis2/cli-app-scripts": "^7.1.1",
27
27
  "prop-types": "^15.7.2",
28
28
  "react": "^16.8",