grafeo-ogm 2.4.7 → 2.5.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/CHANGELOG.md +126 -0
- package/README.md +95 -35
- package/dist/cjs/cli/commands/db-push.d.ts.map +1 -1
- package/dist/cjs/cli/commands/db-push.js +74 -8
- package/dist/cjs/cli/commands/db-push.js.map +1 -1
- package/dist/cjs/cli/commands/db-seed.d.ts.map +1 -1
- package/dist/cjs/cli/commands/db-seed.js +10 -1
- package/dist/cjs/cli/commands/db-seed.js.map +1 -1
- package/dist/cjs/cli/introspect.d.ts +2 -2
- package/dist/cjs/cli/introspect.d.ts.map +1 -1
- package/dist/cjs/cli/introspect.js +44 -2
- package/dist/cjs/cli/introspect.js.map +1 -1
- package/dist/cjs/cli/push-planner.d.ts +57 -2
- package/dist/cjs/cli/push-planner.d.ts.map +1 -1
- package/dist/cjs/cli/push-planner.js +161 -3
- package/dist/cjs/cli/push-planner.js.map +1 -1
- package/dist/cjs/compilers/fulltext.compiler.d.ts.map +1 -1
- package/dist/cjs/compilers/fulltext.compiler.js +5 -1
- package/dist/cjs/compilers/fulltext.compiler.js.map +1 -1
- package/dist/cjs/compilers/mutation.compiler.d.ts +107 -1
- package/dist/cjs/compilers/mutation.compiler.d.ts.map +1 -1
- package/dist/cjs/compilers/mutation.compiler.js +695 -422
- package/dist/cjs/compilers/mutation.compiler.js.map +1 -1
- package/dist/cjs/compilers/select-normalizer.d.ts.map +1 -1
- package/dist/cjs/compilers/select-normalizer.js +12 -1
- package/dist/cjs/compilers/select-normalizer.js.map +1 -1
- package/dist/cjs/compilers/selection.compiler.d.ts +56 -0
- package/dist/cjs/compilers/selection.compiler.d.ts.map +1 -1
- package/dist/cjs/compilers/selection.compiler.js +271 -29
- package/dist/cjs/compilers/selection.compiler.js.map +1 -1
- package/dist/cjs/compilers/where.compiler.d.ts.map +1 -1
- package/dist/cjs/compilers/where.compiler.js +36 -15
- package/dist/cjs/compilers/where.compiler.js.map +1 -1
- package/dist/cjs/execution/executor.d.ts +34 -9
- package/dist/cjs/execution/executor.d.ts.map +1 -1
- package/dist/cjs/execution/executor.js +42 -5
- package/dist/cjs/execution/executor.js.map +1 -1
- package/dist/cjs/execution/result-mapper.d.ts.map +1 -1
- package/dist/cjs/execution/result-mapper.js +4 -2
- package/dist/cjs/execution/result-mapper.js.map +1 -1
- package/dist/cjs/generator/generate-types.d.ts.map +1 -1
- package/dist/cjs/generator/generate-types.js +76 -0
- package/dist/cjs/generator/generate-types.js.map +1 -1
- package/dist/cjs/generator/type-emitters/aggregation-emitter.d.ts.map +1 -1
- package/dist/cjs/generator/type-emitters/aggregation-emitter.js +19 -7
- package/dist/cjs/generator/type-emitters/aggregation-emitter.js.map +1 -1
- package/dist/cjs/generator/type-emitters/input-emitter.js +13 -4
- package/dist/cjs/generator/type-emitters/input-emitter.js.map +1 -1
- package/dist/cjs/generator/type-emitters/model-map-emitter.d.ts +1 -0
- package/dist/cjs/generator/type-emitters/model-map-emitter.d.ts.map +1 -1
- package/dist/cjs/generator/type-emitters/model-map-emitter.js +5 -20
- package/dist/cjs/generator/type-emitters/model-map-emitter.js.map +1 -1
- package/dist/cjs/generator/type-emitters/node-type-emitter.d.ts +3 -0
- package/dist/cjs/generator/type-emitters/node-type-emitter.d.ts.map +1 -1
- package/dist/cjs/generator/type-emitters/node-type-emitter.js +6 -11
- package/dist/cjs/generator/type-emitters/node-type-emitter.js.map +1 -1
- package/dist/cjs/generator/type-emitters/select-fields-emitter.js +21 -2
- package/dist/cjs/generator/type-emitters/select-fields-emitter.js.map +1 -1
- package/dist/cjs/generator/type-emitters/where-emitter.js +19 -3
- package/dist/cjs/generator/type-emitters/where-emitter.js.map +1 -1
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/interface-model.d.ts +12 -0
- package/dist/cjs/interface-model.d.ts.map +1 -1
- package/dist/cjs/interface-model.js +27 -13
- package/dist/cjs/interface-model.js.map +1 -1
- package/dist/cjs/model.d.ts.map +1 -1
- package/dist/cjs/model.js +12 -0
- package/dist/cjs/model.js.map +1 -1
- package/dist/cjs/ogm.d.ts +22 -2
- package/dist/cjs/ogm.d.ts.map +1 -1
- package/dist/cjs/ogm.js +42 -5
- package/dist/cjs/ogm.js.map +1 -1
- package/dist/cjs/policy/nested-writes.d.ts.map +1 -1
- package/dist/cjs/policy/nested-writes.js +40 -20
- package/dist/cjs/policy/nested-writes.js.map +1 -1
- package/dist/cjs/schema/parser.d.ts.map +1 -1
- package/dist/cjs/schema/parser.js +94 -16
- package/dist/cjs/schema/parser.js.map +1 -1
- package/dist/cjs/schema/types.d.ts +1 -1
- package/dist/cjs/schema/types.d.ts.map +1 -1
- package/dist/cjs/subgraph/subgraph-operations.d.ts.map +1 -1
- package/dist/cjs/subgraph/subgraph-operations.js +71 -6
- package/dist/cjs/subgraph/subgraph-operations.js.map +1 -1
- package/dist/cjs/subgraph/types.d.ts +14 -0
- package/dist/cjs/subgraph/types.d.ts.map +1 -1
- package/dist/cjs/testing/cypher-assert.d.ts +19 -1
- package/dist/cjs/testing/cypher-assert.d.ts.map +1 -1
- package/dist/cjs/testing/cypher-assert.js +217 -13
- package/dist/cjs/testing/cypher-assert.js.map +1 -1
- package/dist/cjs/testing/neo4j-record-factory.d.ts +29 -2
- package/dist/cjs/testing/neo4j-record-factory.d.ts.map +1 -1
- package/dist/cjs/testing/neo4j-record-factory.js +93 -3
- package/dist/cjs/testing/neo4j-record-factory.js.map +1 -1
- package/dist/cjs/utils/cypher-field-projection.d.ts +31 -3
- package/dist/cjs/utils/cypher-field-projection.d.ts.map +1 -1
- package/dist/cjs/utils/cypher-field-projection.js +59 -7
- package/dist/cjs/utils/cypher-field-projection.js.map +1 -1
- package/dist/cjs/utils/write-coercion.d.ts +18 -0
- package/dist/cjs/utils/write-coercion.d.ts.map +1 -1
- package/dist/cjs/utils/write-coercion.js +74 -1
- package/dist/cjs/utils/write-coercion.js.map +1 -1
- package/dist/esm/cli/commands/db-push.d.ts.map +1 -1
- package/dist/esm/cli/commands/db-push.js +74 -8
- package/dist/esm/cli/commands/db-push.js.map +1 -1
- package/dist/esm/cli/commands/db-seed.d.ts.map +1 -1
- package/dist/esm/cli/commands/db-seed.js +10 -1
- package/dist/esm/cli/commands/db-seed.js.map +1 -1
- package/dist/esm/cli/introspect.d.ts +2 -2
- package/dist/esm/cli/introspect.d.ts.map +1 -1
- package/dist/esm/cli/introspect.js +44 -2
- package/dist/esm/cli/introspect.js.map +1 -1
- package/dist/esm/cli/push-planner.d.ts +57 -2
- package/dist/esm/cli/push-planner.d.ts.map +1 -1
- package/dist/esm/cli/push-planner.js +162 -4
- package/dist/esm/cli/push-planner.js.map +1 -1
- package/dist/esm/compilers/fulltext.compiler.d.ts.map +1 -1
- package/dist/esm/compilers/fulltext.compiler.js +5 -1
- package/dist/esm/compilers/fulltext.compiler.js.map +1 -1
- package/dist/esm/compilers/mutation.compiler.d.ts +107 -1
- package/dist/esm/compilers/mutation.compiler.d.ts.map +1 -1
- package/dist/esm/compilers/mutation.compiler.js +692 -422
- package/dist/esm/compilers/mutation.compiler.js.map +1 -1
- package/dist/esm/compilers/select-normalizer.d.ts.map +1 -1
- package/dist/esm/compilers/select-normalizer.js +12 -1
- package/dist/esm/compilers/select-normalizer.js.map +1 -1
- package/dist/esm/compilers/selection.compiler.d.ts +56 -0
- package/dist/esm/compilers/selection.compiler.d.ts.map +1 -1
- package/dist/esm/compilers/selection.compiler.js +273 -31
- package/dist/esm/compilers/selection.compiler.js.map +1 -1
- package/dist/esm/compilers/where.compiler.d.ts.map +1 -1
- package/dist/esm/compilers/where.compiler.js +37 -16
- package/dist/esm/compilers/where.compiler.js.map +1 -1
- package/dist/esm/execution/executor.d.ts +34 -9
- package/dist/esm/execution/executor.d.ts.map +1 -1
- package/dist/esm/execution/executor.js +41 -5
- package/dist/esm/execution/executor.js.map +1 -1
- package/dist/esm/execution/result-mapper.d.ts.map +1 -1
- package/dist/esm/execution/result-mapper.js +4 -2
- package/dist/esm/execution/result-mapper.js.map +1 -1
- package/dist/esm/generator/generate-types.d.ts.map +1 -1
- package/dist/esm/generator/generate-types.js +76 -0
- package/dist/esm/generator/generate-types.js.map +1 -1
- package/dist/esm/generator/type-emitters/aggregation-emitter.d.ts.map +1 -1
- package/dist/esm/generator/type-emitters/aggregation-emitter.js +19 -7
- package/dist/esm/generator/type-emitters/aggregation-emitter.js.map +1 -1
- package/dist/esm/generator/type-emitters/input-emitter.js +13 -4
- package/dist/esm/generator/type-emitters/input-emitter.js.map +1 -1
- package/dist/esm/generator/type-emitters/model-map-emitter.d.ts +1 -0
- package/dist/esm/generator/type-emitters/model-map-emitter.d.ts.map +1 -1
- package/dist/esm/generator/type-emitters/model-map-emitter.js +5 -20
- package/dist/esm/generator/type-emitters/model-map-emitter.js.map +1 -1
- package/dist/esm/generator/type-emitters/node-type-emitter.d.ts +3 -0
- package/dist/esm/generator/type-emitters/node-type-emitter.d.ts.map +1 -1
- package/dist/esm/generator/type-emitters/node-type-emitter.js +6 -11
- package/dist/esm/generator/type-emitters/node-type-emitter.js.map +1 -1
- package/dist/esm/generator/type-emitters/select-fields-emitter.js +21 -2
- package/dist/esm/generator/type-emitters/select-fields-emitter.js.map +1 -1
- package/dist/esm/generator/type-emitters/where-emitter.js +19 -3
- package/dist/esm/generator/type-emitters/where-emitter.js.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/interface-model.d.ts +12 -0
- package/dist/esm/interface-model.d.ts.map +1 -1
- package/dist/esm/interface-model.js +27 -13
- package/dist/esm/interface-model.js.map +1 -1
- package/dist/esm/model.d.ts.map +1 -1
- package/dist/esm/model.js +12 -0
- package/dist/esm/model.js.map +1 -1
- package/dist/esm/ogm.d.ts +22 -2
- package/dist/esm/ogm.d.ts.map +1 -1
- package/dist/esm/ogm.js +43 -6
- package/dist/esm/ogm.js.map +1 -1
- package/dist/esm/policy/nested-writes.d.ts.map +1 -1
- package/dist/esm/policy/nested-writes.js +40 -20
- package/dist/esm/policy/nested-writes.js.map +1 -1
- package/dist/esm/schema/parser.d.ts.map +1 -1
- package/dist/esm/schema/parser.js +94 -16
- package/dist/esm/schema/parser.js.map +1 -1
- package/dist/esm/schema/types.d.ts +1 -1
- package/dist/esm/schema/types.d.ts.map +1 -1
- package/dist/esm/subgraph/subgraph-operations.d.ts.map +1 -1
- package/dist/esm/subgraph/subgraph-operations.js +71 -6
- package/dist/esm/subgraph/subgraph-operations.js.map +1 -1
- package/dist/esm/subgraph/types.d.ts +14 -0
- package/dist/esm/subgraph/types.d.ts.map +1 -1
- package/dist/esm/testing/cypher-assert.d.ts +19 -1
- package/dist/esm/testing/cypher-assert.d.ts.map +1 -1
- package/dist/esm/testing/cypher-assert.js +217 -13
- package/dist/esm/testing/cypher-assert.js.map +1 -1
- package/dist/esm/testing/neo4j-record-factory.d.ts +29 -2
- package/dist/esm/testing/neo4j-record-factory.d.ts.map +1 -1
- package/dist/esm/testing/neo4j-record-factory.js +93 -3
- package/dist/esm/testing/neo4j-record-factory.js.map +1 -1
- package/dist/esm/utils/cypher-field-projection.d.ts +31 -3
- package/dist/esm/utils/cypher-field-projection.d.ts.map +1 -1
- package/dist/esm/utils/cypher-field-projection.js +58 -7
- package/dist/esm/utils/cypher-field-projection.js.map +1 -1
- package/dist/esm/utils/write-coercion.d.ts +18 -0
- package/dist/esm/utils/write-coercion.d.ts.map +1 -1
- package/dist/esm/utils/write-coercion.js +73 -1
- package/dist/esm/utils/write-coercion.js.map +1 -1
- package/package.json +1 -1
|
@@ -6,6 +6,48 @@ const errors_1 = require("../errors");
|
|
|
6
6
|
const validation_1 = require("../utils/validation");
|
|
7
7
|
/** No-op logger used when no logger is provided. */
|
|
8
8
|
const NOOP_LOGGER = { debug: () => { } };
|
|
9
|
+
/**
|
|
10
|
+
* An owned relationship entry: a type with an optional APOC direction
|
|
11
|
+
* marker. APOC parses the joined relationshipFilter itself, so nothing
|
|
12
|
+
* outside this shape (e.g. a `|` smuggling in another type) may pass.
|
|
13
|
+
*/
|
|
14
|
+
const OWNED_RELATIONSHIP = /^<?[A-Za-z_][A-Za-z0-9_]*>?$/;
|
|
15
|
+
/**
|
|
16
|
+
* The APOC relationshipFilter for the owned relationships. A bare type is
|
|
17
|
+
* traversed OUTGOING (`TYPE>`); `<TYPE` is incoming and `<TYPE>` is both.
|
|
18
|
+
*
|
|
19
|
+
* Before v2.5.0 bare types were passed as-is, and APOC expands a bare type
|
|
20
|
+
* in BOTH directions: from a Chapter shared by two Books, deleting Book A
|
|
21
|
+
* climbed back up to Book B and deleted it too, and deleting a Chapter
|
|
22
|
+
* deleted its parent Book.
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* The escaped label the root is matched with: `rootLabel`, else the first
|
|
26
|
+
* owned label (v2.5.0). Called after validateConfig, which checked both.
|
|
27
|
+
*/
|
|
28
|
+
function rootLabelOf(config) {
|
|
29
|
+
return (0, validation_1.assertSafeLabel)(config.rootLabel ?? config.ownedLabels[0]);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Message of the apoc.util.validate guards in the clone query, without the
|
|
33
|
+
* `Failed to invoke procedure … java.lang.RuntimeException:` wrapper.
|
|
34
|
+
*/
|
|
35
|
+
const CLONE_GUARD_MESSAGE = /cloneSubgraph: (\d+ owned node\(s\) [^\n]*)/;
|
|
36
|
+
function ownedRelationshipFilter(config) {
|
|
37
|
+
return config.ownedRelationships
|
|
38
|
+
.map((rel) => {
|
|
39
|
+
const incoming = rel.startsWith('<');
|
|
40
|
+
const outgoing = rel.endsWith('>');
|
|
41
|
+
// APOC reads `<TYPE>` as incoming only (checked on APOC 5.26), so
|
|
42
|
+
// "both" is sent as the bare type, which APOC expands both ways.
|
|
43
|
+
if (incoming && outgoing)
|
|
44
|
+
return rel.slice(1, -1);
|
|
45
|
+
if (incoming || outgoing)
|
|
46
|
+
return rel;
|
|
47
|
+
return `${rel}>`;
|
|
48
|
+
})
|
|
49
|
+
.join('|');
|
|
50
|
+
}
|
|
9
51
|
/**
|
|
10
52
|
* Validates all labels and relationship types in a SubgraphConfig
|
|
11
53
|
* to prevent Cypher injection (these values are string-interpolated),
|
|
@@ -29,8 +71,12 @@ function validateConfig(config, operation, rootId) {
|
|
|
29
71
|
'would traverse every relationship reachable from the root.');
|
|
30
72
|
for (const label of config.ownedLabels)
|
|
31
73
|
(0, validation_1.assertSafeLabel)(label);
|
|
74
|
+
if (config.rootLabel !== undefined)
|
|
75
|
+
(0, validation_1.assertSafeLabel)(config.rootLabel);
|
|
32
76
|
for (const rel of config.ownedRelationships)
|
|
33
|
-
(
|
|
77
|
+
if (!OWNED_RELATIONSHIP.test(rel))
|
|
78
|
+
throw new errors_1.SubgraphOperationError(operation, rootId, `Invalid owned relationship "${rel}": expected TYPE, TYPE>, <TYPE ` +
|
|
79
|
+
'or <TYPE> where TYPE matches [A-Za-z_][A-Za-z0-9_]*');
|
|
34
80
|
for (const ref of config.referenceRelationships) {
|
|
35
81
|
(0, validation_1.assertSafeLabel)(ref.fromLabel);
|
|
36
82
|
(0, validation_1.assertSafeIdentifier)(ref.relationshipType, 'reference relationship type');
|
|
@@ -67,7 +113,8 @@ async function cloneSubgraph(sourceRootId, config, transaction, logger) {
|
|
|
67
113
|
catch (error) {
|
|
68
114
|
if (error instanceof errors_1.SubgraphOperationError)
|
|
69
115
|
throw error;
|
|
70
|
-
|
|
116
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
117
|
+
throw new errors_1.SubgraphOperationError('clone', sourceRootId, CLONE_GUARD_MESSAGE.exec(message)?.[1] ?? message, error instanceof Error ? error : undefined);
|
|
71
118
|
}
|
|
72
119
|
}
|
|
73
120
|
/**
|
|
@@ -85,11 +132,12 @@ async function cloneSubgraph(sourceRootId, config, transaction, logger) {
|
|
|
85
132
|
async function deleteSubgraph(rootId, config, transaction, logger) {
|
|
86
133
|
const log = logger ?? NOOP_LOGGER;
|
|
87
134
|
validateConfig(config, 'delete', rootId);
|
|
88
|
-
const relFilter = config
|
|
135
|
+
const relFilter = ownedRelationshipFilter(config);
|
|
89
136
|
const labelFilter = config.ownedLabels.map((l) => `+${l}`).join('|');
|
|
137
|
+
const rootLabel = rootLabelOf(config);
|
|
90
138
|
try {
|
|
91
139
|
const result = await transaction.run(`
|
|
92
|
-
MATCH (source {id: $rootId})
|
|
140
|
+
MATCH (source:${rootLabel} {id: $rootId})
|
|
93
141
|
CALL apoc.path.subgraphAll(source, {
|
|
94
142
|
relationshipFilter: $relFilter,
|
|
95
143
|
labelFilter: $labelFilter,
|
|
@@ -120,19 +168,36 @@ async function deleteSubgraph(rootId, config, transaction, logger) {
|
|
|
120
168
|
* Executes the APOC subgraph clone and generates new UUIDs for cloned nodes.
|
|
121
169
|
*/
|
|
122
170
|
async function executeApocClone(sourceRootId, config, transaction, logger) {
|
|
123
|
-
const relFilter = config
|
|
171
|
+
const relFilter = ownedRelationshipFilter(config);
|
|
124
172
|
const labelFilter = config.ownedLabels.map((l) => `+${l}`).join('|');
|
|
173
|
+
const rootLabel = rootLabelOf(config);
|
|
125
174
|
// Step 1: Collect subgraph and clone it
|
|
126
175
|
// APOC cloneSubgraph returns: input=INTEGER (original internal ID), output=NODE (clone).
|
|
127
176
|
// skipProperties: ['id'] avoids unique constraint violations during clone.
|
|
128
177
|
// We use `input` (internal ID) to match back to the original's app-level id.
|
|
178
|
+
//
|
|
179
|
+
// v2.5.0 — nodeMapping is keyed by the original's `id`, so an owned node
|
|
180
|
+
// with no id (or one sharing an id with another owned node) cannot be
|
|
181
|
+
// mapped: before v2.5.0 they collapsed onto one key, and only one of them
|
|
182
|
+
// got a new UUID. The apoc.util.validate guards abort before anything is
|
|
183
|
+
// cloned.
|
|
129
184
|
const result = await transaction.run(`
|
|
130
|
-
MATCH (source {id: $sourceId})
|
|
185
|
+
MATCH (source:${rootLabel} {id: $sourceId})
|
|
131
186
|
CALL apoc.path.subgraphAll(source, {
|
|
132
187
|
relationshipFilter: $relFilter,
|
|
133
188
|
labelFilter: $labelFilter,
|
|
134
189
|
maxLevel: $maxLevel
|
|
135
190
|
}) YIELD nodes, relationships
|
|
191
|
+
WITH nodes, relationships, [n IN nodes WHERE n.id IS NOT NULL | n.id] AS ids
|
|
192
|
+
WITH nodes, relationships,
|
|
193
|
+
size(nodes) - size(ids) AS missingIds,
|
|
194
|
+
size(ids) - size(apoc.coll.toSet(ids)) AS duplicateIds
|
|
195
|
+
CALL apoc.util.validate(missingIds > 0,
|
|
196
|
+
'cloneSubgraph: %d owned node(s) have no \`id\`; every owned node needs a unique \`id\` to be mapped to its clone',
|
|
197
|
+
[missingIds])
|
|
198
|
+
CALL apoc.util.validate(duplicateIds > 0,
|
|
199
|
+
'cloneSubgraph: %d owned node(s) share an \`id\` with another owned node; every owned node needs a unique \`id\` to be mapped to its clone',
|
|
200
|
+
[duplicateIds])
|
|
136
201
|
CALL apoc.refactor.cloneSubgraph(nodes, relationships, {skipProperties: ['id']})
|
|
137
202
|
YIELD input, output, error
|
|
138
203
|
WHERE output IS NOT NULL
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subgraph-operations.js","sourceRoot":"","sources":["../../../src/subgraph/subgraph-operations.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"subgraph-operations.js","sourceRoot":"","sources":["../../../src/subgraph/subgraph-operations.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,20 @@ export interface SubgraphReferenceRelationship {
|
|
|
7
7
|
/** Configuration for clone/delete operations — domain-agnostic blueprint. */
|
|
8
8
|
export interface SubgraphConfig {
|
|
9
9
|
ownedLabels: string[];
|
|
10
|
+
/**
|
|
11
|
+
* Label the root node must carry; defaults to `ownedLabels[0]` (v2.5.0).
|
|
12
|
+
* The root is matched as `(:rootLabel {id})`. Before v2.5.0 it was
|
|
13
|
+
* matched by `id` alone, so a node of any label with that id became a
|
|
14
|
+
* root, and the lookup scanned every node.
|
|
15
|
+
*/
|
|
16
|
+
rootLabel?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Relationship types the traversal follows from the root. A bare
|
|
19
|
+
* `'TYPE'` is followed OUTGOING only; write `'<TYPE'` for incoming and
|
|
20
|
+
* `'<TYPE>'` for both directions (v2.5.0). Before v2.5.0 a bare type was
|
|
21
|
+
* followed both ways, so the traversal could climb from a shared child
|
|
22
|
+
* up to another parent and take it in too.
|
|
23
|
+
*/
|
|
10
24
|
ownedRelationships: string[];
|
|
11
25
|
maxLevel: number;
|
|
12
26
|
referenceRelationships: SubgraphReferenceRelationship[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/subgraph/types.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,MAAM,WAAW,6BAA6B;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,KAAK,GAAG,IAAI,CAAC;CACzB;AAED,6EAA6E;AAC7E,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,sBAAsB,EAAE,6BAA6B,EAAE,CAAC;CACzD;AAED,oBAAoB;AACpB,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;;;;OAKG;IACH,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACrC;AAED,qBAAqB;AACrB,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAC;CACtB"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/subgraph/types.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,MAAM,WAAW,6BAA6B;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,KAAK,GAAG,IAAI,CAAC;CACzB;AAED,6EAA6E;AAC7E,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,sBAAsB,EAAE,6BAA6B,EAAE,CAAC;CACzD;AAED,oBAAoB;AACpB,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;;;;OAKG;IACH,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACrC;AAED,qBAAqB;AACrB,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAC;CACtB"}
|
|
@@ -8,6 +8,11 @@ export declare class CypherAssert {
|
|
|
8
8
|
* - Collapse all whitespace sequences to a single space
|
|
9
9
|
* - Trim leading/trailing whitespace
|
|
10
10
|
* - Rename params to canonical $p0, $p1, etc. (in order of appearance)
|
|
11
|
+
*
|
|
12
|
+
* String literals and backticked names are kept verbatim (v2.5.0): their
|
|
13
|
+
* whitespace is part of the value, and a `$name` inside a string is text,
|
|
14
|
+
* not a parameter. Before v2.5.0 both were collapsed and renamed, so
|
|
15
|
+
* `'a b'` equalled `'a b'`.
|
|
11
16
|
*/
|
|
12
17
|
static normalize(cypher: string): string;
|
|
13
18
|
/**
|
|
@@ -16,7 +21,20 @@ export declare class CypherAssert {
|
|
|
16
21
|
*/
|
|
17
22
|
static assertStructurallyEqual(actual: string, expected: string): void;
|
|
18
23
|
/**
|
|
19
|
-
* Assert that a Cypher string contains a
|
|
24
|
+
* Assert that a Cypher string contains a clause, and that `pattern`
|
|
25
|
+
* appears inside that clause.
|
|
26
|
+
*
|
|
27
|
+
* The clause keyword is matched case-insensitively as a whole word (or
|
|
28
|
+
* words, e.g. 'ORDER BY', 'ON CREATE SET'), never inside a name, a
|
|
29
|
+
* parameter, a string or a comment. A clause runs from its keyword to the
|
|
30
|
+
* next clause keyword at the same bracket depth (WHERE, ORDER BY, SKIP and
|
|
31
|
+
* LIMIT each count as their own clause), a `|` at that depth, or the
|
|
32
|
+
* bracket closing the enclosing one. The assertion passes when any
|
|
33
|
+
* occurrence of the clause contains `pattern`.
|
|
34
|
+
*
|
|
35
|
+
* Before v2.5.0 the clause was a raw substring (`'SET'` matched
|
|
36
|
+
* `$offset`) and `pattern` could appear anywhere in the query.
|
|
37
|
+
*
|
|
20
38
|
* @param cypher - The full Cypher string
|
|
21
39
|
* @param clauseType - e.g., 'WHERE', 'MATCH', 'RETURN', 'SET'
|
|
22
40
|
* @param pattern - Substring to search for within the clause
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cypher-assert.d.ts","sourceRoot":"","sources":["../../../src/testing/cypher-assert.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cypher-assert.d.ts","sourceRoot":"","sources":["../../../src/testing/cypher-assert.ts"],"names":[],"mappings":"AAmLA;;;GAGG;AACH,qBAAa,YAAY;IACvB;;;;;;;;;;OAUG;IACH,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAkBxC;;;OAGG;IACH,MAAM,CAAC,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAStE;;;;;;;;;;;;;;;;;;OAkBG;IACH,MAAM,CAAC,oBAAoB,CACzB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,IAAI;IAaP;;OAEG;IACH,MAAM,CAAC,uBAAuB,CAC5B,MAAM,EAAE,MAAM,EACd,mBAAmB,EAAE,MAAM,EAC3B,OAAO,CAAC,EAAE,MAAM,GACf,IAAI;IAQP;;;OAGG;IACH,MAAM,CAAC,YAAY,CACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,IAAI;CAeR"}
|
|
@@ -1,6 +1,183 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CypherAssert = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* JSON with object keys sorted at every depth and bigints written as
|
|
6
|
+
* `{"$bigint":"<digits>"}`, so two values compare equal regardless of key
|
|
7
|
+
* order and a bigint never equals the number or string with its digits.
|
|
8
|
+
*
|
|
9
|
+
* Every pair that JSON.stringify called equal before v2.4.8 is still equal:
|
|
10
|
+
* this only sorts keys and gives bigint (which used to throw a TypeError)
|
|
11
|
+
* an encoding. A neo4j Integer stays `{"high":…,"low":…}`, so it equals an
|
|
12
|
+
* Integer of the same value and not a plain number.
|
|
13
|
+
*/
|
|
14
|
+
function canonicalJson(value) {
|
|
15
|
+
return JSON.stringify(value, (_key, v) => {
|
|
16
|
+
if (typeof v === 'bigint')
|
|
17
|
+
return { $bigint: v.toString() };
|
|
18
|
+
if (v && typeof v === 'object' && !Array.isArray(v)) {
|
|
19
|
+
const sorted = {};
|
|
20
|
+
for (const k of Object.keys(v).sort())
|
|
21
|
+
sorted[k] = v[k];
|
|
22
|
+
return sorted;
|
|
23
|
+
}
|
|
24
|
+
return v;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Split Cypher into tokens, keeping string literals, backticked names and
|
|
29
|
+
* comments whole so nothing inside them is read as a keyword, a parameter
|
|
30
|
+
* or collapsible whitespace (v2.5.0).
|
|
31
|
+
*/
|
|
32
|
+
function tokenize(cypher) {
|
|
33
|
+
const tokens = [];
|
|
34
|
+
let i = 0;
|
|
35
|
+
const push = (kind, end) => {
|
|
36
|
+
tokens.push({ kind, text: cypher.slice(i, end), start: i, end });
|
|
37
|
+
i = end;
|
|
38
|
+
};
|
|
39
|
+
while (i < cypher.length) {
|
|
40
|
+
const ch = cypher[i];
|
|
41
|
+
if (/\s/.test(ch)) {
|
|
42
|
+
let j = i + 1;
|
|
43
|
+
while (j < cypher.length && /\s/.test(cypher[j]))
|
|
44
|
+
j++;
|
|
45
|
+
push('space', j);
|
|
46
|
+
}
|
|
47
|
+
else if (ch === "'" || ch === '"') {
|
|
48
|
+
let j = i + 1;
|
|
49
|
+
while (j < cypher.length && cypher[j] !== ch)
|
|
50
|
+
j += cypher[j] === '\\' ? 2 : 1;
|
|
51
|
+
push('quoted', Math.min(j + 1, cypher.length));
|
|
52
|
+
}
|
|
53
|
+
else if (ch === '`') {
|
|
54
|
+
// A backticked name escapes a backtick by doubling it.
|
|
55
|
+
let j = i + 1;
|
|
56
|
+
while (j < cypher.length)
|
|
57
|
+
if (cypher[j] === '`' && cypher[j + 1] === '`')
|
|
58
|
+
j += 2;
|
|
59
|
+
else if (cypher[j] === '`')
|
|
60
|
+
break;
|
|
61
|
+
else
|
|
62
|
+
j++;
|
|
63
|
+
push('quoted', Math.min(j + 1, cypher.length));
|
|
64
|
+
}
|
|
65
|
+
else if (cypher.startsWith('//', i)) {
|
|
66
|
+
const nl = cypher.indexOf('\n', i);
|
|
67
|
+
push('comment', nl === -1 ? cypher.length : nl);
|
|
68
|
+
}
|
|
69
|
+
else if (cypher.startsWith('/*', i)) {
|
|
70
|
+
const close = cypher.indexOf('*/', i + 2);
|
|
71
|
+
push('comment', close === -1 ? cypher.length : close + 2);
|
|
72
|
+
}
|
|
73
|
+
else if (ch === '$' && /[A-Za-z_]/.test(cypher[i + 1] ?? '')) {
|
|
74
|
+
let j = i + 1;
|
|
75
|
+
while (j < cypher.length && /[A-Za-z0-9_]/.test(cypher[j]))
|
|
76
|
+
j++;
|
|
77
|
+
push('param', j);
|
|
78
|
+
}
|
|
79
|
+
else if (/[A-Za-z0-9_]/.test(ch)) {
|
|
80
|
+
let j = i + 1;
|
|
81
|
+
while (j < cypher.length && /[A-Za-z0-9_]/.test(cypher[j]))
|
|
82
|
+
j++;
|
|
83
|
+
push('word', j);
|
|
84
|
+
}
|
|
85
|
+
else
|
|
86
|
+
push('punct', i + 1);
|
|
87
|
+
}
|
|
88
|
+
return tokens;
|
|
89
|
+
}
|
|
90
|
+
/** Keywords that start a clause, and so end the clause before them. */
|
|
91
|
+
const CLAUSE_KEYWORDS = new Set([
|
|
92
|
+
'CALL',
|
|
93
|
+
'CREATE',
|
|
94
|
+
'DELETE',
|
|
95
|
+
'DETACH',
|
|
96
|
+
'FINISH',
|
|
97
|
+
'FOREACH',
|
|
98
|
+
'LIMIT',
|
|
99
|
+
'LOAD',
|
|
100
|
+
'MATCH',
|
|
101
|
+
'MERGE',
|
|
102
|
+
'OFFSET',
|
|
103
|
+
'ON',
|
|
104
|
+
'OPTIONAL',
|
|
105
|
+
'ORDER',
|
|
106
|
+
'REMOVE',
|
|
107
|
+
'RETURN',
|
|
108
|
+
'SET',
|
|
109
|
+
'SKIP',
|
|
110
|
+
'UNION',
|
|
111
|
+
'UNWIND',
|
|
112
|
+
'USE',
|
|
113
|
+
'WHERE',
|
|
114
|
+
'WITH',
|
|
115
|
+
'YIELD',
|
|
116
|
+
]);
|
|
117
|
+
/** The tokens that carry meaning, so keyword checks look past whitespace. */
|
|
118
|
+
function significant(tokens) {
|
|
119
|
+
return tokens.filter((t) => t.kind !== 'space' && t.kind !== 'comment');
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Whether `sig[k]` (a word) is used as a keyword rather than a name: not a
|
|
123
|
+
* property (`.set`), a label or type (`:Set`), a map key (`set:`), or the
|
|
124
|
+
* WITH of `STARTS WITH` / `ENDS WITH`.
|
|
125
|
+
*/
|
|
126
|
+
function isKeywordUse(sig, k) {
|
|
127
|
+
const prev = sig[k - 1];
|
|
128
|
+
const next = sig[k + 1];
|
|
129
|
+
if (prev?.kind === 'punct' && (prev.text === '.' || prev.text === ':'))
|
|
130
|
+
return false;
|
|
131
|
+
if (next?.kind === 'punct' && next.text === ':')
|
|
132
|
+
return false;
|
|
133
|
+
if (sig[k].text.toUpperCase() === 'WITH' &&
|
|
134
|
+
prev?.kind === 'word' &&
|
|
135
|
+
['STARTS', 'ENDS'].includes(prev.text.toUpperCase()))
|
|
136
|
+
return false;
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* The source text of every occurrence of `clauseType` used as a keyword:
|
|
141
|
+
* from the keyword to the next clause keyword at the same bracket depth,
|
|
142
|
+
* a `|` at that depth (list and pattern comprehensions), or the bracket
|
|
143
|
+
* that closes the enclosing one — whichever comes first.
|
|
144
|
+
*/
|
|
145
|
+
function clauseSegments(cypher, clauseType) {
|
|
146
|
+
const words = clauseType.trim().toUpperCase().split(/\s+/);
|
|
147
|
+
const sig = significant(tokenize(cypher));
|
|
148
|
+
const segments = [];
|
|
149
|
+
for (let k = 0; k + words.length <= sig.length; k++) {
|
|
150
|
+
const matches = words.every((w, n) => sig[k + n].kind === 'word' && sig[k + n].text.toUpperCase() === w);
|
|
151
|
+
if (!matches || !isKeywordUse(sig, k))
|
|
152
|
+
continue;
|
|
153
|
+
let depth = 0;
|
|
154
|
+
let end = cypher.length;
|
|
155
|
+
for (let j = k + words.length; j < sig.length; j++) {
|
|
156
|
+
const t = sig[j];
|
|
157
|
+
if (t.kind === 'punct' && '([{'.includes(t.text))
|
|
158
|
+
depth++;
|
|
159
|
+
else if (t.kind === 'punct' && ')]}'.includes(t.text)) {
|
|
160
|
+
if (--depth < 0) {
|
|
161
|
+
end = t.start;
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
else if (depth === 0 && t.kind === 'punct' && t.text === '|') {
|
|
166
|
+
end = t.start;
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
else if (depth === 0 &&
|
|
170
|
+
t.kind === 'word' &&
|
|
171
|
+
CLAUSE_KEYWORDS.has(t.text.toUpperCase()) &&
|
|
172
|
+
isKeywordUse(sig, j)) {
|
|
173
|
+
end = t.start;
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
segments.push(cypher.slice(sig[k].start, end));
|
|
178
|
+
}
|
|
179
|
+
return segments;
|
|
180
|
+
}
|
|
4
181
|
/**
|
|
5
182
|
* Structural Cypher comparison utility that normalizes whitespace
|
|
6
183
|
* and parameter names for deterministic test assertions.
|
|
@@ -11,17 +188,30 @@ class CypherAssert {
|
|
|
11
188
|
* - Collapse all whitespace sequences to a single space
|
|
12
189
|
* - Trim leading/trailing whitespace
|
|
13
190
|
* - Rename params to canonical $p0, $p1, etc. (in order of appearance)
|
|
191
|
+
*
|
|
192
|
+
* String literals and backticked names are kept verbatim (v2.5.0): their
|
|
193
|
+
* whitespace is part of the value, and a `$name` inside a string is text,
|
|
194
|
+
* not a parameter. Before v2.5.0 both were collapsed and renamed, so
|
|
195
|
+
* `'a b'` equalled `'a b'`.
|
|
14
196
|
*/
|
|
15
197
|
static normalize(cypher) {
|
|
16
|
-
const collapsed = cypher.replace(/\s+/g, ' ').trim();
|
|
17
198
|
const seen = new Map();
|
|
18
199
|
let counter = 0;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
200
|
+
return tokenize(cypher)
|
|
201
|
+
.map((t) => {
|
|
202
|
+
if (t.kind === 'space')
|
|
203
|
+
return ' ';
|
|
204
|
+
if (t.kind === 'comment')
|
|
205
|
+
return t.text.replace(/\s+/g, ' ');
|
|
206
|
+
if (t.kind === 'param') {
|
|
207
|
+
if (!seen.has(t.text))
|
|
208
|
+
seen.set(t.text, `$p${counter++}`);
|
|
209
|
+
return seen.get(t.text);
|
|
210
|
+
}
|
|
211
|
+
return t.text;
|
|
212
|
+
})
|
|
213
|
+
.join('')
|
|
214
|
+
.trim();
|
|
25
215
|
}
|
|
26
216
|
/**
|
|
27
217
|
* Assert two Cypher strings are structurally equal after normalization.
|
|
@@ -34,16 +224,30 @@ class CypherAssert {
|
|
|
34
224
|
throw new Error(`Cypher mismatch:\n Actual: ${normalizedActual}\n Expected: ${normalizedExpected}`);
|
|
35
225
|
}
|
|
36
226
|
/**
|
|
37
|
-
* Assert that a Cypher string contains a
|
|
227
|
+
* Assert that a Cypher string contains a clause, and that `pattern`
|
|
228
|
+
* appears inside that clause.
|
|
229
|
+
*
|
|
230
|
+
* The clause keyword is matched case-insensitively as a whole word (or
|
|
231
|
+
* words, e.g. 'ORDER BY', 'ON CREATE SET'), never inside a name, a
|
|
232
|
+
* parameter, a string or a comment. A clause runs from its keyword to the
|
|
233
|
+
* next clause keyword at the same bracket depth (WHERE, ORDER BY, SKIP and
|
|
234
|
+
* LIMIT each count as their own clause), a `|` at that depth, or the
|
|
235
|
+
* bracket closing the enclosing one. The assertion passes when any
|
|
236
|
+
* occurrence of the clause contains `pattern`.
|
|
237
|
+
*
|
|
238
|
+
* Before v2.5.0 the clause was a raw substring (`'SET'` matched
|
|
239
|
+
* `$offset`) and `pattern` could appear anywhere in the query.
|
|
240
|
+
*
|
|
38
241
|
* @param cypher - The full Cypher string
|
|
39
242
|
* @param clauseType - e.g., 'WHERE', 'MATCH', 'RETURN', 'SET'
|
|
40
243
|
* @param pattern - Substring to search for within the clause
|
|
41
244
|
*/
|
|
42
245
|
static assertContainsClause(cypher, clauseType, pattern) {
|
|
43
|
-
|
|
246
|
+
const segments = clauseSegments(cypher, clauseType);
|
|
247
|
+
if (segments.length === 0)
|
|
44
248
|
throw new Error(`Cypher does not contain clause '${clauseType}':\n ${cypher}`);
|
|
45
|
-
if (!
|
|
46
|
-
throw new Error(`Cypher does not contain pattern '${pattern}':\n ${cypher}`);
|
|
249
|
+
if (!segments.some((s) => s.includes(pattern)))
|
|
250
|
+
throw new Error(`Cypher does not contain pattern '${pattern}' within a '${clauseType}' clause:\n ${cypher}`);
|
|
47
251
|
}
|
|
48
252
|
/**
|
|
49
253
|
* Assert that a Cypher string does NOT contain a specific clause/pattern.
|
|
@@ -61,8 +265,8 @@ class CypherAssert {
|
|
|
61
265
|
for (const key of Object.keys(expected)) {
|
|
62
266
|
if (!(key in actual))
|
|
63
267
|
throw new Error(`Missing param key '${key}' in actual params: ${JSON.stringify(actual)}`);
|
|
64
|
-
const actualVal =
|
|
65
|
-
const expectedVal =
|
|
268
|
+
const actualVal = canonicalJson(actual[key]);
|
|
269
|
+
const expectedVal = canonicalJson(expected[key]);
|
|
66
270
|
if (actualVal !== expectedVal)
|
|
67
271
|
throw new Error(`Param '${key}' mismatch:\n Actual: ${actualVal}\n Expected: ${expectedVal}`);
|
|
68
272
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cypher-assert.js","sourceRoot":"","sources":["../../../src/testing/cypher-assert.ts"],"names":[],"mappings":";;;AAAA
|
|
1
|
+
{"version":3,"file":"cypher-assert.js","sourceRoot":"","sources":["../../../src/testing/cypher-assert.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,12 +14,39 @@ export declare class Neo4jRecordFactory {
|
|
|
14
14
|
*/
|
|
15
15
|
static integer(value: number): Integer;
|
|
16
16
|
/**
|
|
17
|
-
* Create a Neo4j DateTime value from an ISO string
|
|
17
|
+
* Create a Neo4j DateTime value from an ISO string, as the driver would
|
|
18
|
+
* return `datetime(isoString)`: the wall-clock fields and the offset are
|
|
19
|
+
* kept as written (`10:00+02:00` stays `10:00+02:00`), all nine fractional
|
|
20
|
+
* digits are kept, and a `[Area/City]` zone id is carried over.
|
|
21
|
+
*
|
|
22
|
+
* Field values are plain numbers (what the driver returns with
|
|
23
|
+
* `disableLosslessIntegers`), so `toString()` matches the driver's.
|
|
24
|
+
*
|
|
25
|
+
* A string with neither an offset nor a zone id is read as UTC, as Neo4j
|
|
26
|
+
* reads it with its default zone.
|
|
27
|
+
*
|
|
28
|
+
* Before v2.4.8 the value was converted to UTC with the offset dropped
|
|
29
|
+
* and the fraction cut to milliseconds; before v2.5.0 an offset-less
|
|
30
|
+
* string was read in the machine's local zone.
|
|
18
31
|
*/
|
|
19
32
|
static dateTime(isoString: string): unknown;
|
|
33
|
+
/** The pre-v2.5.0 parse: through `Date`, in UTC, millisecond precision. */
|
|
34
|
+
private static legacyDateTime;
|
|
20
35
|
/**
|
|
21
36
|
* Create a mock Neo4j Node.
|
|
37
|
+
*
|
|
38
|
+
* `properties` are stored as given. The driver returns an Int property as
|
|
39
|
+
* an Integer, so pass `Neo4jRecordFactory.integer(n)` where a test needs
|
|
40
|
+
* that; a JS number is never converted, because it may stand for a Float.
|
|
41
|
+
*
|
|
42
|
+
* `options.identity` and `options.elementId` (v2.5.0) give mock nodes
|
|
43
|
+
* distinct ids; without them every node has identity 0 and elementId "0".
|
|
44
|
+
* A given identity alone yields elementId `String(identity)`, as the
|
|
45
|
+
* driver does for a 4.x server.
|
|
22
46
|
*/
|
|
23
|
-
static node(labels: string[], properties: Record<string, unknown
|
|
47
|
+
static node(labels: string[], properties: Record<string, unknown>, options?: {
|
|
48
|
+
identity?: number | Integer;
|
|
49
|
+
elementId?: string;
|
|
50
|
+
}): unknown;
|
|
24
51
|
}
|
|
25
52
|
//# sourceMappingURL=neo4j-record-factory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neo4j-record-factory.d.ts","sourceRoot":"","sources":["../../../src/testing/neo4j-record-factory.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,OAAO,EAAE,MAAM,IAAI,WAAW,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"neo4j-record-factory.d.ts","sourceRoot":"","sources":["../../../src/testing/neo4j-record-factory.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,OAAO,EAAE,MAAM,IAAI,WAAW,EAAE,MAAM,cAAc,CAAC;AAoDrE;;GAEG;AACH,qBAAa,kBAAkB;IAC7B;;;;OAIG;IACH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,WAAW;IAMzD;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAItC;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAsC3C,2EAA2E;IAC3E,OAAO,CAAC,MAAM,CAAC,cAAc;IAoB7B;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,IAAI,CACT,MAAM,EAAE,MAAM,EAAE,EAChB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,OAAO,GAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GAChE,OAAO;CASX"}
|