@dudousxd/nestjs-catalog 0.13.0 → 0.15.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/client.js CHANGED
@@ -11,7 +11,7 @@
11
11
  * types are.
12
12
  */
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.DELETE_RECONCILIATION_STRATEGIES = exports.isWorkflowStatus = exports.isWorkflowNodeKind = exports.isWorkflowExecutionMode = exports.workflowRunOrder = exports.workflowGraphHash = exports.WORKFLOW_STATUSES = exports.WORKFLOW_NODE_KINDS = exports.WORKFLOW_NODE_ID_PATTERN = exports.WORKFLOW_ISSUE_CODES = exports.WORKFLOW_EXECUTION_MODES = exports.validateWorkflow = exports.TRANSFORM_LANGUAGES = exports.isWorkflowNode = exports.isWorkflowEdge = exports.isTransformLanguage = exports.isConnectorKind = exports.CONNECTOR_KINDS = exports.catalogRoutes = exports.CATALOG_REVISION_LIMIT = void 0;
14
+ exports.DELETE_RECONCILIATION_STRATEGIES = exports.isWorkflowStatus = exports.isWorkflowNodeKind = exports.isWorkflowExecutionMode = exports.workflowRunOrder = exports.workflowGraphHash = exports.WORKFLOW_STATUSES = exports.WORKFLOW_NODE_KINDS = exports.WORKFLOW_NODE_ID_PATTERN = exports.WORKFLOW_ISSUE_CODES = exports.WORKFLOW_EXECUTION_MODES = exports.validateWorkflow = exports.WORKFLOW_CALL_CONTRACT = exports.readWorkflowCallOutput = exports.TRANSFORM_LANGUAGES = exports.isWorkflowNode = exports.isWorkflowEdge = exports.isTransformLanguage = exports.isConnectorKind = exports.CONNECTOR_KINDS = exports.catalogRoutes = exports.UnsafeIdentifierError = exports.physicalColumn = exports.outputAlias = exports.isSafeIdentifier = exports.VALUELESS_FILTER_OPERATORS = exports.resolveObjectFilters = exports.parseObjectFilter = exports.offeredFilterOperators = exports.isCatalogFilterOperator = exports.filterOperatorsFor = exports.filterOperatorTakesValue = exports.encodeObjectFilter = exports.coerceFilterValue = exports.CATALOG_FILTER_OPERATORS = exports.CATALOG_FILTER_LIMIT = exports.CATALOG_REVISION_LIMIT = void 0;
15
15
  exports.isDeleteReconciliationStrategy = isDeleteReconciliationStrategy;
16
16
  exports.pipelineExpectationRoutes = pipelineExpectationRoutes;
17
17
  // A value, not a type: a screen saying how far back the history goes should read
@@ -19,6 +19,67 @@ exports.pipelineExpectationRoutes = pipelineExpectationRoutes;
19
19
  // costs.
20
20
  var catalog_workspace_1 = require("./catalog.workspace");
21
21
  Object.defineProperty(exports, "CATALOG_REVISION_LIMIT", { enumerable: true, get: function () { return catalog_workspace_1.CATALOG_REVISION_LIMIT; } });
