node_modules ignore

This commit is contained in:
2025-05-08 23:43:47 +02:00
parent e19d52f172
commit 4574544c9f
65041 changed files with 10593536 additions and 0 deletions

View File

@@ -0,0 +1,89 @@
import { AnyAttribute, Attribute, ComponentAttribute, DynamicZoneAttribute, Model, RelationalAttribute } from '../types';
export interface Path {
raw: string | null;
attribute: string | null;
}
export interface Parent {
attribute?: Attribute;
key: string | null;
path: Path;
schema: Model;
}
export interface TraverseOptions {
schema: Model;
path?: Path;
parent?: Parent;
getModel(uid: string): Model;
}
export interface VisitorOptions {
data: unknown;
value: unknown;
schema: Model;
key: string;
attribute?: AnyAttribute;
path: Path;
parent?: Parent;
getModel(uid: string): Model;
}
export type Traverse = (visitor: Visitor, options: TraverseOptions, data: unknown) => Promise<unknown>;
export interface Visitor {
(visitorOptions: VisitorOptions, opts: Pick<TransformUtils, 'set' | 'remove'>): void;
}
interface Interceptor<T = unknown> {
predicate(data: unknown): data is T;
handler(visitor: Visitor, options: TraverseOptions, data: T, recurseOptions: {
recurse: Traverse;
}): void;
}
interface ParseUtils<T> {
transform(data: T): unknown;
remove(key: string, data: T): unknown;
set(key: string, value: unknown, data: T): unknown;
keys(data: T): string[];
get(key: string, data: T): unknown;
}
interface Parser<T = unknown> {
predicate(data: unknown): data is T;
parser(data: T): ParseUtils<T>;
}
interface Ignore {
(ctx: Context): boolean;
}
interface AttributeHandler<AttributeType = Attribute> {
predicate(ctx: Context<AttributeType>): boolean;
handler(ctx: Context<AttributeType>, opts: Pick<TransformUtils, 'set' | 'recurse'>): void;
}
interface CommonHandler<AttributeType = Attribute> {
predicate(ctx: Context<AttributeType>): boolean;
handler(ctx: Context<AttributeType>, opts: Pick<TransformUtils, 'set' | 'recurse'>): void;
}
export interface TransformUtils {
remove(key: string): void;
set(key: string, value: unknown): void;
recurse: Traverse;
}
interface Context<AttributeType = Attribute> {
key: string;
value: unknown;
attribute: AttributeType;
schema: Model;
path: Path;
data: unknown;
visitor: Visitor;
parent?: Parent;
getModel(uid: string): Model;
}
declare const _default: () => {
traverse: Traverse;
intercept<T>(predicate: Interceptor<T>['predicate'], handler: Interceptor<T>['handler']): any;
parse<T_1>(predicate: (data: unknown) => data is T_1, parser: (data: T_1) => ParseUtils<T_1>): any;
ignore(predicate: Ignore): any;
on(predicate: CommonHandler['predicate'], handler: CommonHandler['handler']): any;
onAttribute(predicate: AttributeHandler['predicate'], handler: AttributeHandler['handler']): any;
onRelation(handler: AttributeHandler<RelationalAttribute>['handler']): any;
onMedia(handler: AttributeHandler<RelationalAttribute>['handler']): any;
onComponent(handler: AttributeHandler<ComponentAttribute>['handler']): any;
onDynamicZone(handler: AttributeHandler<DynamicZoneAttribute>['handler']): any;
};
export default _default;
//# sourceMappingURL=factory.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/traverse/factory.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,YAAY,EACZ,SAAS,EACT,kBAAkB,EAClB,oBAAoB,EACpB,KAAK,EACL,mBAAmB,EACpB,MAAM,UAAU,CAAC;AAElB,MAAM,WAAW,IAAI;IACnB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,MAAM;IACrB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,KAAK,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,KAAK,CAAC;IACd,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,KAAK,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,YAAY,CAAC;IACzB,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;CAC9B;AAED,MAAM,MAAM,QAAQ,GAAG,CACrB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,eAAe,EACxB,IAAI,EAAE,OAAO,KACV,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,MAAM,WAAW,OAAO;IACtB,CAAC,cAAc,EAAE,cAAc,EAAE,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,KAAK,GAAG,QAAQ,CAAC,GAAG,IAAI,CAAC;CACtF;AAED,UAAU,WAAW,CAAC,CAAC,GAAG,OAAO;IAC/B,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,CAAC,CAAC;IACpC,OAAO,CACL,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,eAAe,EACxB,IAAI,EAAE,CAAC,EACP,cAAc,EAAE;QAAE,OAAO,EAAE,QAAQ,CAAA;KAAE,GACpC,IAAI,CAAC;CACT;AAED,UAAU,UAAU,CAAC,CAAC;IACpB,SAAS,CAAC,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC;IAC5B,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC;IACtC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC;IACnD,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC;IACxB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC;CACpC;AAED,UAAU,MAAM,CAAC,CAAC,GAAG,OAAO;IAC1B,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,CAAC,CAAC;IACpC,MAAM,CAAC,IAAI,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;CAChC;AAED,UAAU,MAAM;IACd,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC;CACzB;AAED,UAAU,gBAAgB,CAAC,aAAa,GAAG,SAAS;IAClD,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC;IAChD,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,KAAK,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC;CAC3F;AACD,UAAU,aAAa,CAAC,aAAa,GAAG,SAAS;IAC/C,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC;IAChD,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,KAAK,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC;CAC3F;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IACvC,OAAO,EAAE,QAAQ,CAAC;CACnB;AAED,UAAU,OAAO,CAAC,aAAa,GAAG,SAAS;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,aAAa,CAAC;IACzB,MAAM,EAAE,KAAK,CAAC;IACd,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;CAC9B;;;4BA4H2B,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,WAAW,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC;;sBAUrE,MAAM;kBAKV,aAAa,CAAC,WAAW,CAAC,WAAW,aAAa,CAAC,SAAS,CAAC;2BAKpD,gBAAgB,CAAC,WAAW,CAAC,WAAW,gBAAgB,CAAC,SAAS,CAAC;wBAKtE,iBAAiB,mBAAmB,CAAC,CAAC,SAAS,CAAC;qBAInD,iBAAiB,mBAAmB,CAAC,CAAC,SAAS,CAAC;yBAI5C,iBAAiB,kBAAkB,CAAC,CAAC,SAAS,CAAC;2BAI7C,iBAAiB,oBAAoB,CAAC,CAAC,SAAS,CAAC;;AAnJ5E,wBAuJE"}

View File

