@open-mercato/shared 0.6.7-develop.6597.1.b8f069b7fe → 0.6.7-develop.6603.1.78e5b7a65d
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/lib/bootstrap/dynamicLoader.js +7 -0
- package/dist/lib/bootstrap/dynamicLoader.js.map +2 -2
- package/dist/lib/crud/factory.js +4 -3
- package/dist/lib/crud/factory.js.map +2 -2
- package/dist/lib/crud/ids.js +11 -2
- package/dist/lib/crud/ids.js.map +2 -2
- package/dist/lib/version.js +1 -1
- package/dist/lib/version.js.map +1 -1
- package/package.json +2 -2
- package/src/lib/bootstrap/__tests__/dynamicLoader.commandInterceptors.test.ts +76 -0
- package/src/lib/bootstrap/dynamicLoader.ts +8 -0
- package/src/lib/crud/__tests__/ids.test.ts +31 -1
- package/src/lib/crud/factory.ts +4 -3
- package/src/lib/crud/ids.ts +22 -1
|
@@ -94,6 +94,7 @@ async function loadBootstrapData(appRoot) {
|
|
|
94
94
|
diModule,
|
|
95
95
|
searchModule,
|
|
96
96
|
commandLoadersModule,
|
|
97
|
+
commandInterceptorsModule,
|
|
97
98
|
workflowsModule
|
|
98
99
|
] = await Promise.all([
|
|
99
100
|
compileAndImport(path.join(generatedDir, "modules.cli.generated.ts")),
|
|
@@ -101,6 +102,7 @@ async function loadBootstrapData(appRoot) {
|
|
|
101
102
|
compileAndImport(path.join(generatedDir, "di.generated.ts")),
|
|
102
103
|
compileAndImport(path.join(generatedDir, "search.generated.ts")).catch(() => ({ searchModuleConfigs: [] })),
|
|
103
104
|
compileAndImport(path.join(generatedDir, "command-loaders.generated.ts")).catch(() => ({ commandLoaderEntries: [] })),
|
|
105
|
+
compileAndImport(path.join(generatedDir, "command-interceptors.generated.ts")).catch(() => ({ commandInterceptorEntries: [] })),
|
|
104
106
|
compileAndImport(path.join(generatedDir, "workflows.generated.ts")).catch(() => ({ allCodeWorkflows: [] }))
|
|
105
107
|
]);
|
|
106
108
|
return {
|
|
@@ -111,6 +113,11 @@ async function loadBootstrapData(appRoot) {
|
|
|
111
113
|
// Search configs are needed by workers for indexing
|
|
112
114
|
searchModuleConfigs: searchModule.searchModuleConfigs ?? [],
|
|
113
115
|
commandLoaderEntries: commandLoadersModule.commandLoaderEntries ?? [],
|
|
116
|
+
// Command interceptors must apply in worker/CLI processes too — the
|
|
117
|
+
// interceptor registry is per-process, so relying on the Next.js runtime's
|
|
118
|
+
// registration silently no-ops every interceptor for queued/CLI commands
|
|
119
|
+
// (#4327).
|
|
120
|
+
commandInterceptorEntries: commandInterceptorsModule.commandInterceptorEntries ?? [],
|
|
114
121
|
// Code workflow definitions are needed by workers to resume code-defined instances
|
|
115
122
|
codeWorkflows: workflowsModule.allCodeWorkflows ?? [],
|
|
116
123
|
// Empty UI-related data - not needed for CLI
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/bootstrap/dynamicLoader.ts"],
|
|
4
|
-
"sourcesContent": ["import type { BootstrapData } from './types'\nimport { findAppRoot, type AppRoot } from './appResolver'\nimport { registerEntityIds } from '../encryption/entityIds'\nimport {\n ensureMikroOrmV7GeneratedCacheCompatibility,\n recoverMikroOrmV7GeneratedCacheFromImportError,\n} from './generatedCacheRecovery'\nimport path from 'node:path'\nimport fs from 'node:fs'\nimport { pathToFileURL } from 'node:url'\n\n/**\n * Compile a TypeScript file to JavaScript using esbuild bundler.\n * This bundles the file and all its dependencies, handling JSON imports properly.\n * The compiled file is written next to the source file with a .mjs extension.\n */\nasync function compileAndImport(tsPath: string, allowRecovery: boolean = true): Promise<Record<string, unknown>> {\n const jsPath = tsPath.replace(/\\.ts$/, '.mjs')\n const appRoot = path.dirname(path.dirname(path.dirname(tsPath)))\n\n // Check if we need to recompile (source newer than compiled)\n const tsExists = fs.existsSync(tsPath)\n const jsExists = fs.existsSync(jsPath)\n\n if (!tsExists) {\n throw new Error(`Generated file not found: ${tsPath}`)\n }\n\n const needsCompile = !jsExists ||\n fs.statSync(tsPath).mtimeMs > fs.statSync(jsPath).mtimeMs\n\n if (needsCompile) {\n // Dynamically import esbuild only when needed\n const esbuild = await import('esbuild')\n\n // Plugin to resolve @/ alias to app root (works for @app modules)\n const aliasPlugin: import('esbuild').Plugin = {\n name: 'alias-resolver',\n setup(build) {\n // Resolve @/ alias to app root\n build.onResolve({ filter: /^@\\// }, (args) => {\n const resolved = path.join(appRoot, args.path.slice(2))\n // Try with .ts extension if base path doesn't exist\n if (!fs.existsSync(resolved) && fs.existsSync(resolved + '.ts')) {\n return { path: resolved + '.ts' }\n }\n // Also check for /index.ts if it's a directory\n if (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory() && fs.existsSync(path.join(resolved, 'index.ts'))) {\n return { path: path.join(resolved, 'index.ts') }\n }\n return { path: resolved }\n })\n },\n }\n\n // Plugin to mark non-JSON package imports as external\n const externalNonJsonPlugin: import('esbuild').Plugin = {\n name: 'external-non-json',\n setup(build) {\n // Mark all package imports as external EXCEPT JSON files\n // Filter matches paths that don't start with . or / (package imports like @open-mercato/shared)\n build.onResolve({ filter: /^[^./]/ }, (args) => {\n // Skip Windows absolute paths (e.g., C:\\...) - they're local files, not packages\n if (/^[a-zA-Z]:/.test(args.path)) {\n return null // Let esbuild handle it\n }\n // If it's a JSON file, let esbuild bundle it\n if (args.path.endsWith('.json')) {\n return null // Let esbuild handle it\n }\n // Otherwise mark as external\n return { path: args.path, external: true }\n })\n },\n }\n\n // Use esbuild.build with bundling to handle JSON imports\n await esbuild.build({\n entryPoints: [tsPath],\n outfile: jsPath,\n bundle: true,\n format: 'esm',\n platform: 'node',\n target: 'node18',\n plugins: [aliasPlugin, externalNonJsonPlugin],\n // Allow JSON imports\n loader: { '.json': 'json' },\n })\n }\n\n // Import the compiled JavaScript\n try {\n const fileUrl = `${pathToFileURL(jsPath).href}?mtime=${fs.statSync(jsPath).mtimeMs}`\n return import(fileUrl)\n } catch (error) {\n if (!allowRecovery) {\n throw error\n }\n\n const recovered = recoverMikroOrmV7GeneratedCacheFromImportError(appRoot, error)\n if (!recovered.applied) {\n throw error\n }\n\n return compileAndImport(tsPath, false)\n }\n}\n\n\n/**\n * Dynamically load bootstrap data from a resolved app directory.\n *\n * IMPORTANT: This only works in unbundled contexts (CLI, tsx).\n * Do NOT use this in Next.js bundled code - use static imports instead.\n *\n * For CLI context, we skip loading modules.generated.ts which has Next.js dependencies.\n * CLI commands are discovered separately via the CLI module system.\n *\n * @param appRoot - Optional explicit app root path. If not provided, will search from cwd.\n * @returns The loaded bootstrap data\n * @throws Error if app root cannot be found or generated files are missing\n */\nexport async function loadBootstrapData(appRoot?: string): Promise<BootstrapData> {\n const resolved: AppRoot | null = appRoot\n ? {\n generatedDir: path.join(appRoot, '.mercato', 'generated'),\n appDir: appRoot,\n mercatoDir: path.join(appRoot, '.mercato'),\n }\n : findAppRoot()\n\n if (!resolved) {\n throw new Error(\n 'Could not find app root with .mercato/generated directory. ' +\n 'Make sure you run this command from within a Next.js app directory, ' +\n 'or run \"yarn mercato generate\" first to create the generated files.',\n )\n }\n\n const { generatedDir } = resolved\n\n ensureMikroOrmV7GeneratedCacheCompatibility(resolved.appDir)\n\n // IMPORTANT: Load entity IDs FIRST and register them before loading modules.\n // This is because modules (e.g., ce.ts files) use E.xxx.xxx at module scope,\n // and they need entity IDs to be available when they're imported.\n const entityIdsModule = await compileAndImport(path.join(generatedDir, 'entities.ids.generated.ts'))\n registerEntityIds(entityIdsModule.E as BootstrapData['entityIds'])\n\n // Now load the rest of the generated files.\n // modules.cli.generated.ts excludes Next.js-dependent code (routes, APIs, widgets)\n const [\n modulesModule,\n entitiesModule,\n diModule,\n searchModule,\n commandLoadersModule,\n workflowsModule,\n ] = await Promise.all([\n compileAndImport(path.join(generatedDir, 'modules.cli.generated.ts')),\n compileAndImport(path.join(generatedDir, 'entities.generated.ts')),\n compileAndImport(path.join(generatedDir, 'di.generated.ts')),\n compileAndImport(path.join(generatedDir, 'search.generated.ts')).catch(() => ({ searchModuleConfigs: [] })),\n compileAndImport(path.join(generatedDir, 'command-loaders.generated.ts')).catch(() => ({ commandLoaderEntries: [] })),\n compileAndImport(path.join(generatedDir, 'workflows.generated.ts')).catch(() => ({ allCodeWorkflows: [] })),\n ])\n\n return {\n modules: modulesModule.modules as BootstrapData['modules'],\n entities: entitiesModule.entities as BootstrapData['entities'],\n diRegistrars: diModule.diRegistrars as BootstrapData['diRegistrars'],\n entityIds: entityIdsModule.E as BootstrapData['entityIds'],\n // Search configs are needed by workers for indexing\n searchModuleConfigs: (searchModule.searchModuleConfigs ?? []) as BootstrapData['searchModuleConfigs'],\n commandLoaderEntries: (commandLoadersModule.commandLoaderEntries ?? []) as BootstrapData['commandLoaderEntries'],\n // Code workflow definitions are needed by workers to resume code-defined instances\n codeWorkflows: (workflowsModule.allCodeWorkflows ?? []) as BootstrapData['codeWorkflows'],\n // Empty UI-related data - not needed for CLI\n dashboardWidgetEntries: [],\n injectionWidgetEntries: [],\n injectionTables: [],\n interceptorEntries: [],\n componentOverrideEntries: [],\n }\n}\n\n/**\n * Create and execute bootstrap in CLI context.\n *\n * This is a convenience function that finds the app root, loads the generated\n * data dynamically, and runs bootstrap. Use this in CLI entry points.\n *\n * Returns the loaded bootstrap data so the CLI can register modules directly\n * (avoids module resolution issues when importing @open-mercato/cli/mercato).\n *\n * @param appRoot - Optional explicit app root path\n * @returns The loaded bootstrap data (modules, entities, etc.)\n */\nexport async function bootstrapFromAppRoot(appRoot?: string): Promise<BootstrapData> {\n const { createBootstrap, waitForAsyncRegistration } = await import('./factory.js')\n const data = await loadBootstrapData(appRoot)\n const bootstrap = createBootstrap(data)\n bootstrap()\n // In CLI context, wait for async registrations (UI widgets, search configs, etc.)\n await waitForAsyncRegistration()\n\n return data\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import type { BootstrapData } from './types'\nimport { findAppRoot, type AppRoot } from './appResolver'\nimport { registerEntityIds } from '../encryption/entityIds'\nimport {\n ensureMikroOrmV7GeneratedCacheCompatibility,\n recoverMikroOrmV7GeneratedCacheFromImportError,\n} from './generatedCacheRecovery'\nimport path from 'node:path'\nimport fs from 'node:fs'\nimport { pathToFileURL } from 'node:url'\n\n/**\n * Compile a TypeScript file to JavaScript using esbuild bundler.\n * This bundles the file and all its dependencies, handling JSON imports properly.\n * The compiled file is written next to the source file with a .mjs extension.\n */\nasync function compileAndImport(tsPath: string, allowRecovery: boolean = true): Promise<Record<string, unknown>> {\n const jsPath = tsPath.replace(/\\.ts$/, '.mjs')\n const appRoot = path.dirname(path.dirname(path.dirname(tsPath)))\n\n // Check if we need to recompile (source newer than compiled)\n const tsExists = fs.existsSync(tsPath)\n const jsExists = fs.existsSync(jsPath)\n\n if (!tsExists) {\n throw new Error(`Generated file not found: ${tsPath}`)\n }\n\n const needsCompile = !jsExists ||\n fs.statSync(tsPath).mtimeMs > fs.statSync(jsPath).mtimeMs\n\n if (needsCompile) {\n // Dynamically import esbuild only when needed\n const esbuild = await import('esbuild')\n\n // Plugin to resolve @/ alias to app root (works for @app modules)\n const aliasPlugin: import('esbuild').Plugin = {\n name: 'alias-resolver',\n setup(build) {\n // Resolve @/ alias to app root\n build.onResolve({ filter: /^@\\// }, (args) => {\n const resolved = path.join(appRoot, args.path.slice(2))\n // Try with .ts extension if base path doesn't exist\n if (!fs.existsSync(resolved) && fs.existsSync(resolved + '.ts')) {\n return { path: resolved + '.ts' }\n }\n // Also check for /index.ts if it's a directory\n if (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory() && fs.existsSync(path.join(resolved, 'index.ts'))) {\n return { path: path.join(resolved, 'index.ts') }\n }\n return { path: resolved }\n })\n },\n }\n\n // Plugin to mark non-JSON package imports as external\n const externalNonJsonPlugin: import('esbuild').Plugin = {\n name: 'external-non-json',\n setup(build) {\n // Mark all package imports as external EXCEPT JSON files\n // Filter matches paths that don't start with . or / (package imports like @open-mercato/shared)\n build.onResolve({ filter: /^[^./]/ }, (args) => {\n // Skip Windows absolute paths (e.g., C:\\...) - they're local files, not packages\n if (/^[a-zA-Z]:/.test(args.path)) {\n return null // Let esbuild handle it\n }\n // If it's a JSON file, let esbuild bundle it\n if (args.path.endsWith('.json')) {\n return null // Let esbuild handle it\n }\n // Otherwise mark as external\n return { path: args.path, external: true }\n })\n },\n }\n\n // Use esbuild.build with bundling to handle JSON imports\n await esbuild.build({\n entryPoints: [tsPath],\n outfile: jsPath,\n bundle: true,\n format: 'esm',\n platform: 'node',\n target: 'node18',\n plugins: [aliasPlugin, externalNonJsonPlugin],\n // Allow JSON imports\n loader: { '.json': 'json' },\n })\n }\n\n // Import the compiled JavaScript\n try {\n const fileUrl = `${pathToFileURL(jsPath).href}?mtime=${fs.statSync(jsPath).mtimeMs}`\n return import(fileUrl)\n } catch (error) {\n if (!allowRecovery) {\n throw error\n }\n\n const recovered = recoverMikroOrmV7GeneratedCacheFromImportError(appRoot, error)\n if (!recovered.applied) {\n throw error\n }\n\n return compileAndImport(tsPath, false)\n }\n}\n\n\n/**\n * Dynamically load bootstrap data from a resolved app directory.\n *\n * IMPORTANT: This only works in unbundled contexts (CLI, tsx).\n * Do NOT use this in Next.js bundled code - use static imports instead.\n *\n * For CLI context, we skip loading modules.generated.ts which has Next.js dependencies.\n * CLI commands are discovered separately via the CLI module system.\n *\n * @param appRoot - Optional explicit app root path. If not provided, will search from cwd.\n * @returns The loaded bootstrap data\n * @throws Error if app root cannot be found or generated files are missing\n */\nexport async function loadBootstrapData(appRoot?: string): Promise<BootstrapData> {\n const resolved: AppRoot | null = appRoot\n ? {\n generatedDir: path.join(appRoot, '.mercato', 'generated'),\n appDir: appRoot,\n mercatoDir: path.join(appRoot, '.mercato'),\n }\n : findAppRoot()\n\n if (!resolved) {\n throw new Error(\n 'Could not find app root with .mercato/generated directory. ' +\n 'Make sure you run this command from within a Next.js app directory, ' +\n 'or run \"yarn mercato generate\" first to create the generated files.',\n )\n }\n\n const { generatedDir } = resolved\n\n ensureMikroOrmV7GeneratedCacheCompatibility(resolved.appDir)\n\n // IMPORTANT: Load entity IDs FIRST and register them before loading modules.\n // This is because modules (e.g., ce.ts files) use E.xxx.xxx at module scope,\n // and they need entity IDs to be available when they're imported.\n const entityIdsModule = await compileAndImport(path.join(generatedDir, 'entities.ids.generated.ts'))\n registerEntityIds(entityIdsModule.E as BootstrapData['entityIds'])\n\n // Now load the rest of the generated files.\n // modules.cli.generated.ts excludes Next.js-dependent code (routes, APIs, widgets)\n const [\n modulesModule,\n entitiesModule,\n diModule,\n searchModule,\n commandLoadersModule,\n commandInterceptorsModule,\n workflowsModule,\n ] = await Promise.all([\n compileAndImport(path.join(generatedDir, 'modules.cli.generated.ts')),\n compileAndImport(path.join(generatedDir, 'entities.generated.ts')),\n compileAndImport(path.join(generatedDir, 'di.generated.ts')),\n compileAndImport(path.join(generatedDir, 'search.generated.ts')).catch(() => ({ searchModuleConfigs: [] })),\n compileAndImport(path.join(generatedDir, 'command-loaders.generated.ts')).catch(() => ({ commandLoaderEntries: [] })),\n compileAndImport(path.join(generatedDir, 'command-interceptors.generated.ts')).catch(() => ({ commandInterceptorEntries: [] })),\n compileAndImport(path.join(generatedDir, 'workflows.generated.ts')).catch(() => ({ allCodeWorkflows: [] })),\n ])\n\n return {\n modules: modulesModule.modules as BootstrapData['modules'],\n entities: entitiesModule.entities as BootstrapData['entities'],\n diRegistrars: diModule.diRegistrars as BootstrapData['diRegistrars'],\n entityIds: entityIdsModule.E as BootstrapData['entityIds'],\n // Search configs are needed by workers for indexing\n searchModuleConfigs: (searchModule.searchModuleConfigs ?? []) as BootstrapData['searchModuleConfigs'],\n commandLoaderEntries: (commandLoadersModule.commandLoaderEntries ?? []) as BootstrapData['commandLoaderEntries'],\n // Command interceptors must apply in worker/CLI processes too \u2014 the\n // interceptor registry is per-process, so relying on the Next.js runtime's\n // registration silently no-ops every interceptor for queued/CLI commands\n // (#4327).\n commandInterceptorEntries: (commandInterceptorsModule.commandInterceptorEntries ??\n []) as BootstrapData['commandInterceptorEntries'],\n // Code workflow definitions are needed by workers to resume code-defined instances\n codeWorkflows: (workflowsModule.allCodeWorkflows ?? []) as BootstrapData['codeWorkflows'],\n // Empty UI-related data - not needed for CLI\n dashboardWidgetEntries: [],\n injectionWidgetEntries: [],\n injectionTables: [],\n interceptorEntries: [],\n componentOverrideEntries: [],\n }\n}\n\n/**\n * Create and execute bootstrap in CLI context.\n *\n * This is a convenience function that finds the app root, loads the generated\n * data dynamically, and runs bootstrap. Use this in CLI entry points.\n *\n * Returns the loaded bootstrap data so the CLI can register modules directly\n * (avoids module resolution issues when importing @open-mercato/cli/mercato).\n *\n * @param appRoot - Optional explicit app root path\n * @returns The loaded bootstrap data (modules, entities, etc.)\n */\nexport async function bootstrapFromAppRoot(appRoot?: string): Promise<BootstrapData> {\n const { createBootstrap, waitForAsyncRegistration } = await import('./factory.js')\n const data = await loadBootstrapData(appRoot)\n const bootstrap = createBootstrap(data)\n bootstrap()\n // In CLI context, wait for async registrations (UI widgets, search configs, etc.)\n await waitForAsyncRegistration()\n\n return data\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/lib/crud/factory.js
CHANGED
|
@@ -45,7 +45,7 @@ import { createProfiler, shouldEnableProfiler } from "@open-mercato/shared/lib/p
|
|
|
45
45
|
import { getTranslationOverlayPlugin } from "@open-mercato/shared/lib/localization/overlay-plugin";
|
|
46
46
|
import { applyResponseEnrichers, applyResponseEnricherToRecord, resolveListCacheEnricherPlan } from "./enricher-runner.js";
|
|
47
47
|
import { runApiInterceptorsAfter, runApiInterceptorsBefore } from "./interceptor-runner.js";
|
|
48
|
-
import { mergeIdFilter, parseIdsParam } from "./ids.js";
|
|
48
|
+
import { mergeIdFilter, parseIdsParam, isIdsParamProvided } from "./ids.js";
|
|
49
49
|
import { mergeAdvancedFilters } from "./advanced-filter-integration.js";
|
|
50
50
|
import { parseExtensionHeaders } from "../umes/extension-headers.js";
|
|
51
51
|
import { createGenericOptimisticLockReader } from "./optimistic-lock.js";
|
|
@@ -975,6 +975,7 @@ function makeCrudRoute(opts) {
|
|
|
975
975
|
...interceptorRequest.query ?? {}
|
|
976
976
|
};
|
|
977
977
|
const parsedIds = parseIdsParam(queryParams.ids);
|
|
978
|
+
const idsParamProvided = isIdsParamProvided(queryParams.ids);
|
|
978
979
|
await opts.hooks?.beforeList?.(validated, ctx);
|
|
979
980
|
profiler.mark("before_list_hook");
|
|
980
981
|
const availableFormats = resolveAvailableExportFormats(opts.list);
|
|
@@ -1155,7 +1156,7 @@ function makeCrudRoute(opts) {
|
|
|
1155
1156
|
const page = exportRequested ? { page: 1, pageSize: exportPageSize } : { page: requestedPage, pageSize: requestedPageSize };
|
|
1156
1157
|
const baseFilters = exportFullRequested ? {} : opts.list.buildFilters ? await opts.list.buildFilters(validated, ctx) : {};
|
|
1157
1158
|
const filters = exportFullRequested ? baseFilters : mergeAdvancedFilters(baseFilters, validated);
|
|
1158
|
-
const mergedFilters = exportFullRequested ? filters : mergeIdFilter(filters, parsedIds);
|
|
1159
|
+
const mergedFilters = exportFullRequested ? filters : mergeIdFilter(filters, parsedIds, { idsParamProvided });
|
|
1159
1160
|
const withDeleted = parseBooleanToken(queryParams.withDeleted) === true;
|
|
1160
1161
|
profiler.mark("filters_ready", { withDeleted });
|
|
1161
1162
|
if (ormCfg.orgField && ctx.organizationIds && ctx.organizationIds.length === 0 && !opts.list?.omitAutomaticTenantOrgScope) {
|
|
@@ -1412,7 +1413,7 @@ function makeCrudRoute(opts) {
|
|
|
1412
1413
|
}
|
|
1413
1414
|
const fallbackBaseFilters = exportFullRequested ? {} : opts.list.buildFilters ? await opts.list.buildFilters(validated, ctx) : {};
|
|
1414
1415
|
const fallbackFilters = exportFullRequested ? fallbackBaseFilters : mergeAdvancedFilters(fallbackBaseFilters, validated);
|
|
1415
|
-
const mergedFallbackFilters = exportFullRequested ? fallbackFilters : mergeIdFilter(fallbackFilters, parsedIds);
|
|
1416
|
+
const mergedFallbackFilters = exportFullRequested ? fallbackFilters : mergeIdFilter(fallbackFilters, parsedIds, { idsParamProvided });
|
|
1416
1417
|
const ormFilters = translateFiltersForOrm(
|
|
1417
1418
|
mergedFallbackFilters,
|
|
1418
1419
|
em,
|