22
+ /**
23
+ * The filter rule, shipped to the browser deliberately — the same exception, for
24
+ * the same reason, that `validateWorkflow` further down is.
25
+ *
26
+ * A console has to know which control to draw for a column, and the only way for
27
+ * that answer to match what the server will accept is for both to run this
28
+ * function. A screen with its own copy of the rules eventually lies: it offers a
29
+ * control the read refuses, or omits one that would have worked, and on types
30
+ * that are created at runtime nobody notices until a publisher adds a column. The
31
+ * functions are pure and import nothing.
32
+ *
33
+ * `SnapshotRef` rides along because a snapshot picker is a browser screen and
34
+ * `GET objects/:name/snapshots` is what fills it. The endpoints alone are not an
35
+ * API; the endpoints plus the response types are.
36
+ */
37
+ var catalog_filters_1 = require("./catalog.filters");
38
+ Object.defineProperty(exports, "CATALOG_FILTER_LIMIT", { enumerable: true, get: function () { return catalog_filters_1.CATALOG_FILTER_LIMIT; } });
39
+ Object.defineProperty(exports, "CATALOG_FILTER_OPERATORS", { enumerable: true, get: function () { return catalog_filters_1.CATALOG_FILTER_OPERATORS; } });
40
+ Object.defineProperty(exports, "coerceFilterValue", { enumerable: true, get: function () { return catalog_filters_1.coerceFilterValue; } });
41
+ Object.defineProperty(exports, "encodeObjectFilter", { enumerable: true, get: function () { return catalog_filters_1.encodeObjectFilter; } });
42
+ Object.defineProperty(exports, "filterOperatorTakesValue", { enumerable: true, get: function () { return catalog_filters_1.filterOperatorTakesValue; } });
43
+ Object.defineProperty(exports, "filterOperatorsFor", { enumerable: true, get: function () { return catalog_filters_1.filterOperatorsFor; } });
44
+ Object.defineProperty(exports, "isCatalogFilterOperator", { enumerable: true, get: function () { return catalog_filters_1.isCatalogFilterOperator; } });
45
+ Object.defineProperty(exports, "offeredFilterOperators", { enumerable: true, get: function () { return catalog_filters_1.offeredFilterOperators; } });
46
+ Object.defineProperty(exports, "parseObjectFilter", { enumerable: true, get: function () { return catalog_filters_1.parseObjectFilter; } });
47
+ Object.defineProperty(exports, "resolveObjectFilters", { enumerable: true, get: function () { return catalog_filters_1.resolveObjectFilters; } });
48
+ Object.defineProperty(exports, "VALUELESS_FILTER_OPERATORS", { enumerable: true, get: function () { return catalog_filters_1.VALUELESS_FILTER_OPERATORS; } });
49
+ /**
50
+ * How a name becomes a column, shipped to the browser deliberately.
51
+ *
52
+ * The second exception to "types only" on this entry point, and it is made for
53
+ * the same reason `validateWorkflow` is the first: the answer has to be the
54
+ * same one the server will give, and the only way to guarantee that is for both
55
+ * to run these functions.
56
+ *
57
+ * A console proposing to replicate a table has to be able to ask, *before* it
58
+ * draws anything, whether the source's own column spellings could be published
59
+ * as property names — because a property `name` is what the warehouse looks
60
+ * every field up by, `row[property.name]`, so a name the publisher then refuses
61
+ * has to be renamed, and a rename with nothing renaming the record's keys to
62
+ * match writes null into that column on every run and reports success. That is
63
+ * not a hypothesis; it is what happened to six types in one evening.
64
+ *
65
+ * **Both halves, because the composition is the rule.** A name no longer has to
66
+ * be an identifier itself — the view's output alias and the read's lookup key go
67
+ * through {@link outputAlias} together, so `Asset Id` is a perfectly good
68
+ * property name and lands in `Asset_Id`. What is still refused is a name whose
69
+ * *cleaned* form is not an identifier: `2024 Total` cleans to `2024_Total`, and
70
+ * no store will quote a name starting with a digit. So the question worth asking
71
+ * from a browser is `isSafeIdentifier(physicalColumn(name))` — the same two
72
+ * calls, in the same order, that `identifierRefusal` makes at publish time.
73
+ * Exporting only `isSafeIdentifier` would let a console answer the stricter,
74
+ * obsolete question and refuse a graph the server would have accepted.
75
+ *
76
+ * Safe to export because `catalog.identifiers.ts` imports nothing at all.
77
+ */
78
+ var catalog_identifiers_1 = require("./catalog.identifiers");
79
+ Object.defineProperty(exports, "isSafeIdentifier", { enumerable: true, get: function () { return catalog_identifiers_1.isSafeIdentifier; } });
80
+ Object.defineProperty(exports, "outputAlias", { enumerable: true, get: function () { return catalog_identifiers_1.outputAlias; } });
81
+ Object.defineProperty(exports, "physicalColumn", { enumerable: true, get: function () { return catalog_identifiers_1.physicalColumn; } });
82
+ Object.defineProperty(exports, "UnsafeIdentifierError", { enumerable: true, get: function () { return catalog_identifiers_1.UnsafeIdentifierError; } });
22
83
  /**
23
84
  * Builds the paths the catalog controller serves, relative to wherever it was
24
85
  * mounted. Kept as string builders rather than a fetch wrapper so the host
@@ -80,6 +141,10 @@ Object.defineProperty(exports, "isTransformLanguage", { enumerable: true, get: f
80
141
  Object.defineProperty(exports, "isWorkflowEdge", { enumerable: true, get: function () { return catalog_pipeline_1.isWorkflowEdge; } });
81
142
  Object.defineProperty(exports, "isWorkflowNode", { enumerable: true, get: function () { return catalog_pipeline_1.isWorkflowNode; } });
82
143
  Object.defineProperty(exports, "TRANSFORM_LANGUAGES", { enumerable: true, get: function () { return catalog_pipeline_1.TRANSFORM_LANGUAGES; } });
144
+ // A screen that shows what a call node got back narrows it the same way the
145
+ // runner does, so the two cannot disagree about what "no rows" looks like.
146
+ Object.defineProperty(exports, "readWorkflowCallOutput", { enumerable: true, get: function () { return catalog_pipeline_1.readWorkflowCallOutput; } });
147
+ Object.defineProperty(exports, "WORKFLOW_CALL_CONTRACT", { enumerable: true, get: function () { return catalog_pipeline_1.WORKFLOW_CALL_CONTRACT; } });
83
148
  /**
84
149
  * The workflow validator, shipped to the browser deliberately.
85
150
  *
package/dist/index.d.ts CHANGED
@@ -1,16 +1,17 @@
1
1
  export { CatalogProperty, type CatalogPropertyOptions, CatalogType, type CatalogTypeOptions, } from './catalog.decorators';
2
2
  export { CATALOG_EVENT_PHASE, CATALOG_EVENT_PHASE_FALLBACK, CATALOG_EVENTS, CATALOG_LIB, type CatalogEvent, type CatalogEventPayloads, UNATTRIBUTED_PRINCIPAL_ID, catalogEventPhase, channelNameFor, curationActor, emitCatalog, } from './catalog.events';
3
3
  export { CatalogModule } from './catalog.module';
4
- export { assertReadOnlyShape, type CatalogQueryRelation, type CatalogQueryRequest, type CatalogQueryResult, type CatalogQueryStore, isQueryStore, } from './catalog.query';
4
+ export { assertReadOnlyShape, type CatalogQueryRelation, type CatalogQueryRequest, type CatalogQueryResult, type CatalogQueryStore, type CatalogQueryStreamRequest, isQueryStore, isStreamingQueryStore, } from './catalog.query';
5
5
  export { CATALOG_OPTIONS, type CatalogModuleOptions } from './catalog.options';
6
6
  export * from './catalog.secrets';
7
7
  export { type CatalogOverlayStore, FileCatalogOverlayStore, InMemoryCatalogOverlayStore, } from './catalog.overlay-store';
8
8
  export { CATALOG_OVERLAY_STORE } from './catalog.overlay-store.token';
9
9
  export { MikroOrmCatalogRegistry } from './catalog.registry';
10
10
  export { CatalogRegistry } from './catalog.registry.base';
11
- export { CATALOG_PIPELINE_STORE, type CatalogConnection, type CatalogConnector, type ConnectionCheck, CONNECTOR_KINDS, type CatalogLoadExpectations, type CatalogLoadExpectationStore, type CatalogPipelineStore, type CatalogStageStore, type CatalogTransform, type CatalogWorkflow, type CatalogWorkflowCapabilities, type CatalogWorkflowStore, type ConnectorKind, type ConnectorRun, type DeleteReconciliation, isConnectorKind, isPipelineStore, isTransformLanguage, type LoadExpectation, type RowCountBound, type StoredLoadExpectation, supportsLoadExpectations, supportsTransformRevisions, isWorkflowEdge, isWorkflowExecutionMode, isWorkflowNode, isWorkflowNodeKind, isWorkflowStatus, supportsWorkflows, supportsWorkflowStages, TRANSFORM_RUNNER, TRANSFORM_LANGUAGES, type TransformLanguage, type TransformResult, type TransformRunner, validateWorkflow, WORKFLOW_EXECUTION_MODES, WORKFLOW_ISSUE_CODES, WORKFLOW_NODE_ID_PATTERN, WORKFLOW_NODE_KINDS, WORKFLOW_STATUSES, type WorkflowEdge, type WorkflowExecutionMode, type WorkflowGraph, workflowGraphHash, type WorkflowIssueCode, type WorkflowNode, type WorkflowNodeKind, type WorkflowNodeOutcome, type WorkflowNodeStepInput, type WorkflowNodeStepOutput, workflowRunOrder, type WorkflowSinkNode, type WorkflowSourceNode, type WorkflowStageRef, type WorkflowStatus, type WorkflowTransformNode, type WorkflowValidationIssue, } from './catalog.pipeline';
11
+ export { CATALOG_PIPELINE_STORE, type CatalogConnection, type CatalogConnector, type ConnectionCheck, CONNECTOR_KINDS, type CatalogLoadExpectations, type CatalogLoadExpectationStore, type CatalogPipelineStore, type CatalogStageStore, type CatalogTransform, type CatalogWorkflow, type CatalogWorkflowCapabilities, type CatalogWorkflowStore, type CallableWorkflowRef, type ConnectorKind, type ConnectorRun, type DeleteReconciliation, isConnectorKind, isPipelineStore, isTransformLanguage, type LoadExpectation, type RowCountBound, type StoredLoadExpectation, readWorkflowCallOutput, supportsLoadExpectations, supportsTransformRevisions, isWorkflowEdge, isWorkflowExecutionMode, isWorkflowNode, isWorkflowNodeKind, isWorkflowStatus, supportsWorkflows, supportsWorkflowStages, TRANSFORM_RUNNER, TRANSFORM_LANGUAGES, type TransformLanguage, type TransformResult, type TransformRunner, validateWorkflow, WORKFLOW_CALL_CONTRACT, WORKFLOW_EXECUTION_MODES, WORKFLOW_ISSUE_CODES, WORKFLOW_NODE_ID_PATTERN, WORKFLOW_NODE_KINDS, WORKFLOW_STATUSES, type WorkflowCallEnvelope, type WorkflowCallNode, type WorkflowCallOutput, type WorkflowEdge, type WorkflowExecutionMode, type WorkflowGraph, workflowGraphHash, type WorkflowIssueCode, type WorkflowNode, type WorkflowNodeKind, type WorkflowNodeOutcome, type WorkflowNodeStepInput, type WorkflowNodeStepOutput, workflowRunOrder, type WorkflowSinkNode, type WorkflowSourceNode, type WorkflowStageRef, type WorkflowStatus, type WorkflowTransformNode, type WorkflowValidationIssue, } from './catalog.pipeline';
12
12
  export * from './catalog.environment';
13
- export { QueryCache, toCsv } from './catalog.query-cache';
13
+ export { QueryCache } from './catalog.query-cache';
14
+ export { type CsvRow, csvCell, csvLines, guardFormula, toCsv } from './catalog.csv';
14
15
  export { SubprocessTransformRunner, type TransformRunnerOptions, } from './transform-runner';
15
16
  export { CatalogService } from './catalog.service';
16
17
  export { DEFAULT_SEARCH_LIMIT, MAX_SEARCH_LIMIT, bestMatch, emptySearch, maySearch, type SearchInput, type SearchableDashboard, type SearchableSavedQuery, searchCatalog, visibleToPrincipal, } from './search';
@@ -18,7 +19,8 @@ export type { CatalogSearchField, CatalogSearchHit, CatalogSearchKind, CatalogSe
18
19
  export { type AuditQuery, CATALOG_REVISION_LIMIT, CATALOG_TRACE_OUTCOMES, CATALOG_TRACE_STORE, CATALOG_WORKSPACE_STORE, type CatalogAuditEvent, type CatalogRevision, type CatalogTrace, type CatalogTraceList, type CatalogTraceOutcome, type CatalogTraceSpan, type CatalogTraceStore, type CatalogTraceTotals, type CatalogUnlinkedList, type CatalogWorkspaceStore, type Dashboard, type DashboardCard, type EmbeddedChart, type EmbeddedChartPlacement, type EmbeddedDashboard, embeddedVisualization, isCatalogTraceOutcome, isTraceStore, isWorkspaceStore, type QueryVisualization, type SaveQueryInput, type SavedQuery, supportsSavedQueryRevisions, type TraceQuery, traceOutcomeFilter, } from './catalog.workspace';
19
20
  export { CATALOG_PRINCIPAL_RESOLVER, type CatalogActor, type CatalogGrants, type CatalogPrincipal, type CatalogPrincipalResolver, type CatalogScope, composePrincipalId, delegatePrincipal, expandScopes, hasScope, parsePrincipalId, PRINCIPAL_ACTOR_SEPARATOR, maySeeClassification, mayRead, mayWrite, readableObjectPage, StaticKeyPrincipalResolver, } from './catalog.principal';
20
21
  export * from './catalog.access';
21
- export { assertNoColumnCollisions, assertSafeIdentifier, CATALOG_RESERVED_COLUMNS, CATALOG_SNAPSHOT_MODES, CATALOG_STORE, type CarryForwardResult, type CatalogColumnCollision, CatalogColumnCollisionError, type CatalogMergeStore, type CatalogReadQuery, type CatalogReadResult, type CatalogReadStore, type CatalogReservedColumn, type CatalogSnapshotMode, type CatalogStoreCapabilities, type CatalogWriteStore, type ColumnCollisionOptions, findColumnCollisions, isCatalogStoreCapabilities, isReservedColumn, isSafeIdentifier, isWriteStore, type SnapshotRef, supportsCarryForward, UnsafeIdentifierError, } from './catalog.store';
22
+ export * from './catalog.filters';
23
+ export { assertNoColumnCollisions, assertSafeIdentifier, CATALOG_RESERVED_COLUMNS, CATALOG_SNAPSHOT_MODES, CATALOG_STORE, type CarryForwardResult, type CatalogColumnCollision, CatalogColumnCollisionError, type CatalogFilteringReadStore, supportsObjectFilters, type CatalogMergeStore, type CatalogReadQuery, type CatalogReadResult, type CatalogReadStore, type CatalogReservedColumn, type CatalogSnapshotMode, type CatalogStoreCapabilities, type CatalogWriteStore, type ColumnCollisionOptions, findColumnCollisions, isCatalogStoreCapabilities, isReservedColumn, isSafeIdentifier, isWriteStore, outputAlias, physicalColumn, type SnapshotRef, supportsCarryForward, UnsafeIdentifierError, } from './catalog.store';
22
24
  export { MikroOrmReadStore } from './stores/mikro-orm-read.store';
23
25
  export type { CatalogGraph, CatalogObjectPage, CatalogObjectQuery, CatalogObjectTypeDef, CatalogOverlay, CatalogPropertyDef, CatalogRelationDef, CatalogSnapshot, RelationKind, ScalarType, } from './catalog.types';
24
26
  export { REQUIRED_SCOPES, REQUIRES_HUMAN, RequireHuman, RequireScopes, } from './catalog.route-auth';
package/dist/index.js CHANGED
@@ -14,8 +14,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.MAX_SEARCH_LIMIT = exports.DEFAULT_SEARCH_LIMIT = exports.CatalogService = exports.SubprocessTransformRunner = exports.toCsv = exports.QueryCache = exports.workflowRunOrder = exports.workflowGraphHash = exports.WORKFLOW_STATUSES = exports.WORKFLOW_NODE_KINDS = exports.WORKFLOW_NODE_ID_PATTERN = exports.WORKFLOW_ISSUE_CODES = exports.WORKFLOW_EXECUTION_MODES = exports.validateWorkflow = exports.TRANSFORM_LANGUAGES = exports.TRANSFORM_RUNNER = exports.supportsWorkflowStages = exports.supportsWorkflows = exports.isWorkflowStatus = exports.isWorkflowNodeKind = exports.isWorkflowNode = exports.isWorkflowExecutionMode = exports.isWorkflowEdge = exports.supportsTransformRevisions = exports.supportsLoadExpectations = exports.isTransformLanguage = exports.isPipelineStore = exports.isConnectorKind = exports.CONNECTOR_KINDS = exports.CATALOG_PIPELINE_STORE = exports.CatalogRegistry = exports.MikroOrmCatalogRegistry = exports.CATALOG_OVERLAY_STORE = exports.InMemoryCatalogOverlayStore = exports.FileCatalogOverlayStore = exports.CATALOG_OPTIONS = exports.isQueryStore = exports.assertReadOnlyShape = exports.CatalogModule = exports.emitCatalog = exports.curationActor = exports.channelNameFor = exports.catalogEventPhase = exports.UNATTRIBUTED_PRINCIPAL_ID = exports.CATALOG_LIB = exports.CATALOG_EVENTS = exports.CATALOG_EVENT_PHASE_FALLBACK = exports.CATALOG_EVENT_PHASE = exports.CatalogType = exports.CatalogProperty = void 0;
18
- exports.RequireScopes = exports.RequireHuman = exports.REQUIRES_HUMAN = exports.REQUIRED_SCOPES = exports.MikroOrmReadStore = exports.UnsafeIdentifierError = exports.supportsCarryForward = exports.isWriteStore = exports.isSafeIdentifier = exports.isReservedColumn = exports.isCatalogStoreCapabilities = exports.findColumnCollisions = exports.CatalogColumnCollisionError = exports.CATALOG_STORE = exports.CATALOG_SNAPSHOT_MODES = exports.CATALOG_RESERVED_COLUMNS = exports.assertSafeIdentifier = exports.assertNoColumnCollisions = exports.StaticKeyPrincipalResolver = exports.readableObjectPage = exports.mayWrite = exports.mayRead = exports.maySeeClassification = exports.PRINCIPAL_ACTOR_SEPARATOR = exports.parsePrincipalId = exports.hasScope = exports.expandScopes = exports.delegatePrincipal = exports.composePrincipalId = exports.CATALOG_PRINCIPAL_RESOLVER = exports.traceOutcomeFilter = exports.supportsSavedQueryRevisions = exports.isWorkspaceStore = exports.isTraceStore = exports.isCatalogTraceOutcome = exports.embeddedVisualization = exports.CATALOG_WORKSPACE_STORE = exports.CATALOG_TRACE_STORE = exports.CATALOG_TRACE_OUTCOMES = exports.CATALOG_REVISION_LIMIT = exports.visibleToPrincipal = exports.searchCatalog = exports.maySearch = exports.emptySearch = exports.bestMatch = void 0;
17
+ exports.csvLines = exports.csvCell = exports.QueryCache = exports.workflowRunOrder = exports.workflowGraphHash = exports.WORKFLOW_STATUSES = exports.WORKFLOW_NODE_KINDS = exports.WORKFLOW_NODE_ID_PATTERN = exports.WORKFLOW_ISSUE_CODES = exports.WORKFLOW_EXECUTION_MODES = exports.WORKFLOW_CALL_CONTRACT = exports.validateWorkflow = exports.TRANSFORM_LANGUAGES = exports.TRANSFORM_RUNNER = exports.supportsWorkflowStages = exports.supportsWorkflows = exports.isWorkflowStatus = exports.isWorkflowNodeKind = exports.isWorkflowNode = exports.isWorkflowExecutionMode = exports.isWorkflowEdge = exports.supportsTransformRevisions = exports.supportsLoadExpectations = exports.readWorkflowCallOutput = exports.isTransformLanguage = exports.isPipelineStore = exports.isConnectorKind = exports.CONNECTOR_KINDS = exports.CATALOG_PIPELINE_STORE = exports.CatalogRegistry = exports.MikroOrmCatalogRegistry = exports.CATALOG_OVERLAY_STORE = exports.InMemoryCatalogOverlayStore = exports.FileCatalogOverlayStore = exports.CATALOG_OPTIONS = exports.isStreamingQueryStore = exports.isQueryStore = exports.assertReadOnlyShape = exports.CatalogModule = exports.emitCatalog = exports.curationActor = exports.channelNameFor = exports.catalogEventPhase = exports.UNATTRIBUTED_PRINCIPAL_ID = exports.CATALOG_LIB = exports.CATALOG_EVENTS = exports.CATALOG_EVENT_PHASE_FALLBACK = exports.CATALOG_EVENT_PHASE = exports.CatalogType = exports.CatalogProperty = void 0;
18
+ exports.MikroOrmReadStore = exports.UnsafeIdentifierError = exports.supportsCarryForward = exports.physicalColumn = exports.outputAlias = exports.isWriteStore = exports.isSafeIdentifier = exports.isReservedColumn = exports.isCatalogStoreCapabilities = exports.findColumnCollisions = exports.supportsObjectFilters = exports.CatalogColumnCollisionError = exports.CATALOG_STORE = exports.CATALOG_SNAPSHOT_MODES = exports.CATALOG_RESERVED_COLUMNS = exports.assertSafeIdentifier = exports.assertNoColumnCollisions = exports.StaticKeyPrincipalResolver = exports.readableObjectPage = exports.mayWrite = exports.mayRead = exports.maySeeClassification = exports.PRINCIPAL_ACTOR_SEPARATOR = exports.parsePrincipalId = exports.hasScope = exports.expandScopes = exports.delegatePrincipal = exports.composePrincipalId = exports.CATALOG_PRINCIPAL_RESOLVER = exports.traceOutcomeFilter = exports.supportsSavedQueryRevisions = exports.isWorkspaceStore = exports.isTraceStore = exports.isCatalogTraceOutcome = exports.embeddedVisualization = exports.CATALOG_WORKSPACE_STORE = exports.CATALOG_TRACE_STORE = exports.CATALOG_TRACE_OUTCOMES = exports.CATALOG_REVISION_LIMIT = exports.visibleToPrincipal = exports.searchCatalog = exports.maySearch = exports.emptySearch = exports.bestMatch = exports.MAX_SEARCH_LIMIT = exports.DEFAULT_SEARCH_LIMIT = exports.CatalogService = exports.SubprocessTransformRunner = exports.toCsv = exports.guardFormula = void 0;
19
+ exports.RequireScopes = exports.RequireHuman = exports.REQUIRES_HUMAN = exports.REQUIRED_SCOPES = void 0;
19
20
  var catalog_decorators_1 = require("./catalog.decorators");
20
21
  Object.defineProperty(exports, "CatalogProperty", { enumerable: true, get: function () { return catalog_decorators_1.CatalogProperty; } });
21
22
  Object.defineProperty(exports, "CatalogType", { enumerable: true, get: function () { return catalog_decorators_1.CatalogType; } });
@@ -34,6 +35,7 @@ Object.defineProperty(exports, "CatalogModule", { enumerable: true, get: functio
34
35
  var catalog_query_1 = require("./catalog.query");
35
36
  Object.defineProperty(exports, "assertReadOnlyShape", { enumerable: true, get: function () { return catalog_query_1.assertReadOnlyShape; } });
36
37
  Object.defineProperty(exports, "isQueryStore", { enumerable: true, get: function () { return catalog_query_1.isQueryStore; } });
38
+ Object.defineProperty(exports, "isStreamingQueryStore", { enumerable: true, get: function () { return catalog_query_1.isStreamingQueryStore; } });
37
39
  var catalog_options_1 = require("./catalog.options");
38
40
  Object.defineProperty(exports, "CATALOG_OPTIONS", { enumerable: true, get: function () { return catalog_options_1.CATALOG_OPTIONS; } });
39
41
  // Everything, deliberately, and here more than anywhere: this is a seam two
@@ -59,6 +61,7 @@ Object.defineProperty(exports, "CONNECTOR_KINDS", { enumerable: true, get: funct
59
61
  Object.defineProperty(exports, "isConnectorKind", { enumerable: true, get: function () { return catalog_pipeline_1.isConnectorKind; } });
60
62
  Object.defineProperty(exports, "isPipelineStore", { enumerable: true, get: function () { return catalog_pipeline_1.isPipelineStore; } });
61
63
  Object.defineProperty(exports, "isTransformLanguage", { enumerable: true, get: function () { return catalog_pipeline_1.isTransformLanguage; } });
64
+ Object.defineProperty(exports, "readWorkflowCallOutput", { enumerable: true, get: function () { return catalog_pipeline_1.readWorkflowCallOutput; } });
62
65
  Object.defineProperty(exports, "supportsLoadExpectations", { enumerable: true, get: function () { return catalog_pipeline_1.supportsLoadExpectations; } });
63
66
  Object.defineProperty(exports, "supportsTransformRevisions", { enumerable: true, get: function () { return catalog_pipeline_1.supportsTransformRevisions; } });
64
67
  Object.defineProperty(exports, "isWorkflowEdge", { enumerable: true, get: function () { return catalog_pipeline_1.isWorkflowEdge; } });
@@ -71,6 +74,7 @@ Object.defineProperty(exports, "supportsWorkflowStages", { enumerable: true, get
71
74
  Object.defineProperty(exports, "TRANSFORM_RUNNER", { enumerable: true, get: function () { return catalog_pipeline_1.TRANSFORM_RUNNER; } });
72
75
  Object.defineProperty(exports, "TRANSFORM_LANGUAGES", { enumerable: true, get: function () { return catalog_pipeline_1.TRANSFORM_LANGUAGES; } });
73
76
  Object.defineProperty(exports, "validateWorkflow", { enumerable: true, get: function () { return catalog_pipeline_1.validateWorkflow; } });
77
+ Object.defineProperty(exports, "WORKFLOW_CALL_CONTRACT", { enumerable: true, get: function () { return catalog_pipeline_1.WORKFLOW_CALL_CONTRACT; } });
74
78
  Object.defineProperty(exports, "WORKFLOW_EXECUTION_MODES", { enumerable: true, get: function () { return catalog_pipeline_1.WORKFLOW_EXECUTION_MODES; } });
75
79
  Object.defineProperty(exports, "WORKFLOW_ISSUE_CODES", { enumerable: true, get: function () { return catalog_pipeline_1.WORKFLOW_ISSUE_CODES; } });
76
80
  Object.defineProperty(exports, "WORKFLOW_NODE_ID_PATTERN", { enumerable: true, get: function () { return catalog_pipeline_1.WORKFLOW_NODE_ID_PATTERN; } });
@@ -83,7 +87,14 @@ Object.defineProperty(exports, "workflowRunOrder", { enumerable: true, get: func
83
87
  __exportStar(require("./catalog.environment"), exports);
84
88
  var catalog_query_cache_1 = require("./catalog.query-cache");
85
89
  Object.defineProperty(exports, "QueryCache", { enumerable: true, get: function () { return catalog_query_cache_1.QueryCache; } });
86
- Object.defineProperty(exports, "toCsv", { enumerable: true, get: function () { return catalog_query_cache_1.toCsv; } });
90
+ // CSV. `toCsv` is the shape it always was; `csvLines` is the one the export
91
+ // route uses, and `guardFormula` is exported because a host writing its own
92
+ // export route needs the escaping and not the framing.
93
+ var catalog_csv_1 = require("./catalog.csv");
94
+ Object.defineProperty(exports, "csvCell", { enumerable: true, get: function () { return catalog_csv_1.csvCell; } });
95
+ Object.defineProperty(exports, "csvLines", { enumerable: true, get: function () { return catalog_csv_1.csvLines; } });
96
+ Object.defineProperty(exports, "guardFormula", { enumerable: true, get: function () { return catalog_csv_1.guardFormula; } });
97
+ Object.defineProperty(exports, "toCsv", { enumerable: true, get: function () { return catalog_csv_1.toCsv; } });
87
98
  var transform_runner_1 = require("./transform-runner");
88
99
  Object.defineProperty(exports, "SubprocessTransformRunner", { enumerable: true, get: function () { return transform_runner_1.SubprocessTransformRunner; } });
89
100
  var catalog_service_1 = require("./catalog.service");
@@ -132,6 +143,13 @@ Object.defineProperty(exports, "StaticKeyPrincipalResolver", { enumerable: true,
132
143
  // implemented only by a host willing to restate them — which nothing in this
133
144
  // repo would have caught: no consumer compiles against the built barrel here.
134
145
  __exportStar(require("./catalog.access"), exports);
146
+ // The filter rule, whole. A store implementing `CatalogFilteringReadStore` needs
147
+ // the operator list to declare what it applies and `CatalogResolvedFilter` to
148
+ // read what it was handed, and a host writing its own objects route needs
149
+ // `resolveObjectFilters` — shipping the interface without them would be the same
150
+ // unimplementable seam the barrel spec above was written after. It is also on
151
+ // `/client`, because the console derives its controls from the same function.
152
+ __exportStar(require("./catalog.filters"), exports);
135
153
  var catalog_store_1 = require("./catalog.store");
136
154
  Object.defineProperty(exports, "assertNoColumnCollisions", { enumerable: true, get: function () { return catalog_store_1.assertNoColumnCollisions; } });
137
155
  Object.defineProperty(exports, "assertSafeIdentifier", { enumerable: true, get: function () { return catalog_store_1.assertSafeIdentifier; } });
@@ -139,11 +157,14 @@ Object.defineProperty(exports, "CATALOG_RESERVED_COLUMNS", { enumerable: true, g
139
157
  Object.defineProperty(exports, "CATALOG_SNAPSHOT_MODES", { enumerable: true, get: function () { return catalog_store_1.CATALOG_SNAPSHOT_MODES; } });
140
158
  Object.defineProperty(exports, "CATALOG_STORE", { enumerable: true, get: function () { return catalog_store_1.CATALOG_STORE; } });
141
159
  Object.defineProperty(exports, "CatalogColumnCollisionError", { enumerable: true, get: function () { return catalog_store_1.CatalogColumnCollisionError; } });
160
+ Object.defineProperty(exports, "supportsObjectFilters", { enumerable: true, get: function () { return catalog_store_1.supportsObjectFilters; } });
142
161
  Object.defineProperty(exports, "findColumnCollisions", { enumerable: true, get: function () { return catalog_store_1.findColumnCollisions; } });
143
162
  Object.defineProperty(exports, "isCatalogStoreCapabilities", { enumerable: true, get: function () { return catalog_store_1.isCatalogStoreCapabilities; } });
144
163
  Object.defineProperty(exports, "isReservedColumn", { enumerable: true, get: function () { return catalog_store_1.isReservedColumn; } });
145
164
  Object.defineProperty(exports, "isSafeIdentifier", { enumerable: true, get: function () { return catalog_store_1.isSafeIdentifier; } });
146
165
  Object.defineProperty(exports, "isWriteStore", { enumerable: true, get: function () { return catalog_store_1.isWriteStore; } });
166
+ Object.defineProperty(exports, "outputAlias", { enumerable: true, get: function () { return catalog_store_1.outputAlias; } });
167
+ Object.defineProperty(exports, "physicalColumn", { enumerable: true, get: function () { return catalog_store_1.physicalColumn; } });
147
168
  Object.defineProperty(exports, "supportsCarryForward", { enumerable: true, get: function () { return catalog_store_1.supportsCarryForward; } });
148
169
  Object.defineProperty(exports, "UnsafeIdentifierError", { enumerable: true, get: function () { return catalog_store_1.UnsafeIdentifierError; } });
149
170
  var mikro_orm_read_store_1 = require("./stores/mikro-orm-read.store");
@@ -1,6 +1,6 @@
1
1
  import { EntityManager } from '@mikro-orm/core';
2
2
  import { MikroOrmCatalogRegistry } from '../catalog.registry';
3
- import type { CatalogReadQuery, CatalogReadResult, CatalogReadStore, CatalogStoreCapabilities } from '../catalog.store';
3
+ import type { CatalogFilteringReadStore, CatalogReadQuery, CatalogReadResult, CatalogStoreCapabilities } from '../catalog.store';
4
4
  import type { CatalogObjectTypeDef } from '../catalog.types';
5
5
  /**
6
6
  * Reads objects straight out of the application's own tables, through the ORM
@@ -11,10 +11,16 @@ import type { CatalogObjectTypeDef } from '../catalog.types';
11
11
  * trade is that there is also no history — the tables hold current state, and
12
12
  * nothing here can show you last Tuesday.
13
13
  */