@@ -0,0 +1,158 @@
'use strict';
var fp = require('lodash/fp');
const DEFAULT_PATH = {
raw: null,
attribute: null
};
var traverseFactory = (()=>{
const state = {
parsers: [],
interceptors: [],
ignore: [],
handlers: {
attributes: [],
common: []
}
};
const traverse = async (visitor, options, data)=>{
const { path = DEFAULT_PATH, parent, schema, getModel } = options ?? {};
// interceptors
for (const { predicate, handler } of state.interceptors){
if (predicate(data)) {
return handler(visitor, options, data, {
recurse: traverse
});
}
}
// parsers
const parser = state.parsers.find((parser)=>parser.predicate(data))?.parser;
const utils = parser?.(data);
// Return the data untouched if we don't know how to traverse it
if (!utils) {
return data;
}
// main loop
let out = utils.transform(data);
const keys = utils.keys(out);
for (const key of keys){
const attribute = schema?.attributes?.[key];
const newPath = {
...path
};
newPath.raw = fp.isNil(path.raw) ? key : `${path.raw}.${key}`;
if (!fp.isNil(attribute)) {
newPath.attribute = fp.isNil(path.attribute) ? key : `${path.attribute}.${key}`;
}
// visitors
const visitorOptions = {
key,
value: utils.get(key, out),
attribute,
schema,
path: newPath,
data: out,
getModel,
parent
};
const transformUtils = {
remove (key) {
out = utils.remove(key, out);
},
set (key, value) {
out = utils.set(key, value, out);
},
recurse: traverse
};
await visitor(visitorOptions, fp.pick([
'remove',
'set'
], transformUtils));
const value = utils.get(key, out);
const createContext = ()=>({
key,
value,
attribute,
schema,
path: newPath,
data: out,
visitor,
getModel,
parent
});
// ignore
const ignoreCtx = createContext();
const shouldIgnore = state.ignore.some((predicate)=>predicate(ignoreCtx));
if (shouldIgnore) {
continue;
}
// handlers
const handlers = [
...state.handlers.common,
...state.handlers.attributes
];
for await (const handler of handlers){
const ctx = createContext();
const pass = await handler.predicate(ctx);
if (pass) {
await handler.handler(ctx, fp.pick([
'recurse',
'set'
], transformUtils));
}
}
}
return out;
};
return {
traverse,
intercept (predicate, handler) {
state.interceptors.push({
predicate,
handler
});
return this;
},
parse (predicate, parser) {
state.parsers.push({
predicate,
parser
});
return this;
},
ignore (predicate) {
state.ignore.push(predicate);
return this;
},
on (predicate, handler) {
state.handlers.common.push({
predicate,
handler
});
return this;
},
onAttribute (predicate, handler) {
state.handlers.attributes.push({
predicate,
handler
});
return this;
},
onRelation (handler) {
return this.onAttribute(({ attribute })=>attribute?.type === 'relation', handler);
},
onMedia (handler) {
return this.onAttribute(({ attribute })=>attribute?.type === 'media', handler);
},
onComponent (handler) {
return this.onAttribute(({ attribute })=>attribute?.type === 'component', handler);
},
onDynamicZone (handler) {
return this.onAttribute(({ attribute })=>attribute?.type === 'dynamiczone', handler);
}
};
});
module.exports = traverseFactory;
//# sourceMappingURL=factory.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,156 @@
import { isNil, pick } from 'lodash/fp';
const DEFAULT_PATH = {
raw: null,
attribute: null
};
var traverseFactory = (()=>{
const state = {
parsers: [],
interceptors: [],
ignore: [],
handlers: {
attributes: [],
common: []
}
};
const traverse = async (visitor, options, data)=>{
const { path = DEFAULT_PATH, parent, schema, getModel } = options ?? {};
// interceptors
for (const { predicate, handler } of state.interceptors){
if (predicate(data)) {
return handler(visitor, options, data, {
recurse: traverse
});
}
}
// parsers
const parser = state.parsers.find((parser)=>parser.predicate(data))?.parser;
const utils = parser?.(data);
// Return the data untouched if we don't know how to traverse it
if (!utils) {
return data;
}
// main loop
let out = utils.transform(data);
const keys = utils.keys(out);
for (const key of keys){
const attribute = schema?.attributes?.[key];
const newPath = {
...path
};
newPath.raw = isNil(path.raw) ? key : `${path.raw}.${key}`;
if (!isNil(attribute)) {
newPath.attribute = isNil(path.attribute) ? key : `${path.attribute}.${key}`;
}
// visitors
const visitorOptions = {
key,
value: utils.get(key, out),
attribute,
schema,
path: newPath,
data: out,
getModel,
parent
};
const transformUtils = {
remove (key) {
out = utils.remove(key, out);
},
set (key, value) {
out = utils.set(key, value, out);
},
recurse: traverse
};
await visitor(visitorOptions, pick([
'remove',
'set'
], transformUtils));
const value = utils.get(key, out);
const createContext = ()=>({
key,
value,
attribute,
schema,
path: newPath,
data: out,
visitor,
getModel,
parent
});
// ignore
const ignoreCtx = createContext();
const shouldIgnore = state.ignore.some((predicate)=>predicate(ignoreCtx));
if (shouldIgnore) {
continue;
}
// handlers
const handlers = [
...state.handlers.common,
...state.handlers.attributes
];
for await (const handler of handlers){
const ctx = createContext();
const pass = await handler.predicate(ctx);
if (pass) {
await handler.handler(ctx, pick([
'recurse',
'set'
], transformUtils));
}
}
}
return out;
};
return {
traverse,
intercept (predicate, handler) {
state.interceptors.push({
predicate,
handler
});
return this;
},
parse (predicate, parser) {
state.parsers.push({
predicate,
parser
});
return this;
},
ignore (predicate) {
state.ignore.push(predicate);
return this;
},
on (predicate, handler) {
state.handlers.common.push({
predicate,
handler
});
return this;
},
onAttribute (predicate, handler) {
state.handlers.attributes.push({
predicate,
handler
});
return this;
},
onRelation (handler) {
return this.onAttribute(({ attribute })=>attribute?.type === 'relation', handler);
},
onMedia (handler) {
return this.onAttribute(({ attribute })=>attribute?.type === 'media', handler);
},
onComponent (handler) {
return this.onAttribute(({ attribute })=>attribute?.type === 'component', handler);
},
onDynamicZone (handler) {
return this.onAttribute(({ attribute })=>attribute?.type === 'dynamiczone', handler);
}
};
});
export { traverseFactory as default };
//# sourceMappingURL=factory.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
export { default as traverseQueryFilters } from './query-filters';
export { default as traverseQuerySort } from './query-sort';
export { default as traverseQueryPopulate } from './query-populate';
export { default as traverseQueryFields } from './query-fields';
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/traverse/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,gBAAgB,CAAC"}

View File

@@ -0,0 +1,14 @@
'use strict';
var queryFilters = require('./query-filters.js');
var querySort = require('./query-sort.js');
var queryPopulate = require('./query-populate.js');
var queryFields = require('./query-fields.js');
exports.traverseQueryFilters = queryFilters;
exports.traverseQuerySort = querySort;
exports.traverseQueryPopulate = queryPopulate;
exports.traverseQueryFields = queryFields;
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"}

View File

@@ -0,0 +1,5 @@
export { default as traverseQueryFilters } from './query-filters.mjs';
export { default as traverseQuerySort } from './query-sort.mjs';
export { default as traverseQueryPopulate } from './query-populate.mjs';
export { default as traverseQueryFields } from './query-fields.mjs';
//# sourceMappingURL=index.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"}

View File

@@ -0,0 +1,4 @@
/// <reference types="lodash" />
declare const _default: import("lodash").CurriedFunction3<import("./factory").Visitor, import("./factory").TraverseOptions, unknown, Promise<unknown>>;
export default _default;
//# sourceMappingURL=query-fields.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"query-fields.d.ts","sourceRoot":"","sources":["../../src/traverse/query-fields.ts"],"names":[],"mappings":";;AA+CA,wBAAsC"}

View File

