Skip to content

Commit 07b84f9

Browse files
authored
Merge pull request #93 from contentstack/main
Back merge
2 parents a21c760 + d95117d commit 07b84f9

File tree

9 files changed

+140
-23
lines changed

9 files changed

+140
-23
lines changed

.talismanrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
fileignoreconfig:
22
- filename: package-lock.json
3-
checksum: d388091773e9515cd3c0a5b881644775aa7b8233a405642e49133f296a4ceeeb
3+
checksum: c27c6a4629a6b1cec5e01b5db15d0e12646a1250e0cf1292ac58c561e9bc4993
44
- filename: test/unit/image-transform.spec.ts
55
checksum: 7beabdd07bd35d620668fcd97e1a303b9cbc40170bf3008a376d75ce0895de2a
66
- filename: test/utils/mocks.ts

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
### Version: 4.4.3
2+
#### Date: November-30-2024
3+
Fix: regex method fixed for validation
4+
15
### Version: 4.4.2
26
#### Date: November-16-2024
37
Fix: Variants reset issue fix on query call

package-lock.json

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

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@contentstack/delivery-sdk",
3-
"version": "4.4.2",
3+
"version": "4.4.3",
44
"type": "module",
55
"license": "MIT",
66
"main": "./dist/legacy/index.cjs",
@@ -36,7 +36,7 @@
3636
"@contentstack/core": "^1.1.3",
3737
"@contentstack/utils": "^1.3.14",
3838
"@types/humps": "^2.0.6",
39-
"axios": "^1.7.7",
39+
"axios": "^1.7.8",
4040
"dotenv": "^16.4.5",
4141
"humps": "^2.0.1",
4242
"path-browserify": "^1.0.1"

src/lib/base-query.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,6 @@ export class BaseQuery extends Pagination {
217217
'x-cs-variant-uid': this._variants
218218
};
219219
}
220-
221220
const response = await getData(this._client, this._urlPath, getRequestOptions);
222221

223222
return response as FindResponse<T>;

