@strapi/utils 5.46.1 → 5.47.0
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/content-api-constants.d.ts +2 -2
- package/dist/content-api-constants.d.ts.map +1 -1
- package/dist/content-api-constants.js +2 -0
- package/dist/content-api-constants.js.map +1 -1
- package/dist/content-api-constants.mjs +2 -0
- package/dist/content-api-constants.mjs.map +1 -1
- package/dist/convert-query-params.d.ts +4 -2
- package/dist/convert-query-params.d.ts.map +1 -1
- package/dist/convert-query-params.js.map +1 -1
- package/dist/convert-query-params.mjs.map +1 -1
- package/dist/has-published-version-param.d.ts +9 -0
- package/dist/has-published-version-param.d.ts.map +1 -0
- package/dist/has-published-version-param.js +24 -0
- package/dist/has-published-version-param.js.map +1 -0
- package/dist/has-published-version-param.mjs +21 -0
- package/dist/has-published-version-param.mjs.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +1 -1
- package/dist/publication-filter.d.ts +14 -0
- package/dist/publication-filter.d.ts.map +1 -0
- package/dist/publication-filter.js +189 -0
- package/dist/publication-filter.js.map +1 -0
- package/dist/publication-filter.mjs +185 -0
- package/dist/publication-filter.mjs.map +1 -0
- package/dist/sanitize/index.d.ts.map +1 -1
- package/dist/sanitize/index.js +4 -0
- package/dist/sanitize/index.js.map +1 -1
- package/dist/sanitize/index.mjs +4 -0
- package/dist/sanitize/index.mjs.map +1 -1
- package/dist/validate/index.d.ts.map +1 -1
- package/dist/validate/index.js +5 -0
- package/dist/validate/index.js.map +1 -1
- package/dist/validate/index.mjs +5 -0
- package/dist/validate/index.mjs.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ValidationError } from './errors.mjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Parses the deprecated `hasPublishedVersion` query param (REST boolean or "true"/"false" strings).
|
|
5
|
+
* @deprecated Prefer `publicationFilter` with document-scoped modes.
|
|
6
|
+
*/ const parseHasPublishedVersionQueryParam = (value)=>{
|
|
7
|
+
if (value === undefined || value === null) {
|
|
8
|
+
return undefined;
|
|
9
|
+
}
|
|
10
|
+
if (value === true || value === 'true') {
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
if (value === false || value === 'false') {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
throw new ValidationError("Invalid value for 'hasPublishedVersion'. Expected boolean or 'true'/'false' string.");
|
|
17
|
+
};
|
|
18
|
+
/** Maps legacy boolean to the document-scoped `publicationFilter` cohorts (same semantics as the old subquery). */ const hasPublishedVersionBooleanToPublicationFilterMode = (value)=>value ? 'has-published-version-document' : 'never-published-document';
|
|
19
|
+
|
|
20
|
+
export { hasPublishedVersionBooleanToPublicationFilterMode, parseHasPublishedVersionQueryParam };
|
|
21
|
+
//# sourceMappingURL=has-published-version-param.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"has-published-version-param.mjs","sources":["../src/has-published-version-param.ts"],"sourcesContent":["import { ValidationError } from './errors';\nimport type { PublicationFilterMode } from './publication-filter';\n\n/**\n * Parses the deprecated `hasPublishedVersion` query param (REST boolean or \"true\"/\"false\" strings).\n * @deprecated Prefer `publicationFilter` with document-scoped modes.\n */\nexport const parseHasPublishedVersionQueryParam = (value: unknown): boolean | undefined => {\n if (value === undefined || value === null) {\n return undefined;\n }\n\n if (value === true || value === 'true') {\n return true;\n }\n\n if (value === false || value === 'false') {\n return false;\n }\n\n throw new ValidationError(\n \"Invalid value for 'hasPublishedVersion'. Expected boolean or 'true'/'false' string.\"\n );\n};\n\n/** Maps legacy boolean to the document-scoped `publicationFilter` cohorts (same semantics as the old subquery). */\nexport const hasPublishedVersionBooleanToPublicationFilterMode = (\n value: boolean\n): Extract<PublicationFilterMode, 'never-published-document' | 'has-published-version-document'> =>\n value ? 'has-published-version-document' : 'never-published-document';\n"],"names":["parseHasPublishedVersionQueryParam","value","undefined","ValidationError","hasPublishedVersionBooleanToPublicationFilterMode"],"mappings":";;AAGA;;;IAIO,MAAMA,kCAAAA,GAAqC,CAACC,KAAAA,GAAAA;IACjD,IAAIA,KAAAA,KAAUC,SAAAA,IAAaD,KAAAA,KAAU,IAAA,EAAM;QACzC,OAAOC,SAAAA;AACT,IAAA;IAEA,IAAID,KAAAA,KAAU,IAAA,IAAQA,KAAAA,KAAU,MAAA,EAAQ;QACtC,OAAO,IAAA;AACT,IAAA;IAEA,IAAIA,KAAAA,KAAU,KAAA,IAASA,KAAAA,KAAU,OAAA,EAAS;QACxC,OAAO,KAAA;AACT,IAAA;AAEA,IAAA,MAAM,IAAIE,eAAAA,CACR,qFAAA,CAAA;AAEJ;AAEA,oHACO,MAAMC,iDAAAA,GAAoD,CAC/DH,KAAAA,GAEAA,KAAAA,GAAQ,mCAAmC;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -32,4 +32,6 @@ export * from './route-serialization';
|
|
|
32
32
|
export * from './primitives';
|
|
33
33
|
export * from './content-api-router';
|
|
34
34
|
export * from './security';
|
|
35
|
+
export * from './publication-filter';
|
|
36
|
+
export * from './has-published-version-param';
|
|
35
37
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE3D,OAAO,KAAK,WAAW,MAAM,wBAAwB,CAAC;AACtD,OAAO,EACL,wBAAwB,EACxB,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,cAAc,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AACjC,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,KAAK,GAAG,MAAM,OAAO,CAAC;AAC7B,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,KAAK,YAAY,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,SAAS,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AACjC,cAAc,OAAO,CAAC;AACtB,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AAEtC,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE3D,OAAO,KAAK,WAAW,MAAM,wBAAwB,CAAC;AACtD,OAAO,EACL,wBAAwB,EACxB,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,cAAc,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AACjC,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,KAAK,GAAG,MAAM,OAAO,CAAC;AAC7B,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,KAAK,YAAY,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,SAAS,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AACjC,cAAc,OAAO,CAAC;AACtB,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AAEtC,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,+BAA+B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -38,6 +38,8 @@ var objects = require('./primitives/objects.js');
|
|
|
38
38
|
var dates = require('./primitives/dates.js');
|
|
39
39
|
var contentApiRouter = require('./content-api-router.js');
|
|
40
40
|
var security = require('./security.js');
|
|
41
|
+
var publicationFilter = require('./publication-filter.js');
|
|
42
|
+
var hasPublishedVersionParam = require('./has-published-version-param.js');
|
|
41
43
|
var z = require('zod/v4');
|
|
42
44
|
|
|
43
45
|
function _interopNamespaceDefault(e) {
|
|
@@ -120,5 +122,10 @@ exports.dates = dates;
|
|
|
120
122
|
exports.createContentApiRoutesFactory = contentApiRouter.createContentApiRoutesFactory;
|
|
121
123
|
exports.CSP_DEFAULTS = security.CSP_DEFAULTS;
|
|
122
124
|
exports.extendMiddlewareConfiguration = security.extendMiddlewareConfiguration;
|
|
125
|
+
exports.buildPublicationFilterWhere = publicationFilter.buildPublicationFilterWhere;
|
|
126
|
+
exports.parsePublicationFilter = publicationFilter.parsePublicationFilter;
|
|
127
|
+
exports.validatePublicationFilterQueryParam = publicationFilter.validatePublicationFilterQueryParam;
|
|
128
|
+
exports.hasPublishedVersionBooleanToPublicationFilterMode = hasPublishedVersionParam.hasPublishedVersionBooleanToPublicationFilterMode;
|
|
129
|
+
exports.parseHasPublishedVersionQueryParam = hasPublishedVersionParam.parseHasPublishedVersionQueryParam;
|
|
123
130
|
exports.z = z__namespace;
|
|
124
131
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/index.mjs
CHANGED
|
@@ -55,6 +55,8 @@ import * as dates from './primitives/dates.mjs';
|
|
|
55
55
|
export { dates };
|
|
56
56
|
export { createContentApiRoutesFactory } from './content-api-router.mjs';
|
|
57
57
|
export { CSP_DEFAULTS, extendMiddlewareConfiguration } from './security.mjs';
|
|
58
|
+
export { buildPublicationFilterWhere, parsePublicationFilter, validatePublicationFilterQueryParam } from './publication-filter.mjs';
|
|
59
|
+
export { hasPublishedVersionBooleanToPublicationFilterMode, parseHasPublishedVersionQueryParam } from './has-published-version-param.mjs';
|
|
58
60
|
import * as z from 'zod/v4';
|
|
59
61
|
export { z };
|
|
60
62
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Model } from './types';
|
|
2
|
+
export type PublicationFilterMode = 'never-published' | 'has-published-version' | 'modified' | 'unmodified' | 'never-published-document' | 'has-published-version-document' | 'published-without-draft' | 'published-with-draft';
|
|
3
|
+
export declare const parsePublicationFilter: (value: unknown) => PublicationFilterMode | undefined;
|
|
4
|
+
/**
|
|
5
|
+
* Validates a `publicationFilter` query value for Content API `validate.query` / `sanitize.query`.
|
|
6
|
+
* Attaches `details.source` and `details.param` so HTTP layer maps to 400 with correct field context.
|
|
7
|
+
*/
|
|
8
|
+
export declare const validatePublicationFilterQueryParam: (value: unknown) => void;
|
|
9
|
+
/**
|
|
10
|
+
* Extra `id IN (subquery)` filter for publicationFilter, scoped to (documentId, locale) when i18n is enabled.
|
|
11
|
+
* Document-scoped modes use `documentId` only. Returns null when the model does not use draft & publish.
|
|
12
|
+
*/
|
|
13
|
+
export declare const buildPublicationFilterWhere: (knex: any, meta: any, model: Model | undefined, mode: PublicationFilterMode, status: 'draft' | 'published') => Record<string, unknown> | null;
|
|
14
|
+
//# sourceMappingURL=publication-filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publication-filter.d.ts","sourceRoot":"","sources":["../src/publication-filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAIrC,MAAM,MAAM,qBAAqB,GAC7B,iBAAiB,GACjB,uBAAuB,GACvB,UAAU,GACV,YAAY,GACZ,0BAA0B,GAC1B,gCAAgC,GAChC,yBAAyB,GACzB,sBAAsB,CAAC;AAa3B,eAAO,MAAM,sBAAsB,UAAW,OAAO,KAAG,qBAAqB,GAAG,SAY/E,CAAC;AAIF;;;GAGG;AACH,eAAO,MAAM,mCAAmC,UAAW,OAAO,KAAG,IAkBpE,CAAC;AAoBF;;;GAGG;AACH,eAAO,MAAM,2BAA2B,SAChC,GAAG,QACH,GAAG,SACF,KAAK,GAAG,SAAS,QAClB,qBAAqB,UACnB,OAAO,GAAG,WAAW,KAC5B,OAAO,MAAM,EAAE,OAAO,CAAC,GAAG,IA6N5B,CAAC"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var errors = require('./errors.js');
|
|
4
|
+
var contentTypes = require('./content-types.js');
|
|
5
|
+
|
|
6
|
+
const ALLOWED = [
|
|
7
|
+
'never-published',
|
|
8
|
+
'has-published-version',
|
|
9
|
+
'modified',
|
|
10
|
+
'unmodified',
|
|
11
|
+
'never-published-document',
|
|
12
|
+
'has-published-version-document',
|
|
13
|
+
'published-without-draft',
|
|
14
|
+
'published-with-draft'
|
|
15
|
+
];
|
|
16
|
+
const parsePublicationFilter = (value)=>{
|
|
17
|
+
if (value === undefined || value === null) {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
if (typeof value === 'string' && ALLOWED.includes(value)) {
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
throw new errors.ValidationError(`Invalid value for 'publicationFilter'. Expected one of: ${ALLOWED.join(', ')}.`);
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Validates a `publicationFilter` query value for Content API `validate.query` / `sanitize.query`.
|
|
27
|
+
* Attaches `details.source` and `details.param` so HTTP layer maps to 400 with correct field context.
|
|
28
|
+
*/ const validatePublicationFilterQueryParam = (value)=>{
|
|
29
|
+
if (value === undefined || value === null) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
parsePublicationFilter(value);
|
|
34
|
+
} catch (e) {
|
|
35
|
+
if (e instanceof errors.ValidationError) {
|
|
36
|
+
const prev = e.details;
|
|
37
|
+
e.details = {
|
|
38
|
+
...prev && typeof prev === 'object' ? prev : {},
|
|
39
|
+
source: 'query',
|
|
40
|
+
param: 'publicationFilter'
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
throw e;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
const columnName = (meta, attr)=>{
|
|
47
|
+
const a = meta?.attributes?.[attr];
|
|
48
|
+
if (!a) {
|
|
49
|
+
throw new errors.ApplicationError(`Cannot build publicationFilter SQL: attribute '${attr}' is missing from metadata for table '${meta?.tableName ?? '<unknown>'}'.`);
|
|
50
|
+
}
|
|
51
|
+
if (!('columnName' in a) || !a.columnName) {
|
|
52
|
+
throw new errors.ApplicationError(`Cannot build publicationFilter SQL: attribute '${attr}' on table '${meta?.tableName ?? '<unknown>'}' has no resolved columnName.`);
|
|
53
|
+
}
|
|
54
|
+
return a.columnName;
|
|
55
|
+
};
|
|
56
|
+
const emptyIdSelection = (knex, table, idCol)=>knex(table).select(`${table}.${idCol}`).whereRaw('0 = 1');
|
|
57
|
+
/**
|
|
58
|
+
* Extra `id IN (subquery)` filter for publicationFilter, scoped to (documentId, locale) when i18n is enabled.
|
|
59
|
+
* Document-scoped modes use `documentId` only. Returns null when the model does not use draft & publish.
|
|
60
|
+
*/ const buildPublicationFilterWhere = (knex, meta, model, mode, status)=>{
|
|
61
|
+
if (!model || !contentTypes.hasDraftAndPublish(model)) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
const table = meta.tableName;
|
|
65
|
+
const idCol = columnName(meta, 'id');
|
|
66
|
+
const docCol = columnName(meta, 'documentId');
|
|
67
|
+
const pubCol = columnName(meta, 'publishedAt');
|
|
68
|
+
const updatedCol = columnName(meta, 'updatedAt');
|
|
69
|
+
const hasLocale = Boolean(meta.attributes.locale);
|
|
70
|
+
const localeCol = hasLocale ? columnName(meta, 'locale') : null;
|
|
71
|
+
const pairOn = (aliasA, aliasB)=>{
|
|
72
|
+
const parts = [
|
|
73
|
+
`${aliasA}.${docCol} = ${aliasB}.${docCol}`
|
|
74
|
+
];
|
|
75
|
+
if (localeCol) {
|
|
76
|
+
parts.push(`(${aliasA}.${localeCol} = ${aliasB}.${localeCol} OR (${aliasA}.${localeCol} IS NULL AND ${aliasB}.${localeCol} IS NULL))`);
|
|
77
|
+
}
|
|
78
|
+
return parts.join(' AND ');
|
|
79
|
+
};
|
|
80
|
+
const documentOn = (aliasA, aliasB)=>`${aliasA}.${docCol} = ${aliasB}.${docCol}`;
|
|
81
|
+
const idIn = (sub)=>({
|
|
82
|
+
id: {
|
|
83
|
+
$in: sub
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
switch(mode){
|
|
87
|
+
case 'never-published':
|
|
88
|
+
{
|
|
89
|
+
if (status === 'published') {
|
|
90
|
+
return idIn(emptyIdSelection(knex, table, idCol));
|
|
91
|
+
}
|
|
92
|
+
const sub = knex(`${table} as d`).select(`d.${idCol}`).whereNull(`d.${pubCol}`).whereNotExists(function() {
|
|
93
|
+
this.select(knex.raw('1')).from(`${table} as p`).whereRaw(pairOn('p', 'd')).whereNotNull(`p.${pubCol}`);
|
|
94
|
+
});
|
|
95
|
+
return idIn(sub);
|
|
96
|
+
}
|
|
97
|
+
case 'has-published-version':
|
|
98
|
+
{
|
|
99
|
+
if (status === 'draft') {
|
|
100
|
+
const sub = knex(`${table} as d`).select(`d.${idCol}`).whereNull(`d.${pubCol}`).whereExists(function() {
|
|
101
|
+
this.select(knex.raw('1')).from(`${table} as p`).whereRaw(pairOn('p', 'd')).whereNotNull(`p.${pubCol}`);
|
|
102
|
+
});
|
|
103
|
+
return idIn(sub);
|
|
104
|
+
}
|
|
105
|
+
const sub = knex(`${table} as p`).select(`p.${idCol}`).whereNotNull(`p.${pubCol}`).whereExists(function() {
|
|
106
|
+
this.select(knex.raw('1')).from(`${table} as d`).whereRaw(pairOn('d', 'p')).whereNull(`d.${pubCol}`);
|
|
107
|
+
});
|
|
108
|
+
return idIn(sub);
|
|
109
|
+
}
|
|
110
|
+
case 'modified':
|
|
111
|
+
{
|
|
112
|
+
if (status === 'draft') {
|
|
113
|
+
const sub = knex(`${table} as d`).select(`d.${idCol}`).whereNull(`d.${pubCol}`).whereExists(function() {
|
|
114
|
+
this.select(knex.raw('1')).from(`${table} as p`).whereRaw(pairOn('p', 'd')).whereNotNull(`p.${pubCol}`).whereRaw(`d.${updatedCol} > p.${updatedCol}`);
|
|
115
|
+
});
|
|
116
|
+
return idIn(sub);
|
|
117
|
+
}
|
|
118
|
+
const sub = knex(`${table} as p`).select(`p.${idCol}`).whereNotNull(`p.${pubCol}`).whereExists(function() {
|
|
119
|
+
this.select(knex.raw('1')).from(`${table} as d`).whereRaw(pairOn('d', 'p')).whereNull(`d.${pubCol}`).whereRaw(`d.${updatedCol} > p.${updatedCol}`);
|
|
120
|
+
});
|
|
121
|
+
return idIn(sub);
|
|
122
|
+
}
|
|
123
|
+
case 'unmodified':
|
|
124
|
+
{
|
|
125
|
+
if (status === 'draft') {
|
|
126
|
+
const sub = knex(`${table} as d`).select(`d.${idCol}`).whereNull(`d.${pubCol}`).whereExists(function() {
|
|
127
|
+
this.select(knex.raw('1')).from(`${table} as p`).whereRaw(pairOn('p', 'd')).whereNotNull(`p.${pubCol}`).whereRaw(`d.${updatedCol} <= p.${updatedCol}`);
|
|
128
|
+
});
|
|
129
|
+
return idIn(sub);
|
|
130
|
+
}
|
|
131
|
+
const sub = knex(`${table} as p`).select(`p.${idCol}`).whereNotNull(`p.${pubCol}`).whereExists(function() {
|
|
132
|
+
this.select(knex.raw('1')).from(`${table} as d`).whereRaw(pairOn('d', 'p')).whereNull(`d.${pubCol}`).whereRaw(`d.${updatedCol} <= p.${updatedCol}`);
|
|
133
|
+
});
|
|
134
|
+
return idIn(sub);
|
|
135
|
+
}
|
|
136
|
+
case 'never-published-document':
|
|
137
|
+
{
|
|
138
|
+
if (status === 'published') {
|
|
139
|
+
return idIn(emptyIdSelection(knex, table, idCol));
|
|
140
|
+
}
|
|
141
|
+
const sub = knex(`${table} as d`).select(`d.${idCol}`).whereNull(`d.${pubCol}`).whereNotExists(function() {
|
|
142
|
+
this.select(knex.raw('1')).from(`${table} as p`).whereRaw(documentOn('p', 'd')).whereNotNull(`p.${pubCol}`);
|
|
143
|
+
});
|
|
144
|
+
return idIn(sub);
|
|
145
|
+
}
|
|
146
|
+
case 'has-published-version-document':
|
|
147
|
+
{
|
|
148
|
+
if (status === 'draft') {
|
|
149
|
+
const sub = knex(`${table} as d`).select(`d.${idCol}`).whereNull(`d.${pubCol}`).whereExists(function() {
|
|
150
|
+
this.select(knex.raw('1')).from(`${table} as p`).whereRaw(documentOn('p', 'd')).whereNotNull(`p.${pubCol}`);
|
|
151
|
+
});
|
|
152
|
+
return idIn(sub);
|
|
153
|
+
}
|
|
154
|
+
const sub = knex(`${table} as p`).select(`p.${idCol}`).whereNotNull(`p.${pubCol}`).whereExists(function() {
|
|
155
|
+
this.select(knex.raw('1')).from(`${table} as d`).whereRaw(documentOn('d', 'p')).whereNull(`d.${pubCol}`);
|
|
156
|
+
});
|
|
157
|
+
return idIn(sub);
|
|
158
|
+
}
|
|
159
|
+
case 'published-without-draft':
|
|
160
|
+
{
|
|
161
|
+
if (status === 'draft') {
|
|
162
|
+
return idIn(emptyIdSelection(knex, table, idCol));
|
|
163
|
+
}
|
|
164
|
+
const sub = knex(`${table} as p`).select(`p.${idCol}`).whereNotNull(`p.${pubCol}`).whereNotExists(function() {
|
|
165
|
+
this.select(knex.raw('1')).from(`${table} as d`).whereRaw(pairOn('d', 'p')).whereNull(`d.${pubCol}`);
|
|
166
|
+
});
|
|
167
|
+
return idIn(sub);
|
|
168
|
+
}
|
|
169
|
+
case 'published-with-draft':
|
|
170
|
+
{
|
|
171
|
+
if (status === 'draft') {
|
|
172
|
+
return idIn(emptyIdSelection(knex, table, idCol));
|
|
173
|
+
}
|
|
174
|
+
const sub = knex(`${table} as p`).select(`p.${idCol}`).whereNotNull(`p.${pubCol}`).whereExists(function() {
|
|
175
|
+
this.select(knex.raw('1')).from(`${table} as d`).whereRaw(pairOn('d', 'p')).whereNull(`d.${pubCol}`);
|
|
176
|
+
});
|
|
177
|
+
return idIn(sub);
|
|
178
|
+
}
|
|
179
|
+
default:
|
|
180
|
+
{
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
exports.buildPublicationFilterWhere = buildPublicationFilterWhere;
|
|
187
|
+
exports.parsePublicationFilter = parsePublicationFilter;
|
|
188
|
+
exports.validatePublicationFilterQueryParam = validatePublicationFilterQueryParam;
|
|
189
|
+
//# sourceMappingURL=publication-filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publication-filter.js","sources":["../src/publication-filter.ts"],"sourcesContent":["import type { Model } from './types';\nimport { ApplicationError, ValidationError } from './errors';\nimport { hasDraftAndPublish } from './content-types';\n\nexport type PublicationFilterMode =\n | 'never-published'\n | 'has-published-version'\n | 'modified'\n | 'unmodified'\n | 'never-published-document'\n | 'has-published-version-document'\n | 'published-without-draft'\n | 'published-with-draft';\n\nconst ALLOWED: PublicationFilterMode[] = [\n 'never-published',\n 'has-published-version',\n 'modified',\n 'unmodified',\n 'never-published-document',\n 'has-published-version-document',\n 'published-without-draft',\n 'published-with-draft',\n];\n\nexport const parsePublicationFilter = (value: unknown): PublicationFilterMode | undefined => {\n if (value === undefined || value === null) {\n return undefined;\n }\n\n if (typeof value === 'string' && (ALLOWED as string[]).includes(value)) {\n return value as PublicationFilterMode;\n }\n\n throw new ValidationError(\n `Invalid value for 'publicationFilter'. Expected one of: ${ALLOWED.join(', ')}.`\n );\n};\n\ntype QueryParamDetails = { source?: string; param?: string; [key: string]: unknown };\n\n/**\n * Validates a `publicationFilter` query value for Content API `validate.query` / `sanitize.query`.\n * Attaches `details.source` and `details.param` so HTTP layer maps to 400 with correct field context.\n */\nexport const validatePublicationFilterQueryParam = (value: unknown): void => {\n if (value === undefined || value === null) {\n return;\n }\n\n try {\n parsePublicationFilter(value);\n } catch (e) {\n if (e instanceof ValidationError) {\n const prev = e.details as QueryParamDetails | undefined;\n e.details = {\n ...(prev && typeof prev === 'object' ? prev : {}),\n source: 'query',\n param: 'publicationFilter',\n };\n }\n throw e;\n }\n};\n\nconst columnName = (meta: any, attr: string): string => {\n const a = meta?.attributes?.[attr];\n if (!a) {\n throw new ApplicationError(\n `Cannot build publicationFilter SQL: attribute '${attr}' is missing from metadata for table '${meta?.tableName ?? '<unknown>'}'.`\n );\n }\n if (!('columnName' in a) || !a.columnName) {\n throw new ApplicationError(\n `Cannot build publicationFilter SQL: attribute '${attr}' on table '${meta?.tableName ?? '<unknown>'}' has no resolved columnName.`\n );\n }\n return a.columnName as string;\n};\n\nconst emptyIdSelection = (knex: any, table: string, idCol: string) =>\n knex(table).select(`${table}.${idCol}`).whereRaw('0 = 1');\n\n/**\n * Extra `id IN (subquery)` filter for publicationFilter, scoped to (documentId, locale) when i18n is enabled.\n * Document-scoped modes use `documentId` only. Returns null when the model does not use draft & publish.\n */\nexport const buildPublicationFilterWhere = (\n knex: any,\n meta: any,\n model: Model | undefined,\n mode: PublicationFilterMode,\n status: 'draft' | 'published'\n): Record<string, unknown> | null => {\n if (!model || !hasDraftAndPublish(model)) {\n return null;\n }\n\n const table = meta.tableName;\n const idCol = columnName(meta, 'id');\n const docCol = columnName(meta, 'documentId');\n const pubCol = columnName(meta, 'publishedAt');\n const updatedCol = columnName(meta, 'updatedAt');\n const hasLocale = Boolean(meta.attributes.locale);\n const localeCol = hasLocale ? columnName(meta, 'locale') : null;\n\n const pairOn = (aliasA: string, aliasB: string) => {\n const parts = [`${aliasA}.${docCol} = ${aliasB}.${docCol}`];\n if (localeCol) {\n parts.push(\n `(${aliasA}.${localeCol} = ${aliasB}.${localeCol} OR (${aliasA}.${localeCol} IS NULL AND ${aliasB}.${localeCol} IS NULL))`\n );\n }\n return parts.join(' AND ');\n };\n\n const documentOn = (aliasA: string, aliasB: string) =>\n `${aliasA}.${docCol} = ${aliasB}.${docCol}`;\n\n const idIn = (sub: any) => ({ id: { $in: sub } });\n\n switch (mode) {\n case 'never-published': {\n if (status === 'published') {\n return idIn(emptyIdSelection(knex, table, idCol));\n }\n\n const sub = knex(`${table} as d`)\n .select(`d.${idCol}`)\n .whereNull(`d.${pubCol}`)\n .whereNotExists(function (this: any) {\n this.select(knex.raw('1'))\n .from(`${table} as p`)\n .whereRaw(pairOn('p', 'd'))\n .whereNotNull(`p.${pubCol}`);\n });\n\n return idIn(sub);\n }\n\n case 'has-published-version': {\n if (status === 'draft') {\n const sub = knex(`${table} as d`)\n .select(`d.${idCol}`)\n .whereNull(`d.${pubCol}`)\n .whereExists(function (this: any) {\n this.select(knex.raw('1'))\n .from(`${table} as p`)\n .whereRaw(pairOn('p', 'd'))\n .whereNotNull(`p.${pubCol}`);\n });\n\n return idIn(sub);\n }\n\n const sub = knex(`${table} as p`)\n .select(`p.${idCol}`)\n .whereNotNull(`p.${pubCol}`)\n .whereExists(function (this: any) {\n this.select(knex.raw('1'))\n .from(`${table} as d`)\n .whereRaw(pairOn('d', 'p'))\n .whereNull(`d.${pubCol}`);\n });\n\n return idIn(sub);\n }\n\n case 'modified': {\n if (status === 'draft') {\n const sub = knex(`${table} as d`)\n .select(`d.${idCol}`)\n .whereNull(`d.${pubCol}`)\n .whereExists(function (this: any) {\n this.select(knex.raw('1'))\n .from(`${table} as p`)\n .whereRaw(pairOn('p', 'd'))\n .whereNotNull(`p.${pubCol}`)\n .whereRaw(`d.${updatedCol} > p.${updatedCol}`);\n });\n\n return idIn(sub);\n }\n\n const sub = knex(`${table} as p`)\n .select(`p.${idCol}`)\n .whereNotNull(`p.${pubCol}`)\n .whereExists(function (this: any) {\n this.select(knex.raw('1'))\n .from(`${table} as d`)\n .whereRaw(pairOn('d', 'p'))\n .whereNull(`d.${pubCol}`)\n .whereRaw(`d.${updatedCol} > p.${updatedCol}`);\n });\n\n return idIn(sub);\n }\n\n case 'unmodified': {\n if (status === 'draft') {\n const sub = knex(`${table} as d`)\n .select(`d.${idCol}`)\n .whereNull(`d.${pubCol}`)\n .whereExists(function (this: any) {\n this.select(knex.raw('1'))\n .from(`${table} as p`)\n .whereRaw(pairOn('p', 'd'))\n .whereNotNull(`p.${pubCol}`)\n .whereRaw(`d.${updatedCol} <= p.${updatedCol}`);\n });\n\n return idIn(sub);\n }\n\n const sub = knex(`${table} as p`)\n .select(`p.${idCol}`)\n .whereNotNull(`p.${pubCol}`)\n .whereExists(function (this: any) {\n this.select(knex.raw('1'))\n .from(`${table} as d`)\n .whereRaw(pairOn('d', 'p'))\n .whereNull(`d.${pubCol}`)\n .whereRaw(`d.${updatedCol} <= p.${updatedCol}`);\n });\n\n return idIn(sub);\n }\n\n case 'never-published-document': {\n if (status === 'published') {\n return idIn(emptyIdSelection(knex, table, idCol));\n }\n\n const sub = knex(`${table} as d`)\n .select(`d.${idCol}`)\n .whereNull(`d.${pubCol}`)\n .whereNotExists(function (this: any) {\n this.select(knex.raw('1'))\n .from(`${table} as p`)\n .whereRaw(documentOn('p', 'd'))\n .whereNotNull(`p.${pubCol}`);\n });\n\n return idIn(sub);\n }\n\n case 'has-published-version-document': {\n if (status === 'draft') {\n const sub = knex(`${table} as d`)\n .select(`d.${idCol}`)\n .whereNull(`d.${pubCol}`)\n .whereExists(function (this: any) {\n this.select(knex.raw('1'))\n .from(`${table} as p`)\n .whereRaw(documentOn('p', 'd'))\n .whereNotNull(`p.${pubCol}`);\n });\n\n return idIn(sub);\n }\n\n const sub = knex(`${table} as p`)\n .select(`p.${idCol}`)\n .whereNotNull(`p.${pubCol}`)\n .whereExists(function (this: any) {\n this.select(knex.raw('1'))\n .from(`${table} as d`)\n .whereRaw(documentOn('d', 'p'))\n .whereNull(`d.${pubCol}`);\n });\n\n return idIn(sub);\n }\n\n case 'published-without-draft': {\n if (status === 'draft') {\n return idIn(emptyIdSelection(knex, table, idCol));\n }\n\n const sub = knex(`${table} as p`)\n .select(`p.${idCol}`)\n .whereNotNull(`p.${pubCol}`)\n .whereNotExists(function (this: any) {\n this.select(knex.raw('1'))\n .from(`${table} as d`)\n .whereRaw(pairOn('d', 'p'))\n .whereNull(`d.${pubCol}`);\n });\n\n return idIn(sub);\n }\n\n case 'published-with-draft': {\n if (status === 'draft') {\n return idIn(emptyIdSelection(knex, table, idCol));\n }\n\n const sub = knex(`${table} as p`)\n .select(`p.${idCol}`)\n .whereNotNull(`p.${pubCol}`)\n .whereExists(function (this: any) {\n this.select(knex.raw('1'))\n .from(`${table} as d`)\n .whereRaw(pairOn('d', 'p'))\n .whereNull(`d.${pubCol}`);\n });\n\n return idIn(sub);\n }\n\n default: {\n return null;\n }\n }\n};\n"],"names":["ALLOWED","parsePublicationFilter","value","undefined","includes","ValidationError","join","validatePublicationFilterQueryParam","e","prev","details","source","param","columnName","meta","attr","a","attributes","ApplicationError","tableName","emptyIdSelection","knex","table","idCol","select","whereRaw","buildPublicationFilterWhere","model","mode","status","hasDraftAndPublish","docCol","pubCol","updatedCol","hasLocale","Boolean","locale","localeCol","pairOn","aliasA","aliasB","parts","push","documentOn","idIn","sub","id","$in","whereNull","whereNotExists","raw","from","whereNotNull","whereExists"],"mappings":"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"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { ValidationError, ApplicationError } from './errors.mjs';
|
|
2
|
+
import { hasDraftAndPublish } from './content-types.mjs';
|
|
3
|
+
|
|
4
|
+
const ALLOWED = [
|
|
5
|
+
'never-published',
|
|
6
|
+
'has-published-version',
|
|
7
|
+
'modified',
|
|
8
|
+
'unmodified',
|
|
9
|
+
'never-published-document',
|
|
10
|
+
'has-published-version-document',
|
|
11
|
+
'published-without-draft',
|
|
12
|
+
'published-with-draft'
|
|
13
|
+
];
|
|
14
|
+
const parsePublicationFilter = (value)=>{
|
|
15
|
+
if (value === undefined || value === null) {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
if (typeof value === 'string' && ALLOWED.includes(value)) {
|
|
19
|
+
return value;
|
|
20
|
+
}
|
|
21
|
+
throw new ValidationError(`Invalid value for 'publicationFilter'. Expected one of: ${ALLOWED.join(', ')}.`);
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Validates a `publicationFilter` query value for Content API `validate.query` / `sanitize.query`.
|
|
25
|
+
* Attaches `details.source` and `details.param` so HTTP layer maps to 400 with correct field context.
|
|
26
|
+
*/ const validatePublicationFilterQueryParam = (value)=>{
|
|
27
|
+
if (value === undefined || value === null) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
parsePublicationFilter(value);
|
|
32
|
+
} catch (e) {
|
|
33
|
+
if (e instanceof ValidationError) {
|
|
34
|
+
const prev = e.details;
|
|
35
|
+
e.details = {
|
|
36
|
+
...prev && typeof prev === 'object' ? prev : {},
|
|
37
|
+
source: 'query',
|
|
38
|
+
param: 'publicationFilter'
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
throw e;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
const columnName = (meta, attr)=>{
|
|
45
|
+
const a = meta?.attributes?.[attr];
|
|
46
|
+
if (!a) {
|
|
47
|
+
throw new ApplicationError(`Cannot build publicationFilter SQL: attribute '${attr}' is missing from metadata for table '${meta?.tableName ?? '<unknown>'}'.`);
|
|
48
|
+
}
|
|
49
|
+
if (!('columnName' in a) || !a.columnName) {
|
|
50
|
+
throw new ApplicationError(`Cannot build publicationFilter SQL: attribute '${attr}' on table '${meta?.tableName ?? '<unknown>'}' has no resolved columnName.`);
|
|
51
|
+
}
|
|
52
|
+
return a.columnName;
|
|
53
|
+
};
|
|
54
|
+
const emptyIdSelection = (knex, table, idCol)=>knex(table).select(`${table}.${idCol}`).whereRaw('0 = 1');
|
|
55
|
+
/**
|
|
56
|
+
* Extra `id IN (subquery)` filter for publicationFilter, scoped to (documentId, locale) when i18n is enabled.
|
|
57
|
+
* Document-scoped modes use `documentId` only. Returns null when the model does not use draft & publish.
|
|
58
|
+
*/ const buildPublicationFilterWhere = (knex, meta, model, mode, status)=>{
|
|
59
|
+
if (!model || !hasDraftAndPublish(model)) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
const table = meta.tableName;
|
|
63
|
+
const idCol = columnName(meta, 'id');
|
|
64
|
+
const docCol = columnName(meta, 'documentId');
|
|
65
|
+
const pubCol = columnName(meta, 'publishedAt');
|
|
66
|
+
const updatedCol = columnName(meta, 'updatedAt');
|
|
67
|
+
const hasLocale = Boolean(meta.attributes.locale);
|
|
68
|
+
const localeCol = hasLocale ? columnName(meta, 'locale') : null;
|
|
69
|
+
const pairOn = (aliasA, aliasB)=>{
|
|
70
|
+
const parts = [
|
|
71
|
+
`${aliasA}.${docCol} = ${aliasB}.${docCol}`
|
|
72
|
+
];
|
|
73
|
+
if (localeCol) {
|
|
74
|
+
parts.push(`(${aliasA}.${localeCol} = ${aliasB}.${localeCol} OR (${aliasA}.${localeCol} IS NULL AND ${aliasB}.${localeCol} IS NULL))`);
|
|
75
|
+
}
|
|
76
|
+
return parts.join(' AND ');
|
|
77
|
+
};
|
|
78
|
+
const documentOn = (aliasA, aliasB)=>`${aliasA}.${docCol} = ${aliasB}.${docCol}`;
|
|
79
|
+
const idIn = (sub)=>({
|
|
80
|
+
id: {
|
|
81
|
+
$in: sub
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
switch(mode){
|
|
85
|
+
case 'never-published':
|
|
86
|
+
{
|
|
87
|
+
if (status === 'published') {
|
|
88
|
+
return idIn(emptyIdSelection(knex, table, idCol));
|
|
89
|
+
}
|
|
90
|
+
const sub = knex(`${table} as d`).select(`d.${idCol}`).whereNull(`d.${pubCol}`).whereNotExists(function() {
|
|
91
|
+
this.select(knex.raw('1')).from(`${table} as p`).whereRaw(pairOn('p', 'd')).whereNotNull(`p.${pubCol}`);
|
|
92
|
+
});
|
|
93
|
+
return idIn(sub);
|
|
94
|
+
}
|
|
95
|
+
case 'has-published-version':
|
|
96
|
+
{
|
|
97
|
+
if (status === 'draft') {
|
|
98
|
+
const sub = knex(`${table} as d`).select(`d.${idCol}`).whereNull(`d.${pubCol}`).whereExists(function() {
|
|
99
|
+
this.select(knex.raw('1')).from(`${table} as p`).whereRaw(pairOn('p', 'd')).whereNotNull(`p.${pubCol}`);
|
|
100
|
+
});
|
|
101
|
+
return idIn(sub);
|
|
102
|
+
}
|
|
103
|
+
const sub = knex(`${table} as p`).select(`p.${idCol}`).whereNotNull(`p.${pubCol}`).whereExists(function() {
|
|
104
|
+
this.select(knex.raw('1')).from(`${table} as d`).whereRaw(pairOn('d', 'p')).whereNull(`d.${pubCol}`);
|
|
105
|
+
});
|
|
106
|
+
return idIn(sub);
|
|
107
|
+
}
|
|
108
|
+
case 'modified':
|
|
109
|
+
{
|
|
110
|
+
if (status === 'draft') {
|
|
111
|
+
const sub = knex(`${table} as d`).select(`d.${idCol}`).whereNull(`d.${pubCol}`).whereExists(function() {
|
|
112
|
+
this.select(knex.raw('1')).from(`${table} as p`).whereRaw(pairOn('p', 'd')).whereNotNull(`p.${pubCol}`).whereRaw(`d.${updatedCol} > p.${updatedCol}`);
|
|
113
|
+
});
|
|
114
|
+
return idIn(sub);
|
|
115
|
+
}
|
|
116
|
+
const sub = knex(`${table} as p`).select(`p.${idCol}`).whereNotNull(`p.${pubCol}`).whereExists(function() {
|
|
117
|
+
this.select(knex.raw('1')).from(`${table} as d`).whereRaw(pairOn('d', 'p')).whereNull(`d.${pubCol}`).whereRaw(`d.${updatedCol} > p.${updatedCol}`);
|
|
118
|
+
});
|
|
119
|
+
return idIn(sub);
|
|
120
|
+
}
|
|
121
|
+
case 'unmodified':
|
|
122
|
+
{
|
|
123
|
+
if (status === 'draft') {
|
|
124
|
+
const sub = knex(`${table} as d`).select(`d.${idCol}`).whereNull(`d.${pubCol}`).whereExists(function() {
|
|
125
|
+
this.select(knex.raw('1')).from(`${table} as p`).whereRaw(pairOn('p', 'd')).whereNotNull(`p.${pubCol}`).whereRaw(`d.${updatedCol} <= p.${updatedCol}`);
|
|
126
|
+
});
|
|
127
|
+
return idIn(sub);
|
|
128
|
+
}
|
|
129
|
+
const sub = knex(`${table} as p`).select(`p.${idCol}`).whereNotNull(`p.${pubCol}`).whereExists(function() {
|
|
130
|
+
this.select(knex.raw('1')).from(`${table} as d`).whereRaw(pairOn('d', 'p')).whereNull(`d.${pubCol}`).whereRaw(`d.${updatedCol} <= p.${updatedCol}`);
|
|
131
|
+
});
|
|
132
|
+
return idIn(sub);
|
|
133
|
+
}
|
|
134
|
+
case 'never-published-document':
|
|
135
|
+
{
|
|
136
|
+
if (status === 'published') {
|
|
137
|
+
return idIn(emptyIdSelection(knex, table, idCol));
|
|
138
|
+
}
|
|
139
|
+
const sub = knex(`${table} as d`).select(`d.${idCol}`).whereNull(`d.${pubCol}`).whereNotExists(function() {
|
|
140
|
+
this.select(knex.raw('1')).from(`${table} as p`).whereRaw(documentOn('p', 'd')).whereNotNull(`p.${pubCol}`);
|
|
141
|
+
});
|
|
142
|
+
return idIn(sub);
|
|
143
|
+
}
|
|
144
|
+
case 'has-published-version-document':
|
|
145
|
+
{
|
|
146
|
+
if (status === 'draft') {
|
|
147
|
+
const sub = knex(`${table} as d`).select(`d.${idCol}`).whereNull(`d.${pubCol}`).whereExists(function() {
|
|
148
|
+
this.select(knex.raw('1')).from(`${table} as p`).whereRaw(documentOn('p', 'd')).whereNotNull(`p.${pubCol}`);
|
|
149
|
+
});
|
|
150
|
+
return idIn(sub);
|
|
151
|
+
}
|
|
152
|
+
const sub = knex(`${table} as p`).select(`p.${idCol}`).whereNotNull(`p.${pubCol}`).whereExists(function() {
|
|
153
|
+
this.select(knex.raw('1')).from(`${table} as d`).whereRaw(documentOn('d', 'p')).whereNull(`d.${pubCol}`);
|
|
154
|
+
});
|
|
155
|
+
return idIn(sub);
|
|
156
|
+
}
|
|
157
|
+
case 'published-without-draft':
|
|
158
|
+
{
|
|
159
|
+
if (status === 'draft') {
|
|
160
|
+
return idIn(emptyIdSelection(knex, table, idCol));
|
|
161
|
+
}
|
|
162
|
+
const sub = knex(`${table} as p`).select(`p.${idCol}`).whereNotNull(`p.${pubCol}`).whereNotExists(function() {
|
|
163
|
+
this.select(knex.raw('1')).from(`${table} as d`).whereRaw(pairOn('d', 'p')).whereNull(`d.${pubCol}`);
|
|
164
|
+
});
|
|
165
|
+
return idIn(sub);
|
|
166
|
+
}
|
|
167
|
+
case 'published-with-draft':
|
|
168
|
+
{
|
|
169
|
+
if (status === 'draft') {
|
|
170
|
+
return idIn(emptyIdSelection(knex, table, idCol));
|
|
171
|
+
}
|
|
172
|
+
const sub = knex(`${table} as p`).select(`p.${idCol}`).whereNotNull(`p.${pubCol}`).whereExists(function() {
|
|
173
|
+
this.select(knex.raw('1')).from(`${table} as d`).whereRaw(pairOn('d', 'p')).whereNull(`d.${pubCol}`);
|
|
174
|
+
});
|
|
175
|
+
return idIn(sub);
|
|
176
|
+
}
|
|
177
|
+
default:
|
|
178
|
+
{
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
export { buildPublicationFilterWhere, parsePublicationFilter, validatePublicationFilterQueryParam };
|
|
185
|
+
//# sourceMappingURL=publication-filter.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publication-filter.mjs","sources":["../src/publication-filter.ts"],"sourcesContent":["import type { Model } from './types';\nimport { ApplicationError, ValidationError } from './errors';\nimport { hasDraftAndPublish } from './content-types';\n\nexport type PublicationFilterMode =\n | 'never-published'\n | 'has-published-version'\n | 'modified'\n | 'unmodified'\n | 'never-published-document'\n | 'has-published-version-document'\n | 'published-without-draft'\n | 'published-with-draft';\n\nconst ALLOWED: PublicationFilterMode[] = [\n 'never-published',\n 'has-published-version',\n 'modified',\n 'unmodified',\n 'never-published-document',\n 'has-published-version-document',\n 'published-without-draft',\n 'published-with-draft',\n];\n\nexport const parsePublicationFilter = (value: unknown): PublicationFilterMode | undefined => {\n if (value === undefined || value === null) {\n return undefined;\n }\n\n if (typeof value === 'string' && (ALLOWED as string[]).includes(value)) {\n return value as PublicationFilterMode;\n }\n\n throw new ValidationError(\n `Invalid value for 'publicationFilter'. Expected one of: ${ALLOWED.join(', ')}.`\n );\n};\n\ntype QueryParamDetails = { source?: string; param?: string; [key: string]: unknown };\n\n/**\n * Validates a `publicationFilter` query value for Content API `validate.query` / `sanitize.query`.\n * Attaches `details.source` and `details.param` so HTTP layer maps to 400 with correct field context.\n */\nexport const validatePublicationFilterQueryParam = (value: unknown): void => {\n if (value === undefined || value === null) {\n return;\n }\n\n try {\n parsePublicationFilter(value);\n } catch (e) {\n if (e instanceof ValidationError) {\n const prev = e.details as QueryParamDetails | undefined;\n e.details = {\n ...(prev && typeof prev === 'object' ? prev : {}),\n source: 'query',\n param: 'publicationFilter',\n };\n }\n throw e;\n }\n};\n\nconst columnName = (meta: any, attr: string): string => {\n const a = meta?.attributes?.[attr];\n if (!a) {\n throw new ApplicationError(\n `Cannot build publicationFilter SQL: attribute '${attr}' is missing from metadata for table '${meta?.tableName ?? '<unknown>'}'.`\n );\n }\n if (!('columnName' in a) || !a.columnName) {\n throw new ApplicationError(\n `Cannot build publicationFilter SQL: attribute '${attr}' on table '${meta?.tableName ?? '<unknown>'}' has no resolved columnName.`\n );\n }\n return a.columnName as string;\n};\n\nconst emptyIdSelection = (knex: any, table: string, idCol: string) =>\n knex(table).select(`${table}.${idCol}`).whereRaw('0 = 1');\n\n/**\n * Extra `id IN (subquery)` filter for publicationFilter, scoped to (documentId, locale) when i18n is enabled.\n * Document-scoped modes use `documentId` only. Returns null when the model does not use draft & publish.\n */\nexport const buildPublicationFilterWhere = (\n knex: any,\n meta: any,\n model: Model | undefined,\n mode: PublicationFilterMode,\n status: 'draft' | 'published'\n): Record<string, unknown> | null => {\n if (!model || !hasDraftAndPublish(model)) {\n return null;\n }\n\n const table = meta.tableName;\n const idCol = columnName(meta, 'id');\n const docCol = columnName(meta, 'documentId');\n const pubCol = columnName(meta, 'publishedAt');\n const updatedCol = columnName(meta, 'updatedAt');\n const hasLocale = Boolean(meta.attributes.locale);\n const localeCol = hasLocale ? columnName(meta, 'locale') : null;\n\n const pairOn = (aliasA: string, aliasB: string) => {\n const parts = [`${aliasA}.${docCol} = ${aliasB}.${docCol}`];\n if (localeCol) {\n parts.push(\n `(${aliasA}.${localeCol} = ${aliasB}.${localeCol} OR (${aliasA}.${localeCol} IS NULL AND ${aliasB}.${localeCol} IS NULL))`\n );\n }\n return parts.join(' AND ');\n };\n\n const documentOn = (aliasA: string, aliasB: string) =>\n `${aliasA}.${docCol} = ${aliasB}.${docCol}`;\n\n const idIn = (sub: any) => ({ id: { $in: sub } });\n\n switch (mode) {\n case 'never-published': {\n if (status === 'published') {\n return idIn(emptyIdSelection(knex, table, idCol));\n }\n\n const sub = knex(`${table} as d`)\n .select(`d.${idCol}`)\n .whereNull(`d.${pubCol}`)\n .whereNotExists(function (this: any) {\n this.select(knex.raw('1'))\n .from(`${table} as p`)\n .whereRaw(pairOn('p', 'd'))\n .whereNotNull(`p.${pubCol}`);\n });\n\n return idIn(sub);\n }\n\n case 'has-published-version': {\n if (status === 'draft') {\n const sub = knex(`${table} as d`)\n .select(`d.${idCol}`)\n .whereNull(`d.${pubCol}`)\n .whereExists(function (this: any) {\n this.select(knex.raw('1'))\n .from(`${table} as p`)\n .whereRaw(pairOn('p', 'd'))\n .whereNotNull(`p.${pubCol}`);\n });\n\n return idIn(sub);\n }\n\n const sub = knex(`${table} as p`)\n .select(`p.${idCol}`)\n .whereNotNull(`p.${pubCol}`)\n .whereExists(function (this: any) {\n this.select(knex.raw('1'))\n .from(`${table} as d`)\n .whereRaw(pairOn('d', 'p'))\n .whereNull(`d.${pubCol}`);\n });\n\n return idIn(sub);\n }\n\n case 'modified': {\n if (status === 'draft') {\n const sub = knex(`${table} as d`)\n .select(`d.${idCol}`)\n .whereNull(`d.${pubCol}`)\n .whereExists(function (this: any) {\n this.select(knex.raw('1'))\n .from(`${table} as p`)\n .whereRaw(pairOn('p', 'd'))\n .whereNotNull(`p.${pubCol}`)\n .whereRaw(`d.${updatedCol} > p.${updatedCol}`);\n });\n\n return idIn(sub);\n }\n\n const sub = knex(`${table} as p`)\n .select(`p.${idCol}`)\n .whereNotNull(`p.${pubCol}`)\n .whereExists(function (this: any) {\n this.select(knex.raw('1'))\n .from(`${table} as d`)\n .whereRaw(pairOn('d', 'p'))\n .whereNull(`d.${pubCol}`)\n .whereRaw(`d.${updatedCol} > p.${updatedCol}`);\n });\n\n return idIn(sub);\n }\n\n case 'unmodified': {\n if (status === 'draft') {\n const sub = knex(`${table} as d`)\n .select(`d.${idCol}`)\n .whereNull(`d.${pubCol}`)\n .whereExists(function (this: any) {\n this.select(knex.raw('1'))\n .from(`${table} as p`)\n .whereRaw(pairOn('p', 'd'))\n .whereNotNull(`p.${pubCol}`)\n .whereRaw(`d.${updatedCol} <= p.${updatedCol}`);\n });\n\n return idIn(sub);\n }\n\n const sub = knex(`${table} as p`)\n .select(`p.${idCol}`)\n .whereNotNull(`p.${pubCol}`)\n .whereExists(function (this: any) {\n this.select(knex.raw('1'))\n .from(`${table} as d`)\n .whereRaw(pairOn('d', 'p'))\n .whereNull(`d.${pubCol}`)\n .whereRaw(`d.${updatedCol} <= p.${updatedCol}`);\n });\n\n return idIn(sub);\n }\n\n case 'never-published-document': {\n if (status === 'published') {\n return idIn(emptyIdSelection(knex, table, idCol));\n }\n\n const sub = knex(`${table} as d`)\n .select(`d.${idCol}`)\n .whereNull(`d.${pubCol}`)\n .whereNotExists(function (this: any) {\n this.select(knex.raw('1'))\n .from(`${table} as p`)\n .whereRaw(documentOn('p', 'd'))\n .whereNotNull(`p.${pubCol}`);\n });\n\n return idIn(sub);\n }\n\n case 'has-published-version-document': {\n if (status === 'draft') {\n const sub = knex(`${table} as d`)\n .select(`d.${idCol}`)\n .whereNull(`d.${pubCol}`)\n .whereExists(function (this: any) {\n this.select(knex.raw('1'))\n .from(`${table} as p`)\n .whereRaw(documentOn('p', 'd'))\n .whereNotNull(`p.${pubCol}`);\n });\n\n return idIn(sub);\n }\n\n const sub = knex(`${table} as p`)\n .select(`p.${idCol}`)\n .whereNotNull(`p.${pubCol}`)\n .whereExists(function (this: any) {\n this.select(knex.raw('1'))\n .from(`${table} as d`)\n .whereRaw(documentOn('d', 'p'))\n .whereNull(`d.${pubCol}`);\n });\n\n return idIn(sub);\n }\n\n case 'published-without-draft': {\n if (status === 'draft') {\n return idIn(emptyIdSelection(knex, table, idCol));\n }\n\n const sub = knex(`${table} as p`)\n .select(`p.${idCol}`)\n .whereNotNull(`p.${pubCol}`)\n .whereNotExists(function (this: any) {\n this.select(knex.raw('1'))\n .from(`${table} as d`)\n .whereRaw(pairOn('d', 'p'))\n .whereNull(`d.${pubCol}`);\n });\n\n return idIn(sub);\n }\n\n case 'published-with-draft': {\n if (status === 'draft') {\n return idIn(emptyIdSelection(knex, table, idCol));\n }\n\n const sub = knex(`${table} as p`)\n .select(`p.${idCol}`)\n .whereNotNull(`p.${pubCol}`)\n .whereExists(function (this: any) {\n this.select(knex.raw('1'))\n .from(`${table} as d`)\n .whereRaw(pairOn('d', 'p'))\n .whereNull(`d.${pubCol}`);\n });\n\n return idIn(sub);\n }\n\n default: {\n return null;\n }\n }\n};\n"],"names":["ALLOWED","parsePublicationFilter","value","undefined","includes","ValidationError","join","validatePublicationFilterQueryParam","e","prev","details","source","param","columnName","meta","attr","a","attributes","ApplicationError","tableName","emptyIdSelection","knex","table","idCol","select","whereRaw","buildPublicationFilterWhere","model","mode","status","hasDraftAndPublish","docCol","pubCol","updatedCol","hasLocale","Boolean","locale","localeCol","pairOn","aliasA","aliasB","parts","push","documentOn","idIn","sub","id","$in","whereNull","whereNotExists","raw","from","whereNotNull","whereExists"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sanitize/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAM1C,OAAO,EACL,KAAK,SAAS,EAGf,MAAM,6BAA6B,CAAC;AAGrC,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAI3C,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sanitize/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAM1C,OAAO,EACL,KAAK,SAAS,EAGf,MAAM,6BAA6B,CAAC;AAGrC,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAI3C,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAG5C,MAAM,WAAW,OAAO;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,CAAC,MAAM,EAAE,KAAK,GAAG,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;CACxD;AACD,MAAM,WAAW,YAAY;IAC3B,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACrE;AAED,MAAM,MAAM,yBAAyB,GAAG,CACtC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,KAAK,EACb,OAAO,CAAC,EAAE,OAAO,KACd,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,MAAM,MAAM,wBAAwB,GAAG,CACrC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,KAAK,EACb,OAAO,CAAC,EAAE,OAAO,KACd,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,MAAM,WAAW,UAAU;IACzB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC;CACpC;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;CACtB;AAED,QAAA,MAAM,mBAAmB,SAAU,UAAU;;;mBAoHlC,OAAO,MAAM,EAAE,OAAO,CAAC,UACtB,KAAK,kCAC0B,OAAO;;;;;CA0HjD,CAAC;AAEF,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;AAErD,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
|
package/dist/sanitize/index.js
CHANGED
|
@@ -12,6 +12,7 @@ var queryFilters = require('../traverse/query-filters.js');
|
|
|
12
12
|
var querySort = require('../traverse/query-sort.js');
|
|
13
13
|
var queryPopulate = require('../traverse/query-populate.js');
|
|
14
14
|
require('../traverse/query-fields.js');
|
|
15
|
+
var publicationFilter = require('../publication-filter.js');
|
|
15
16
|
var removeUnrecognizedFields = require('./visitors/remove-unrecognized-fields.js');
|
|
16
17
|
var removeRestrictedRelations = require('./visitors/remove-restricted-relations.js');
|
|
17
18
|
var removeRestrictedFields = require('./visitors/remove-restricted-fields.js');
|
|
@@ -127,6 +128,9 @@ const createAPISanitizers = (opts)=>{
|
|
|
127
128
|
}
|
|
128
129
|
const { filters, sort, fields, populate } = query;
|
|
129
130
|
const sanitizedQuery = fp.cloneDeep(query);
|
|
131
|
+
if ('publicationFilter' in sanitizedQuery) {
|
|
132
|
+
publicationFilter.validatePublicationFilterQueryParam(sanitizedQuery.publicationFilter);
|
|
133
|
+
}
|
|
130
134
|
if (filters) {
|
|
131
135
|
Object.assign(sanitizedQuery, {
|
|
132
136
|
filters: await sanitizeFilters(filters, schema, {
|