@@ -0,0 +1,41 @@
'use strict';
var fp = require('lodash/fp');
var factory = require('./factory.js');
const isStringArray = (value)=>{
return fp.isArray(value) && value.every(fp.isString);
};
const fields = factory()// Intercept array of strings
// e.g. fields=['title', 'description']
.intercept(isStringArray, async (visitor, options, fields, { recurse })=>{
return Promise.all(fields.map((field)=>recurse(visitor, options, field)));
})// Intercept comma separated fields (as string)
// e.g. fields='title,description'
.intercept((value)=>fp.isString(value) && value.includes(','), (visitor, options, fields, { recurse })=>{
return Promise.all(fields.split(',').map((field)=>recurse(visitor, options, field)));
})// Return wildcards as is
.intercept((value)=>fp.eq('*', value), fp.constant('*'))// Parse string values
// Since we're parsing strings only, each value should be an attribute name (and it's value, undefined),
// thus it shouldn't be possible to set a new value, and get should return the whole data if key === data
.parse(fp.isString, ()=>({
transform: fp.trim,
remove (key, data) {
return data === key ? undefined : data;
},
set (_key, _value, data) {
return data;
},
keys (data) {
return [
data
];
},
get (key, data) {
return key === data ? data : undefined;
}
}));
var traverseQueryFields = fp.curry(fields.traverse);
module.exports = traverseQueryFields;
//# sourceMappingURL=query-fields.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"query-fields.js","sources":["../../src/traverse/query-fields.ts"],"sourcesContent":["import { curry, isArray, isString, eq, trim, constant } from 'lodash/fp';\n\nimport traverseFactory from './factory';\n\nconst isStringArray = (value: unknown): value is string[] => {\n return isArray(value) && value.every(isString);\n};\n\nconst fields = traverseFactory()\n // Intercept array of strings\n // e.g. fields=['title', 'description']\n .intercept(isStringArray, async (visitor, options, fields, { recurse }) => {\n return Promise.all(fields.map((field) => recurse(visitor, options, field)));\n })\n // Intercept comma separated fields (as string)\n // e.g. fields='title,description'\n .intercept(\n (value): value is string => isString(value) && value.includes(','),\n (visitor, options, fields, { recurse }) => {\n return Promise.all(fields.split(',').map((field) => recurse(visitor, options, field)));\n }\n )\n // Return wildcards as is\n .intercept((value): value is string => eq('*', value), constant('*'))\n // Parse string values\n // Since we're parsing strings only, each value should be an attribute name (and it's value, undefined),\n // thus it shouldn't be possible to set a new value, and get should return the whole data if key === data\n .parse(isString, () => ({\n transform: trim,\n\n remove(key, data) {\n return data === key ? undefined : data;\n },\n\n set(_key, _value, data) {\n return data;\n },\n\n keys(data) {\n return [data];\n },\n\n get(key, data) {\n return key === data ? data : undefined;\n },\n }));\n\nexport default curry(fields.traverse);\n"],"names":["isStringArray","value","isArray","every","isString","fields","traverseFactory","intercept","visitor","options","recurse","Promise","all","map","field","includes","split","eq","constant","parse","transform","trim","remove","key","data","undefined","set","_key","_value","keys","get","curry","traverse"],"mappings":";;;;;AAIA,MAAMA,gBAAgB,CAACC,KAAAA,GAAAA;AACrB,IAAA,OAAOC,UAAQD,CAAAA,KAAAA,CAAAA,IAAUA,KAAME,CAAAA,KAAK,CAACC,WAAAA,CAAAA;AACvC,CAAA;AAEA,MAAMC,MAAAA,GAASC,SACb;AACA;CACCC,SAAS,CAACP,eAAe,OAAOQ,OAAAA,EAASC,SAASJ,MAAQ,EAAA,EAAEK,OAAO,EAAE,GAAA;IACpE,OAAOC,OAAAA,CAAQC,GAAG,CAACP,MAAOQ,CAAAA,GAAG,CAAC,CAACC,KAAAA,GAAUJ,OAAQF,CAAAA,OAAAA,EAASC,OAASK,EAAAA,KAAAA,CAAAA,CAAAA,CAAAA;AACrE,CAAA,CACA;AACA;AACCP,CAAAA,SAAS,CACR,CAACN,KAA2BG,GAAAA,WAAAA,CAASH,UAAUA,KAAMc,CAAAA,QAAQ,CAAC,GAAA,CAAA,EAC9D,CAACP,OAASC,EAAAA,OAAAA,EAASJ,MAAQ,EAAA,EAAEK,OAAO,EAAE,GAAA;AACpC,IAAA,OAAOC,OAAQC,CAAAA,GAAG,CAACP,MAAAA,CAAOW,KAAK,CAAC,GAAKH,CAAAA,CAAAA,GAAG,CAAC,CAACC,KAAUJ,GAAAA,OAAAA,CAAQF,SAASC,OAASK,EAAAA,KAAAA,CAAAA,CAAAA,CAAAA;AAChF,CAAA,CAEF;CACCP,SAAS,CAAC,CAACN,KAA2BgB,GAAAA,KAAAA,CAAG,KAAKhB,KAAQiB,CAAAA,EAAAA,WAAAA,CAAS,KAChE;AACA;AACA;CACCC,KAAK,CAACf,WAAU,EAAA,KAAO;QACtBgB,SAAWC,EAAAA,OAAAA;QAEXC,MAAOC,CAAAA,CAAAA,GAAG,EAAEC,IAAI,EAAA;YACd,OAAOA,IAAAA,KAASD,MAAME,SAAYD,GAAAA,IAAAA;AACpC,SAAA;AAEAE,QAAAA,GAAAA,CAAAA,CAAIC,IAAI,EAAEC,MAAM,EAAEJ,IAAI,EAAA;YACpB,OAAOA,IAAAA;AACT,SAAA;AAEAK,QAAAA,IAAAA,CAAAA,CAAKL,IAAI,EAAA;YACP,OAAO;AAACA,gBAAAA;AAAK,aAAA;AACf,SAAA;QAEAM,GAAIP,CAAAA,CAAAA,GAAG,EAAEC,IAAI,EAAA;YACX,OAAOD,GAAAA,KAAQC,OAAOA,IAAOC,GAAAA,SAAAA;AAC/B;KACF,CAAA,CAAA;AAEF,0BAAeM,QAAAA,CAAM1B,MAAO2B,CAAAA,QAAQ,CAAE;;;;"}

View File