src/lib/entry-queryable.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,16 @@ export class EntryQueryable extends BaseQuery {
1515
* @param {string} fieldUid - field uid to select
1616
* @returns {EntryQueryable} - returns EntryQueryable object for chaining method calls
1717
*/
18-
only(fieldUid: string): EntryQueryable {
19-
this._queryParams['only[BASE][]'] = fieldUid;
20-
18+
only(fieldUid: string|string[]): EntryQueryable {
19+
if (Array.isArray(fieldUid)) {
20+
let i = 0;
21+
for (const uid of fieldUid) {
22+
this._queryParams[`only[BASE][${i}]`] = uid;
23+
i++;
24+
}
25+
} else {
26+
this._queryParams["only[BASE][]"] = fieldUid;
27+
}
2128
return this;
2229
}
2330

@@ -34,8 +41,16 @@ export class EntryQueryable extends BaseQuery {
3441
* @param {string} fieldUid - field uid to exclude
3542
* @returns {EntryQueryable} - returns EntryQueryable object for chaining method calls
3643
*/
37-
except(fieldUid: string): EntryQueryable {
38-
this._queryParams['except[BASE][]'] = fieldUid;
44+
except(fieldUid: string|string[]): EntryQueryable {
45+
if (Array.isArray(fieldUid)) {
46+
let i = 0;
47+
for (const uid of fieldUid) {
48+
this._queryParams[`except[BASE][${i}]`] = uid;
49+
i++;
50+
}
51+
} else {
52+
this._queryParams["except[BASE][]"] = fieldUid;
53+
}
3954

4055
return this;
4156
}

src/lib/query.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,6 @@ import { BaseQuery } from './base-query';
33
import { BaseQueryParameters, QueryOperation, QueryOperator, TaxonomyQueryOperation } from './types';
44
import { params, queryParams } from './internal-types';
55

6-
const safePatterns: RegExp[] = [
7-
/^[a-zA-Z0-9_.-]+$/, // Alphanumeric with underscores, periods, and dashes
8-
];
9-
106
export class Query extends BaseQuery {
117
private _contentTypeUid?: string;
128

@@ -34,10 +30,16 @@ export class Query extends BaseQuery {
3430

3531
// Validate if input matches any of the safe, pre-approved patterns
3632
private isValidRegexPattern(input: string): boolean {
37-
if (!this.isValidAlphanumeric(input)) {
38-
return false;
33+
const validRegex = /^[a-zA-Z0-9|^$.*+?()[\]{}\\-]+$/; // Allow only safe regex characters
34+
if (!validRegex.test(input)) {
35+
return false;
36+
}
37+
try {
38+
new RegExp(input);
39+
return true;
40+
} catch (e) {
41+
return false;
3942
}
40-
return safePatterns.some(pattern => pattern.test(input));
4143
}
4244

4345
private isValidValue(value: any[]): boolean {

test/api/entry-queryables.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,28 @@ describe('Query Operators API test cases', () => {
258258

259259
}
260260
});
261+
262+
it('should check for projected fields after only filter is applied', async () => {
263+
const query = makeEntries('contenttype_uid2').only(['title', 'reference'])
264+
const result = await query.find<TEntry>();
265+
if (result.entries) {
266+
expect(result.entries.length).toBeGreaterThan(0);
267+
expect(result.entries[0].reference).toBeDefined();
268+
expect(result.entries[0].title).toBeDefined();
269+
expect(result.entries[0]._version).toBeUndefined();
270+
}
271+
});
272+
273+
it('should ignore fields after except filter is applied', async () => {
274+
const query = makeEntries('contenttype_uid2').except(['title', 'reference'])
275+
const result = await query.find<TEntry>();
276+
if (result.entries) {
277+
expect(result.entries.length).toBeGreaterThan(0);
278+
expect(result.entries[0].reference).toBeUndefined();
279+
expect(result.entries[0].title).toBeUndefined();
280+
expect(result.entries[0]._version).toBeDefined();
281+
}
282+
});
261283
});
262284

263285
function makeEntries(contentTypeUid = ''): Entries {

test/unit/query.spec.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,82 @@ describe('Query class', () => {
8383
expect(mainQuery2._parameters).toHaveProperty('$and', [subQuery1._parameters, subQuery2._parameters]);
8484
});
8585

86+
it('should result in error when regex method is called with invalid regex', async () => {
87+
const regexQuery = getQueryObject(client, 'your-referenced-content-type-uid');
88+
expect(() => regexQuery.regex("fieldUid", "[a-z")).toThrow("Invalid regexPattern: Must be a valid regular expression");
89+
});
90+
91+
it('should add a regex parameter to _parameters when regex method is called with valid regex', () => {
92+
query.regex('fieldUid', '^ABCXYZ123');
93+
expect(query._parameters['fieldUid']).toEqual({ $regex: '^ABCXYZ123' });
94+
});
95+
96+
it('should add a containedIn parameter to _parameters', () => {
97+
query.containedIn('fieldUid', ['value1', 'value2']);
98+
expect(query._parameters['fieldUid']).toEqual({ '$in': ['value1', 'value2'] });
99+
});
100+
101+
it('should add a notContainedIn parameter to _parameters', () => {
102+
query.notContainedIn('fieldUid', ['value1', 'value2']);
103+
expect(query._parameters['fieldUid']).toEqual({ '$nin': ['value1', 'value2'] });
104+
});
105+
106+
it('should add an exists parameter to _parameters', () => {
107+
query.exists('fieldUid');
108+
expect(query._parameters['fieldUid']).toEqual({ '$exists': true });
109+
});
110+
111+
it('should add a notExists parameter to _parameters', () => {
112+
query.notExists('fieldUid');
113+
expect(query._parameters['fieldUid']).toEqual({ '$exists': false });
114+
});
115+
116+
it('should add an equalTo parameter to _parameters', () => {
117+
query.equalTo('fieldUid', 'value');
118+
expect(query._parameters['fieldUid']).toEqual('value');
119+
});
120+
121+
it('should add a notEqualTo parameter to _parameters', () => {
122+
query.notEqualTo('fieldUid', 'value');
123+
expect(query._parameters['fieldUid']).toEqual({ '$ne': 'value' });
124+
});
125+
126+
it('should add a lessThan parameter to _parameters', () => {
127+
query.lessThan('fieldUid', 10);
128+
expect(query._parameters['fieldUid']).toEqual({ '$lt': 10 });
129+
});
130+
131+
it('should add a lessThanOrEqualTo parameter to _parameters', () => {
132+
query.lessThanOrEqualTo('fieldUid', 10);
133+
expect(query._parameters['fieldUid']).toEqual({ '$lte': 10 });
134+
});
135+
136+
it('should add a greaterThan parameter to _parameters', () => {
137+
query.greaterThan('fieldUid', 10);
138+
expect(query._parameters['fieldUid']).toEqual({ '$gt': 10 });
139+
});
140+
141+
it('should add a greaterThanOrEqualTo parameter to _parameters', () => {
142+
query.greaterThanOrEqualTo('fieldUid', 10);
143+
expect(query._parameters['fieldUid']).toEqual({ '$gte': 10 });
144+
});
145+
146+
it('should add a tags parameter to _parameters', () => {
147+
query.tags(['tag1', 'tag2']);
148+
expect(query._parameters['tags']).toEqual(['tag1', 'tag2']);
149+
});
150+
151+
it('should add a search parameter to _queryParams', () => {
152+
query.search('searchKey');
153+
expect(query._queryParams['typeahead']).toEqual('searchKey');
154+
});
155+
156+
it('should provide proper response when find method is called', async () => {
157+
mockClient.onGet(`/content_types/contentTypeUid/entries`).reply(200, entryFindMock);
158+
const returnedValue = await query.find();
159+
expect(returnedValue).toEqual(entryFindMock);
160+
});
161+
86162
it('should provide proper response when find method is called', async () => {
87163
mockClient.onGet(`/content_types/contentTypeUid/entries`).reply(200, entryFindMock);
88164
const returnedValue = await query.find();

0 commit comments

Comments
 (0)