14
- export declare class MikroOrmReadStore implements CatalogReadStore {
14
+ export declare class MikroOrmReadStore implements CatalogFilteringReadStore {
15
15
  private readonly registry;
16
16
  private readonly em;
17
17
  readonly capabilities: CatalogStoreCapabilities;
18
+ /**
19
+ * All of them: every operator maps onto a MikroORM query-builder operator, and
20
+ * the ORM writes the column name from the entity metadata rather than from
21
+ * anything a caller sent.
22
+ */
23
+ readonly objectFilterOperators: readonly ["eq", "ne", "contains", "gte", "lte", "gt", "lt", "empty", "notEmpty"];
18
24
  constructor(registry: MikroOrmCatalogRegistry, em: EntityManager);
19
25
  read(type: CatalogObjectTypeDef, fields: string[], query: CatalogReadQuery): Promise<CatalogReadResult>;
20
26
  }
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.MikroOrmReadStore = void 0;
13
13
  const core_1 = require("@mikro-orm/core");
14
14
  const common_1 = require("@nestjs/common");
15
+ const catalog_filters_1 = require("../catalog.filters");
15
16
  const catalog_registry_1 = require("../catalog.registry");
16
17
  /**
17
18
  * Reads objects straight out of the application's own tables, through the ORM
@@ -30,6 +31,12 @@ let MikroOrmReadStore = class MikroOrmReadStore {
30
31
  writable: false,
31
32
  timeTravel: false,
32
33
  };
34
+ /**
35
+ * All of them: every operator maps onto a MikroORM query-builder operator, and
36
+ * the ORM writes the column name from the entity metadata rather than from
37
+ * anything a caller sent.
38
+ */
39
+ objectFilterOperators = catalog_filters_1.CATALOG_FILTER_OPERATORS;
33
40
  constructor(registry, em) {
34
41
  this.registry = registry;
35
42
  this.em = em;
@@ -48,7 +55,7 @@ let MikroOrmReadStore = class MikroOrmReadStore {
48
55
  // No explicit type arguments: `findAndCount` declares `Fields extends string
49
56
  // = never`, so naming even one generic makes the rest fall back to their
50
57
  // defaults and types `fields` as `never[]`. Inference gets it right.
51
- const [rows, total] = await em.findAndCount(entityClass, buildWhere(type, query.search), {
58
+ const [rows, total] = await em.findAndCount(entityClass, buildWhere(type, query), {
52
59
  limit: size,
53
60
  offset: (page - 1) * size,
54
61
  orderBy: buildOrderBy(type, query.sort, query.dir),
@@ -67,19 +74,78 @@ exports.MikroOrmReadStore = MikroOrmReadStore = __decorate([
67
74
  core_1.EntityManager])
68
75
  ], MikroOrmReadStore);
69
76
  /**
70
- * Only string columns the catalog says are visible.
77
+ * The search term and the column filters, ANDed.
71
78
  *
72
- * A search that reached a classified column would leak it through row
73
- * membership even though the value is never rendered.
79
+ * Search reaches only string columns the catalog says are visible: a search that
80
+ * reached a classified column would leak it through row membership even though
81
+ * the value is never rendered. `filterOperatorsFor` refuses a classified column
82
+ * for the same reason and a sharper one — a range filter lets a reader
83
+ * binary-search a value they may not see.
84
+ *
85
+ * The filters are ANDed with each other and with the search, which is what makes
86
+ * a filter narrowing: two conditions on one column express a range, and a caller
87
+ * that wanted alternatives has `contains` or a second request.
74
88
  */
75
- function buildWhere(type, search) {
76
- const term = search?.trim();
77
- if (!term)
78
- return {};
79
- const searchable = type.properties.filter((p) => !p.hidden && p.type === 'string' && !p.classification);
80
- if (searchable.length === 0)
89
+ function buildWhere(type, query) {
90
+ const conditions = [];
91
+ const term = query.search?.trim();
92
+ if (term) {
93
+ const searchable = type.properties.filter((p) => !p.hidden && p.type === 'string' && !p.classification);
94
+ if (searchable.length > 0) {
95
+ conditions.push({ $or: searchable.map((p) => ({ [p.name]: { $like: `%${term}%` } })) });
96
+ }
97
+ }
98
+ for (const filter of query.filters ?? []) {
99
+ conditions.push({ [filter.property.name]: comparison(filter) });
100
+ }
101
+ if (conditions.length === 0)
81
102
  return {};
82
- return { $or: searchable.map((p) => ({ [p.name]: { $like: `%${term}%` } })) };
103
+ if (conditions.length === 1)
104
+ return conditions[0];
105
+ return { $and: conditions };
106
+ }
107
+ /**
108
+ * One operator as MikroORM spells it.
109
+ *
110
+ * The property name is the ORM's own — it came off the type, which was built
111
+ * from the entity metadata — so the column in the emitted SQL is written by the
112
+ * ORM from that metadata and never by string concatenation here. That is the same
113
+ * guarantee the sort above relies on.
114
+ */
115
+ function comparison(filter) {
116
+ const value = filter.value;
117
+ switch (filter.op) {
118
+ case 'eq':
119
+ return { $eq: value };
120
+ case 'ne':
121
+ // `!=` in SQL is never true of NULL, so a row whose column is empty would
122
+ // drop out of "is not X" — which reads as those rows having the value.
123
+ return { $or: [{ $ne: value }, { $eq: null }] };
124
+ case 'contains':
125
+ return { $like: `%${String(value)}%` };
126
+ case 'gt':
127
+ return { $gt: value };
128
+ case 'gte':
129
+ return { $gte: value };
130
+ case 'lt':
131
+ return { $lt: value };
132
+ case 'lte':
133
+ return { $lte: value };
134
+ case 'empty':
135
+ // A blank string is empty to a reader, and only a text column can hold
136
+ // one. Both spellings, so "no value" means what it says on either.
137
+ return { $or: [{ $eq: null }, { $eq: '' }] };
138
+ case 'notEmpty':
139
+ return { $and: [{ $ne: null }, { $ne: '' }] };
140
+ default:
141
+ // No operator falls through to a silent `{}`, which would be a filter
142
+ // that matches everything. An operator added to the contract and not to
143
+ // this switch fails to compile here rather than at read time.
144
+ return unknownOperator(filter.op);
145
+ }
146
+ }
147
+ function unknownOperator(operator) {
148
+ throw new common_1.BadRequestException(`This store cannot filter with ${String(operator)}.`);
83
149
  }
84
150
  /** Only ever a column the catalog vouched for; falls back to the key. */
85
151
  function buildOrderBy(type, sort, dir) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dudousxd/nestjs-catalog",
3
- "version": "0.13.0",
3
+ "version": "0.15.0",
4
4
  "description": "A metadata registry for NestJS: object types, properties and relations, derived from your ORM and enriched with decorators.",
5
5
  "license": "MIT",
6
6
  "author": "Davide Carvalho",