@@ -0,0 +1,39 @@
import { isString, eq, constant, trim, curry, isArray } from 'lodash/fp';
import traverseFactory from './factory.mjs';
const isStringArray = (value)=>{
return isArray(value) && value.every(isString);
};
const fields = traverseFactory()// Intercept array of strings
// e.g. fields=['title', 'description']
.intercept(isStringArray, async (visitor, options, fields, { recurse })=>{
return Promise.all(fields.map((field)=>recurse(visitor, options, field)));
})// Intercept comma separated fields (as string)
// e.g. fields='title,description'
.intercept((value)=>isString(value) && value.includes(','), (visitor, options, fields, { recurse })=>{
return Promise.all(fields.split(',').map((field)=>recurse(visitor, options, field)));
})// Return wildcards as is
.intercept((value)=>eq('*', value), constant('*'))// Parse string values
// Since we're parsing strings only, each value should be an attribute name (and it's value, undefined),
// thus it shouldn't be possible to set a new value, and get should return the whole data if key === data
.parse(isString, ()=>({
transform: trim,
remove (key, data) {
return data === key ? undefined : data;
},
set (_key, _value, data) {
return data;
},
keys (data) {
return [
data
];
},
get (key, data) {
return key === data ? data : undefined;
}
}));
var traverseQueryFields = curry(fields.traverse);
export { traverseQueryFields as default };
//# sourceMappingURL=query-fields.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"query-fields.mjs","sources":["../../src/traverse/query-fields.ts"],"sourcesContent":["import { curry, isArray, isString, eq, trim, constant } from 'lodash/fp';\n\nimport traverseFactory from './factory';\n\nconst isStringArray = (value: unknown): value is string[] => {\n return isArray(value) && value.every(isString);\n};\n\nconst fields = traverseFactory()\n // Intercept array of strings\n // e.g. fields=['title', 'description']\n .intercept(isStringArray, async (visitor, options, fields, { recurse }) => {\n return Promise.all(fields.map((field) => recurse(visitor, options, field)));\n })\n // Intercept comma separated fields (as string)\n // e.g. fields='title,description'\n .intercept(\n (value): value is string => isString(value) && value.includes(','),\n (visitor, options, fields, { recurse }) => {\n return Promise.all(fields.split(',').map((field) => recurse(visitor, options, field)));\n }\n )\n // Return wildcards as is\n .intercept((value): value is string => eq('*', value), constant('*'))\n // Parse string values\n // Since we're parsing strings only, each value should be an attribute name (and it's value, undefined),\n // thus it shouldn't be possible to set a new value, and get should return the whole data if key === data\n .parse(isString, () => ({\n transform: trim,\n\n remove(key, data) {\n return data === key ? undefined : data;\n },\n\n set(_key, _value, data) {\n return data;\n },\n\n keys(data) {\n return [data];\n },\n\n get(key, data) {\n return key === data ? data : undefined;\n },\n }));\n\nexport default curry(fields.traverse);\n"],"names":["isStringArray","value","isArray","every","isString","fields","traverseFactory","intercept","visitor","options","recurse","Promise","all","map","field","includes","split","eq","constant","parse","transform","trim","remove","key","data","undefined","set","_key","_value","keys","get","curry","traverse"],"mappings":";;;AAIA,MAAMA,gBAAgB,CAACC,KAAAA,GAAAA;AACrB,IAAA,OAAOC,OAAQD,CAAAA,KAAAA,CAAAA,IAAUA,KAAME,CAAAA,KAAK,CAACC,QAAAA,CAAAA;AACvC,CAAA;AAEA,MAAMC,MAAAA,GAASC,iBACb;AACA;CACCC,SAAS,CAACP,eAAe,OAAOQ,OAAAA,EAASC,SAASJ,MAAQ,EAAA,EAAEK,OAAO,EAAE,GAAA;IACpE,OAAOC,OAAAA,CAAQC,GAAG,CAACP,MAAOQ,CAAAA,GAAG,CAAC,CAACC,KAAAA,GAAUJ,OAAQF,CAAAA,OAAAA,EAASC,OAASK,EAAAA,KAAAA,CAAAA,CAAAA,CAAAA;AACrE,CAAA,CACA;AACA;AACCP,CAAAA,SAAS,CACR,CAACN,KAA2BG,GAAAA,QAAAA,CAASH,UAAUA,KAAMc,CAAAA,QAAQ,CAAC,GAAA,CAAA,EAC9D,CAACP,OAASC,EAAAA,OAAAA,EAASJ,MAAQ,EAAA,EAAEK,OAAO,EAAE,GAAA;AACpC,IAAA,OAAOC,OAAQC,CAAAA,GAAG,CAACP,MAAAA,CAAOW,KAAK,CAAC,GAAKH,CAAAA,CAAAA,GAAG,CAAC,CAACC,KAAUJ,GAAAA,OAAAA,CAAQF,SAASC,OAASK,EAAAA,KAAAA,CAAAA,CAAAA,CAAAA;AAChF,CAAA,CAEF;CACCP,SAAS,CAAC,CAACN,KAA2BgB,GAAAA,EAAAA,CAAG,KAAKhB,KAAQiB,CAAAA,EAAAA,QAAAA,CAAS,KAChE;AACA;AACA;CACCC,KAAK,CAACf,QAAU,EAAA,KAAO;QACtBgB,SAAWC,EAAAA,IAAAA;QAEXC,MAAOC,CAAAA,CAAAA,GAAG,EAAEC,IAAI,EAAA;YACd,OAAOA,IAAAA,KAASD,MAAME,SAAYD,GAAAA,IAAAA;AACpC,SAAA;AAEAE,QAAAA,GAAAA,CAAAA,CAAIC,IAAI,EAAEC,MAAM,EAAEJ,IAAI,EAAA;YACpB,OAAOA,IAAAA;AACT,SAAA;AAEAK,QAAAA,IAAAA,CAAAA,CAAKL,IAAI,EAAA;YACP,OAAO;AAACA,gBAAAA;AAAK,aAAA;AACf,SAAA;QAEAM,GAAIP,CAAAA,CAAAA,GAAG,EAAEC,IAAI,EAAA;YACX,OAAOD,GAAAA,KAAQC,OAAOA,IAAOC,GAAAA,SAAAA;AAC/B;KACF,CAAA,CAAA;AAEF,0BAAeM,KAAAA,CAAM1B,MAAO2B,CAAAA,QAAQ,CAAE;;;;"}

View File

@@ -0,0 +1,4 @@
/// <reference types="lodash" />
declare const _default: import("lodash").CurriedFunction3<import("./factory").Visitor, import("./factory").TraverseOptions, unknown, Promise<unknown>>;
export default _default;
//# sourceMappingURL=query-filters.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"query-filters.d.ts","sourceRoot":"","sources":["../../src/traverse/query-filters.ts"],"names":[],"mappings":";;AAoHA,wBAAuC"}

View File

@@ -0,0 +1,114 @@
'use strict';
var fp = require('lodash/fp');
var factory = require('./factory.js');
const isObj = (value)=>fp.isObject(value);
const filters = factory().intercept(// Intercept filters arrays and apply the traversal to each one individually
fp.isArray, async (visitor, options, filters, { recurse })=>{
return Promise.all(filters.map((filter, i)=>{
// In filters, only operators such as $and, $in, $notIn or $or and implicit operators like [...]
// can have a value array, thus we can update the raw path but not the attribute one
const newPath = options.path ? {
...options.path,
raw: `${options.path.raw}[${i}]`
} : options.path;
return recurse(visitor, {
...options,
path: newPath
}, filter);
})).then((res)=>res.filter((val)=>!(fp.isObject(val) && fp.isEmpty(val))));
}).intercept(// Ignore non object filters and return the value as-is
(filters)=>!fp.isObject(filters), (_, __, filters)=>{
return filters;
})// Parse object values
.parse(isObj, ()=>({
transform: fp.cloneDeep,
remove (key, data) {
return fp.omit(key, data);
},
set (key, value, data) {
return {
...data,
[key]: value
};
},
keys (data) {
return Object.keys(data);
},
get (key, data) {
return data[key];
}
}))// Ignore null or undefined values
.ignore(({ value })=>fp.isNil(value))// Recursion on operators (non attributes)
.on(({ attribute })=>fp.isNil(attribute), async ({ key, visitor, path, value, schema, getModel, attribute }, { set, recurse })=>{
const parent = {
key,
path,
schema,
attribute
};
set(key, await recurse(visitor, {
schema,
path,
getModel,
parent
}, value));
})// Handle relation recursion
.onRelation(async ({ key, attribute, visitor, path, value, schema, getModel }, { set, recurse })=>{
const isMorphRelation = attribute.relation.toLowerCase().startsWith('morph');
if (isMorphRelation) {
return;
}
const parent = {
key,
path,
schema,
attribute
};
const targetSchemaUID = attribute.target;
const targetSchema = getModel(targetSchemaUID);
const newValue = await recurse(visitor, {
schema: targetSchema,
path,
getModel,
parent
}, value);
set(key, newValue);
}).onComponent(async ({ key, attribute, visitor, path, schema, value, getModel }, { set, recurse })=>{
const parent = {
key,
path,
schema,
attribute
};
const targetSchema = getModel(attribute.component);
const newValue = await recurse(visitor, {
schema: targetSchema,
path,
getModel,
parent
}, value);
set(key, newValue);
})// Handle media recursion
.onMedia(async ({ key, visitor, path, schema, attribute, value, getModel }, { set, recurse })=>{
const parent = {
key,
path,
schema,
attribute
};
const targetSchemaUID = 'plugin::upload.file';
const targetSchema = getModel(targetSchemaUID);
const newValue = await recurse(visitor, {
schema: targetSchema,
path,
getModel,
parent
}, value);
set(key, newValue);
});
var traverseQueryFilters = fp.curry(filters.traverse);
module.exports = traverseQueryFilters;
//# sourceMappingURL=query-filters.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,112 @@
import { isArray, isObject, isEmpty, cloneDeep, omit, isNil, curry } from 'lodash/fp';
import traverseFactory from './factory.mjs';
const isObj = (value)=>isObject(value);
const filters = traverseFactory().intercept(// Intercept filters arrays and apply the traversal to each one individually
isArray, async (visitor, options, filters, { recurse })=>{
return Promise.all(filters.map((filter, i)=>{
// In filters, only operators such as $and, $in, $notIn or $or and implicit operators like [...]
// can have a value array, thus we can update the raw path but not the attribute one
const newPath = options.path ? {
...options.path,
raw: `${options.path.raw}[${i}]`
} : options.path;
return recurse(visitor, {
...options,
path: newPath
}, filter);
})).then((res)=>res.filter((val)=>!(isObject(val) && isEmpty(val))));
}).intercept(// Ignore non object filters and return the value as-is
(filters)=>!isObject(filters), (_, __, filters)=>{
return filters;
})// Parse object values
.parse(isObj, ()=>({
transform: cloneDeep,
remove (key, data) {
return omit(key, data);
},
set (key, value, data) {
return {
...data,
[key]: value
};
},
keys (data) {
return Object.keys(data);
},
get (key, data) {
return data[key];
}
}))// Ignore null or undefined values
.ignore(({ value })=>isNil(value))// Recursion on operators (non attributes)
.on(({ attribute })=>isNil(attribute), async ({ key, visitor, path, value, schema, getModel, attribute }, { set, recurse })=>{
const parent = {
key,
path,
schema,
attribute
};
set(key, await recurse(visitor, {
schema,
path,
getModel,
parent
}, value));
})// Handle relation recursion
.onRelation(async ({ key, attribute, visitor, path, value, schema, getModel }, { set, recurse })=>{
const isMorphRelation = attribute.relation.toLowerCase().startsWith('morph');
if (isMorphRelation) {
return;
}
const parent = {
key,
path,
schema,
attribute
};
const targetSchemaUID = attribute.target;
const targetSchema = getModel(targetSchemaUID);
const newValue = await recurse(visitor, {
schema: targetSchema,
path,
getModel,
parent
}, value);
set(key, newValue);
}).onComponent(async ({ key, attribute, visitor, path, schema, value, getModel }, { set, recurse })=>{
const parent = {
key,
path,
schema,
attribute
};
const targetSchema = getModel(attribute.component);
const newValue = await recurse(visitor, {
schema: targetSchema,
path,
getModel,
parent
}, value);
set(key, newValue);
})// Handle media recursion
.onMedia(async ({ key, visitor, path, schema, attribute, value, getModel }, { set, recurse })=>{
const parent = {
key,
path,
schema,
attribute
};
const targetSchemaUID = 'plugin::upload.file';
const targetSchema = getModel(targetSchemaUID);
const newValue = await recurse(visitor, {
schema: targetSchema,
path,
getModel,
parent
}, value);
set(key, newValue);
});
var traverseQueryFilters = curry(filters.traverse);
export { traverseQueryFilters as default };
//# sourceMappingURL=query-filters.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,4 @@
/// <reference types="lodash" />
declare const _default: import("lodash").CurriedFunction3<import("./factory").Visitor, import("./factory").TraverseOptions, unknown, Promise<unknown>>;
export default _default;
//# sourceMappingURL=query-populate.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"query-populate.d.ts","sourceRoot":"","sources":["../../src/traverse/query-populate.ts"],"names":[],"mappings":";;AA0RA,wBAAwC"}

View File

@@ -0,0 +1,280 @@
'use strict';
var fp = require('lodash/fp');
var factory = require('./factory.js');
var contentTypes = require('../content-types.js');
const isKeyword = (keyword)=>{
return ({ key, attribute })=>{
return !attribute && keyword === key;
};
};
const isWildcard = (value)=>value === '*';
const isPopulateString = (value)=>{
return fp.isString(value) && !isWildcard(value);
};
const isStringArray = (value)=>fp.isArray(value) && value.every(fp.isString);
const isObj = (value)=>fp.isObject(value);
const populate = factory().intercept(isPopulateString, async (visitor, options, populate, { recurse })=>{
/**
* Ensure the populate clause its in the extended format ( { populate: { ... } }, and not just a string)
* This gives a consistent structure to track the "parent" node of each nested populate clause
*/ const populateObject = pathsToObjectPopulate([
populate
]);
const traversedPopulate = await recurse(visitor, options, populateObject);
const [result] = objectPopulateToPaths(traversedPopulate);
return result;
})// Array of strings ['foo', 'bar.baz'] => map(recurse), then filter out empty items
.intercept(isStringArray, async (visitor, options, populate, { recurse })=>{
const paths = await Promise.all(populate.map((subClause)=>recurse(visitor, options, subClause)));
return paths.filter((item)=>!fp.isNil(item));
})// for wildcard, generate custom utilities to modify the values
.parse(isWildcard, ()=>({
/**
* Since value is '*', we don't need to transform it
*/ transform: fp.identity,
/**
* '*' isn't a key/value structure, so regardless
* of the given key, it returns the data ('*')
*/ get: (_key, data)=>data,
/**
* '*' isn't a key/value structure, so regardless
* of the given `key`, use `value` as the new `data`
*/ set: (_key, value)=>value,
/**
* '*' isn't a key/value structure, but we need to simulate at least one to enable
* the data traversal. We're using '' since it represents a falsy string value
*/ keys: fp.constant([
''
]),
/**
* Removing '*' means setting it to undefined, regardless of the given key
*/ remove: fp.constant(undefined)
}))// Parse string values
.parse(fp.isString, ()=>{
const tokenize = fp.split('.');
const recompose = fp.join('.');
return {
transform: fp.trim,
remove (key, data) {
const [root] = tokenize(data);
return root === key ? undefined : data;
},
set (key, value, data) {
const [root] = tokenize(data);
if (root !== key) {
return data;
}
return fp.isNil(value) || fp.isEmpty(value) ? root : `${root}.${value}`;
},
keys (data) {
const v = fp.first(tokenize(data));
return v ? [
v
] : [];
},
get (key, data) {
const [root, ...rest] = tokenize(data);
return key === root ? recompose(rest) : undefined;
}
};
})// Parse object values
.parse(isObj, ()=>({
transform: fp.cloneDeep,
remove (key, data) {
// eslint-disable-next-line no-unused-vars
const { [key]: ignored, ...rest } = data;
return rest;
},
set (key, value, data) {
return {
...data,
[key]: value
};
},
keys (data) {
return Object.keys(data);
},
get (key, data) {
return data[key];
}
})).ignore(({ key, attribute })=>{
// we don't want to recurse using traversePopulate and instead let
// the visitors recurse with the appropriate traversal (sort, filters, etc...)
return [
'sort',
'filters',
'fields'
].includes(key) && !attribute;
}).on(// Handle recursion on populate."populate"
isKeyword('populate'), async ({ key, visitor, path, value, schema, getModel, attribute }, { set, recurse })=>{
const parent = {
key,
path,
schema,
attribute
};
const newValue = await recurse(visitor, {
schema,
path,
getModel,
parent
}, value);
set(key, newValue);
}).on(isKeyword('on'), async ({ key, visitor, path, value, getModel, parent }, { set, recurse })=>{
const newOn = {};
if (!isObj(value)) {
return;
}
for (const [uid, subPopulate] of Object.entries(value)){
const model = getModel(uid);
const newPath = {
...path,
raw: `${path.raw}[${uid}]`
};
newOn[uid] = await recurse(visitor, {
schema: model,
path: newPath,
getModel,
parent
}, subPopulate);
}
set(key, newOn);
})// Handle populate on relation
.onRelation(async ({ key, value, attribute, visitor, path, schema, getModel }, { set, recurse })=>{
if (fp.isNil(value)) {
return;
}
const parent = {
key,
path,
schema,
attribute
};
if (contentTypes.isMorphToRelationalAttribute(attribute)) {
// Don't traverse values that cannot be parsed
if (!fp.isObject(value) || !('on' in value && fp.isObject(value?.on))) {
return;
}
// If there is a populate fragment defined, traverse it
const newValue = await recurse(visitor, {
schema,
path,
getModel,
parent
}, {
on: value?.on
});
set(key, newValue);
return;
}
const targetSchemaUID = attribute.target;
const targetSchema = getModel(targetSchemaUID);
const newValue = await recurse(visitor, {
schema: targetSchema,
path,
getModel,
parent
}, value);
set(key, newValue);
})// Handle populate on media
.onMedia(async ({ key, path, schema, attribute, visitor, value, getModel }, { recurse, set })=>{
if (fp.isNil(value)) {
return;
}
const parent = {
key,
path,
schema,
attribute
};
const targetSchemaUID = 'plugin::upload.file';
const targetSchema = getModel(targetSchemaUID);
const newValue = await recurse(visitor, {
schema: targetSchema,
path,
getModel,
parent
}, value);
set(key, newValue);
})// Handle populate on components
.onComponent(async ({ key, value, schema, visitor, path, attribute, getModel }, { recurse, set })=>{
if (fp.isNil(value)) {
return;
}
const parent = {
key,
path,
schema,
attribute
};
const targetSchema = getModel(attribute.component);
const newValue = await recurse(visitor, {
schema: targetSchema,
path,
getModel,
parent
}, value);
set(key, newValue);
})// Handle populate on dynamic zones
.onDynamicZone(async ({ key, value, schema, visitor, path, attribute, getModel }, { set, recurse })=>{
if (fp.isNil(value) || !fp.isObject(value)) {
return;
}
const parent = {
key,
path,
schema,
attribute
};
// Handle fragment syntax
if ('on' in value && value.on) {
const newOn = await recurse(visitor, {
schema,
path,
getModel,
parent
}, {
on: value.on
});
set(key, newOn);
}
});
var traverseQueryPopulate = fp.curry(populate.traverse);
const objectPopulateToPaths = (input)=>{
const paths = [];
function traverse(currentObj, parentPath) {
for (const [key, value] of Object.entries(currentObj)){
const currentPath = parentPath ? `${parentPath}.${key}` : key;
if (value === true) {
paths.push(currentPath);
} else {
traverse(value.populate, currentPath);
}
}
}
traverse(input, '');
return paths;
};
const pathsToObjectPopulate = (input)=>{
const result = {};
function traverse(object, keys) {
const [first, ...rest] = keys;
if (rest.length === 0) {
object[first] = true;
} else {
if (!object[first] || typeof object[first] === 'boolean') {
object[first] = {
populate: {}
};
}
traverse(object[first].populate, rest);
}
}
input.forEach((clause)=>traverse(result, clause.split('.')));
return result;
};
module.exports = traverseQueryPopulate;
//# sourceMappingURL=query-populate.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,278 @@
import { isNil, identity, constant, isString, split, join, trim, isEmpty, first, cloneDeep, isObject, curry, isArray } from 'lodash/fp';
import traverseFactory from './factory.mjs';
import { isMorphToRelationalAttribute } from '../content-types.mjs';
const isKeyword = (keyword)=>{
return ({ key, attribute })=>{
return !attribute && keyword === key;
};
};
const isWildcard = (value)=>value === '*';
const isPopulateString = (value)=>{
return isString(value) && !isWildcard(value);
};
const isStringArray = (value)=>isArray(value) && value.every(isString);
const isObj = (value)=>isObject(value);
const populate = traverseFactory().intercept(isPopulateString, async (visitor, options, populate, { recurse })=>{
/**
* Ensure the populate clause its in the extended format ( { populate: { ... } }, and not just a string)
* This gives a consistent structure to track the "parent" node of each nested populate clause
*/ const populateObject = pathsToObjectPopulate([
populate
]);
const traversedPopulate = await recurse(visitor, options, populateObject);
const [result] = objectPopulateToPaths(traversedPopulate);
return result;
})// Array of strings ['foo', 'bar.baz'] => map(recurse), then filter out empty items
.intercept(isStringArray, async (visitor, options, populate, { recurse })=>{
const paths = await Promise.all(populate.map((subClause)=>recurse(visitor, options, subClause)));
return paths.filter((item)=>!isNil(item));
})// for wildcard, generate custom utilities to modify the values
.parse(isWildcard, ()=>({
/**
* Since value is '*', we don't need to transform it
*/ transform: identity,
/**
* '*' isn't a key/value structure, so regardless
* of the given key, it returns the data ('*')
*/ get: (_key, data)=>data,
/**
* '*' isn't a key/value structure, so regardless
* of the given `key`, use `value` as the new `data`
*/ set: (_key, value)=>value,
/**
* '*' isn't a key/value structure, but we need to simulate at least one to enable
* the data traversal. We're using '' since it represents a falsy string value
*/ keys: constant([
''
]),
/**
* Removing '*' means setting it to undefined, regardless of the given key
*/ remove: constant(undefined)
}))// Parse string values
.parse(isString, ()=>{
const tokenize = split('.');
const recompose = join('.');
return {
transform: trim,
remove (key, data) {
const [root] = tokenize(data);
return root === key ? undefined : data;
},
set (key, value, data) {
const [root] = tokenize(data);
if (root !== key) {
return data;
}
return isNil(value) || isEmpty(value) ? root : `${root}.${value}`;
},
keys (data) {
const v = first(tokenize(data));
return v ? [
v
] : [];
},
get (key, data) {
const [root, ...rest] = tokenize(data);
return key === root ? recompose(rest) : undefined;
}
};
})// Parse object values
.parse(isObj, ()=>({
transform: cloneDeep,
remove (key, data) {
// eslint-disable-next-line no-unused-vars
const { [key]: ignored, ...rest } = data;
return rest;
},
set (key, value, data) {
return {
...data,
[key]: value
};
},
keys (data) {
return Object.keys(data);
},
get (key, data) {
return data[key];
}
})).ignore(({ key, attribute })=>{
// we don't want to recurse using traversePopulate and instead let
// the visitors recurse with the appropriate traversal (sort, filters, etc...)
return [
'sort',
'filters',
'fields'
].includes(key) && !attribute;
}).on(// Handle recursion on populate."populate"
isKeyword('populate'), async ({ key, visitor, path, value, schema, getModel, attribute }, { set, recurse })=>{
const parent = {
key,
path,
schema,
attribute
};
const newValue = await recurse(visitor, {
schema,
path,
getModel,
parent
}, value);
set(key, newValue);
}).on(isKeyword('on'), async ({ key, visitor, path, value, getModel, parent }, { set, recurse })=>{
const newOn = {};
if (!isObj(value)) {
return;
}
for (const [uid, subPopulate] of Object.entries(value)){
const model = getModel(uid);
const newPath = {
...path,
raw: `${path.raw}[${uid}]`
};
newOn[uid] = await recurse(visitor, {
schema: model,
path: newPath,
getModel,
parent
}, subPopulate);
}
set(key, newOn);
})// Handle populate on relation
.onRelation(async ({ key, value, attribute, visitor, path, schema, getModel }, { set, recurse })=>{
if (isNil(value)) {
return;
}
const parent = {
key,
path,
schema,
attribute
};
if (isMorphToRelationalAttribute(attribute)) {
// Don't traverse values that cannot be parsed
if (!isObject(value) || !('on' in value && isObject(value?.on))) {
return;
}
// If there is a populate fragment defined, traverse it
const newValue = await recurse(visitor, {
schema,
path,
getModel,
parent
}, {
on: value?.on
});
set(key, newValue);
return;
}
const targetSchemaUID = attribute.target;
const targetSchema = getModel(targetSchemaUID);
const newValue = await recurse(visitor, {
schema: targetSchema,
path,
getModel,
parent
}, value);
set(key, newValue);
})// Handle populate on media
.onMedia(async ({ key, path, schema, attribute, visitor, value, getModel }, { recurse, set })=>{
if (isNil(value)) {
return;
}
const parent = {
key,
path,
schema,
attribute
};
const targetSchemaUID = 'plugin::upload.file';
const targetSchema = getModel(targetSchemaUID);
const newValue = await recurse(visitor, {
schema: targetSchema,
path,
getModel,
parent
}, value);
set(key, newValue);
})// Handle populate on components
.onComponent(async ({ key, value, schema, visitor, path, attribute, getModel }, { recurse, set })=>{
if (isNil(value)) {
return;
}
const parent = {
key,
path,
schema,
attribute
};
const targetSchema = getModel(attribute.component);
const newValue = await recurse(visitor, {
schema: targetSchema,
path,
getModel,
parent
}, value);
set(key, newValue);
})// Handle populate on dynamic zones
.onDynamicZone(async ({ key, value, schema, visitor, path, attribute, getModel }, { set, recurse })=>{
if (isNil(value) || !isObject(value)) {
return;
}
const parent = {
key,
path,
schema,
attribute
};
// Handle fragment syntax
if ('on' in value && value.on) {
const newOn = await recurse(visitor, {
schema,
path,
getModel,
parent
}, {
on: value.on
});
set(key, newOn);
}
});
var traverseQueryPopulate = curry(populate.traverse);
const objectPopulateToPaths = (input)=>{
const paths = [];
function traverse(currentObj, parentPath) {
for (const [key, value] of Object.entries(currentObj)){
const currentPath = parentPath ? `${parentPath}.${key}` : key;
if (value === true) {
paths.push(currentPath);
} else {
traverse(value.populate, currentPath);
}
}
}
traverse(input, '');
return paths;
};
const pathsToObjectPopulate = (input)=>{
const result = {};
function traverse(object, keys) {
const [first, ...rest] = keys;
if (rest.length === 0) {
object[first] = true;
} else {
if (!object[first] || typeof object[first] === 'boolean') {
object[first] = {
populate: {}
};
}
traverse(object[first].populate, rest);
}
}
input.forEach((clause)=>traverse(result, clause.split('.')));
return result;
};
export { traverseQueryPopulate as default };
//# sourceMappingURL=query-populate.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,4 @@
/// <reference types="lodash" />
declare const _default: import("lodash").CurriedFunction3<import("./factory").Visitor, import("./factory").TraverseOptions, unknown, Promise<unknown>>;
export default _default;
//# sourceMappingURL=query-sort.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"query-sort.d.ts","sourceRoot":"","sources":["../../src/traverse/query-sort.ts"],"names":[],"mappings":";;AA+LA,wBAAoC"}

View File

@@ -0,0 +1,144 @@
'use strict';
var fp = require('lodash/fp');
var factory = require('./factory.js');
const ORDERS = {
asc: 'asc',
desc: 'desc'
};
const ORDER_VALUES = Object.values(ORDERS);
const isSortOrder = (value)=>ORDER_VALUES.includes(value.toLowerCase());
const isStringArray = (value)=>Array.isArray(value) && value.every(fp.isString);
const isObjectArray = (value)=>Array.isArray(value) && value.every(fp.isObject);
const isNestedSorts = (value)=>fp.isString(value) && value.split(',').length > 1;
const isObj = (value)=>fp.isObject(value);
const sort = factory().intercept(// String with chained sorts (foo,bar,foobar) => split, map(recurse), then recompose
isNestedSorts, async (visitor, options, sort, { recurse })=>{
return Promise.all(sort.split(',').map(fp.trim).map((nestedSort)=>recurse(visitor, options, nestedSort))).then((res)=>res.filter((part)=>!fp.isEmpty(part)).join(','));
}).intercept(// Array of strings ['foo', 'foo,bar'] => map(recurse), then filter out empty items
isStringArray, async (visitor, options, sort, { recurse })=>{
return Promise.all(sort.map((nestedSort)=>recurse(visitor, options, nestedSort))).then((res)=>res.filter((nestedSort)=>!fp.isEmpty(nestedSort)));
}).intercept(// Array of objects [{ foo: 'asc' }, { bar: 'desc', baz: 'asc' }] => map(recurse), then filter out empty items
isObjectArray, async (visitor, options, sort, { recurse })=>{
return Promise.all(sort.map((nestedSort)=>recurse(visitor, options, nestedSort))).then((res)=>res.filter((nestedSort)=>!fp.isEmpty(nestedSort)));
})// Parse string values
.parse(fp.isString, ()=>{
const tokenize = fp.pipe(fp.split('.'), fp.map(fp.split(':')), fp.flatten);
const recompose = (parts)=>{
if (parts.length === 0) {
return undefined;
}
return parts.reduce((acc, part)=>{
if (fp.isEmpty(part)) {
return acc;
}
if (acc === '') {
return part;
}
return isSortOrder(part) ? `${acc}:${part}` : `${acc}.${part}`;
}, '');
};
return {
transform: fp.trim,
remove (key, data) {
const [root] = tokenize(data);
return root === key ? undefined : data;
},
set (key, value, data) {
const [root] = tokenize(data);
if (root !== key) {
return data;
}
return fp.isNil(value) ? root : `${root}.${value}`;
},
keys (data) {
const v = fp.first(tokenize(data));
return v ? [
v
] : [];
},
get (key, data) {
const [root, ...rest] = tokenize(data);
return key === root ? recompose(rest) : undefined;
}
};
})// Parse object values
.parse(isObj, ()=>({
transform: fp.cloneDeep,
remove (key, data) {
// eslint-disable-next-line no-unused-vars
const { [key]: ignored, ...rest } = data;
return rest;
},
set (key, value, data) {
return {
...data,
[key]: value
};
},
keys (data) {
return Object.keys(data);
},
get (key, data) {
return data[key];
}
}))// Handle deep sort on relation
.onRelation(async ({ key, value, attribute, visitor, path, getModel, schema }, { set, recurse })=>{
const isMorphRelation = attribute.relation.toLowerCase().startsWith('morph');
if (isMorphRelation) {
return;
}
const parent = {
key,
path,
schema,
attribute
};
const targetSchemaUID = attribute.target;
const targetSchema = getModel(targetSchemaUID);
const newValue = await recurse(visitor, {
schema: targetSchema,
path,
getModel,
parent
}, value);
set(key, newValue);
})// Handle deep sort on media
.onMedia(async ({ key, path, schema, attribute, visitor, value, getModel }, { recurse, set })=>{
const parent = {
key,
path,
schema,
attribute
};
const targetSchemaUID = 'plugin::upload.file';
const targetSchema = getModel(targetSchemaUID);
const newValue = await recurse(visitor, {
schema: targetSchema,
path,
getModel,
parent
}, value);
set(key, newValue);
})// Handle deep sort on components
.onComponent(async ({ key, value, visitor, path, schema, attribute, getModel }, { recurse, set })=>{
const parent = {
key,
path,
schema,
attribute
};
const targetSchema = getModel(attribute.component);
const newValue = await recurse(visitor, {
schema: targetSchema,
path,
getModel,
parent
}, value);
set(key, newValue);
});
var traverseQuerySort = fp.curry(sort.traverse);
module.exports = traverseQuerySort;
//# sourceMappingURL=query-sort.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,142 @@
import { trim, isEmpty, isString, pipe, split, map, flatten, isNil, first, cloneDeep, curry, isObject } from 'lodash/fp';
import traverseFactory from './factory.mjs';
const ORDERS = {
asc: 'asc',
desc: 'desc'
};
const ORDER_VALUES = Object.values(ORDERS);
const isSortOrder = (value)=>ORDER_VALUES.includes(value.toLowerCase());
const isStringArray = (value)=>Array.isArray(value) && value.every(isString);
const isObjectArray = (value)=>Array.isArray(value) && value.every(isObject);
const isNestedSorts = (value)=>isString(value) && value.split(',').length > 1;
const isObj = (value)=>isObject(value);
const sort = traverseFactory().intercept(// String with chained sorts (foo,bar,foobar) => split, map(recurse), then recompose
isNestedSorts, async (visitor, options, sort, { recurse })=>{
return Promise.all(sort.split(',').map(trim).map((nestedSort)=>recurse(visitor, options, nestedSort))).then((res)=>res.filter((part)=>!isEmpty(part)).join(','));
}).intercept(// Array of strings ['foo', 'foo,bar'] => map(recurse), then filter out empty items
isStringArray, async (visitor, options, sort, { recurse })=>{
return Promise.all(sort.map((nestedSort)=>recurse(visitor, options, nestedSort))).then((res)=>res.filter((nestedSort)=>!isEmpty(nestedSort)));
}).intercept(// Array of objects [{ foo: 'asc' }, { bar: 'desc', baz: 'asc' }] => map(recurse), then filter out empty items
isObjectArray, async (visitor, options, sort, { recurse })=>{
return Promise.all(sort.map((nestedSort)=>recurse(visitor, options, nestedSort))).then((res)=>res.filter((nestedSort)=>!isEmpty(nestedSort)));
})// Parse string values
.parse(isString, ()=>{
const tokenize = pipe(split('.'), map(split(':')), flatten);
const recompose = (parts)=>{
if (parts.length === 0) {
return undefined;
}
return parts.reduce((acc, part)=>{
if (isEmpty(part)) {
return acc;
}
if (acc === '') {
return part;
}
return isSortOrder(part) ? `${acc}:${part}` : `${acc}.${part}`;
}, '');
};
return {
transform: trim,
remove (key, data) {
const [root] = tokenize(data);
return root === key ? undefined : data;
},
set (key, value, data) {
const [root] = tokenize(data);
if (root !== key) {
return data;
}
return isNil(value) ? root : `${root}.${value}`;
},
keys (data) {
const v = first(tokenize(data));
return v ? [
v
] : [];
},
get (key, data) {
const [root, ...rest] = tokenize(data);
return key === root ? recompose(rest) : undefined;
}
};
})// Parse object values
.parse(isObj, ()=>({
transform: cloneDeep,
remove (key, data) {
// eslint-disable-next-line no-unused-vars
const { [key]: ignored, ...rest } = data;
return rest;
},
set (key, value, data) {
return {
...data,
[key]: value
};
},
keys (data) {
return Object.keys(data);
},
get (key, data) {
return data[key];
}
}))// Handle deep sort on relation
.onRelation(async ({ key, value, attribute, visitor, path, getModel, schema }, { set, recurse })=>{
const isMorphRelation = attribute.relation.toLowerCase().startsWith('morph');
if (isMorphRelation) {
return;
}
const parent = {
key,
path,
schema,
attribute
};
const targetSchemaUID = attribute.target;
const targetSchema = getModel(targetSchemaUID);
const newValue = await recurse(visitor, {
schema: targetSchema,
path,
getModel,
parent
}, value);
set(key, newValue);
})// Handle deep sort on media
.onMedia(async ({ key, path, schema, attribute, visitor, value, getModel }, { recurse, set })=>{
const parent = {
key,
path,
schema,
attribute
};
const targetSchemaUID = 'plugin::upload.file';
const targetSchema = getModel(targetSchemaUID);
const newValue = await recurse(visitor, {
schema: targetSchema,
path,
getModel,
parent
}, value);
set(key, newValue);
})// Handle deep sort on components
.onComponent(async ({ key, value, visitor, path, schema, attribute, getModel }, { recurse, set })=>{
const parent = {
key,
path,
schema,
attribute
};
const targetSchema = getModel(attribute.component);
const newValue = await recurse(visitor, {
schema: targetSchema,
path,
getModel,
parent
}, value);
set(key, newValue);
});
var traverseQuerySort = curry(sort.traverse);
export { traverseQuerySort as default };
//# sourceMappingURL=query-sort.mjs.map

File diff suppressed because one or more lines are too long