Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 3 additions & 27 deletions packages/host/tests/unit/query-field-normalization-test.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
import { module, test } from 'qunit';

import type { LooseCardResource } from '@cardstack/runtime-common';
import {
codeRefWithAbsoluteIdentifier,
rri,
VirtualNetwork,
} from '@cardstack/runtime-common';
import { codeRefWithAbsoluteIdentifier, rri } from '@cardstack/runtime-common';
import {
getValueForResourcePath,
normalizeQueryDefinition,
} from '@cardstack/runtime-common/query-field-utils';

module('normalizeQueryDefinition', function () {
let virtualNetwork = new VirtualNetwork();
let fieldDefinition = {
type: 'containsMany',
isPrimitive: false,
Expand Down Expand Up @@ -49,15 +44,13 @@ module('normalizeQueryDefinition', function () {
fieldPath: 'profile',
resource,
resolvePathValue: (path) => getValueForResourcePath(resource, path),
virtualNetwork,
});

assert.ok(normalized, 'normalization succeeded');
let targetRef = codeRefWithAbsoluteIdentifier(
fieldDefinition.fieldOrCard,
new URL(resource.id!),
undefined,
virtualNetwork,
);
assert.deepEqual(normalized?.query.filter, {
eq: { city: 'NYC' },
Expand All @@ -66,7 +59,7 @@ module('normalizeQueryDefinition', function () {
assert.strictEqual(normalized?.realm, 'https://other.realm/');
});

test('resolves in RRI space when no VirtualNetwork is supplied', function (assert) {
test('resolves relative code refs in RRI space', function (assert) {
let realmURL = new URL('https://realm.example/');
let resource: LooseCardResource = {
// A prefix-mapped realm's canonical instance id.
Expand Down Expand Up @@ -96,7 +89,7 @@ module('normalizeQueryDefinition', function () {
resolvePathValue: () => undefined,
});

assert.ok(normalized, 'normalization succeeded without a VirtualNetwork');
assert.ok(normalized, 'normalization succeeded');
assert.deepEqual(
normalized?.query.filter,
{
Expand Down Expand Up @@ -132,7 +125,6 @@ module('normalizeQueryDefinition', function () {
fieldDefinition.fieldOrCard,
relativeTo,
undefined,
virtualNetwork,
);

let normalized = normalizeQueryDefinition({
Expand All @@ -144,7 +136,6 @@ module('normalizeQueryDefinition', function () {
fieldName: 'testField',
resolvePathValue: () => undefined,
relativeTo,
virtualNetwork,
});

assert.ok(normalized, 'normalization succeeded');
Expand All @@ -160,7 +151,6 @@ module('normalizeQueryDefinition', function () {
fieldDefinition.fieldOrCard,
relativeTo,
undefined,
virtualNetwork,
);

let normalized = normalizeQueryDefinition({
Expand All @@ -174,7 +164,6 @@ module('normalizeQueryDefinition', function () {
fieldName: 'testField',
resolvePathValue: () => undefined,
relativeTo,
virtualNetwork,
});

assert.ok(normalized, 'normalization succeeded');
Expand All @@ -193,7 +182,6 @@ module('normalizeQueryDefinition', function () {
fieldDefinition.fieldOrCard,
relativeTo,
undefined,
virtualNetwork,
);

let normalized = normalizeQueryDefinition({
Expand All @@ -207,7 +195,6 @@ module('normalizeQueryDefinition', function () {
fieldName: 'testField',
resolvePathValue: () => undefined,
relativeTo,
virtualNetwork,
});

assert.ok(normalized, 'normalization succeeded');
Expand All @@ -226,7 +213,6 @@ module('normalizeQueryDefinition', function () {
fieldDefinition.fieldOrCard,
relativeTo,
undefined,
virtualNetwork,
);

let normalized = normalizeQueryDefinition({
Expand All @@ -245,7 +231,6 @@ module('normalizeQueryDefinition', function () {
fieldName: 'testField',
resolvePathValue: () => undefined,
relativeTo,
virtualNetwork,
});

assert.ok(normalized, 'normalization succeeded');
Expand All @@ -269,7 +254,6 @@ module('normalizeQueryDefinition', function () {
fieldDefinition.fieldOrCard,
relativeTo,
undefined,
virtualNetwork,
);
let typeRef = {
module: rri('https://example.com/other'),
Expand All @@ -287,7 +271,6 @@ module('normalizeQueryDefinition', function () {
fieldName: 'testField',
resolvePathValue: () => undefined,
relativeTo,
virtualNetwork,
});

assert.ok(normalized, 'normalization succeeded');
Expand Down Expand Up @@ -318,15 +301,13 @@ module('normalizeQueryDefinition', function () {
fieldName: 'testField',
resolvePathValue: () => undefined,
relativeTo,
virtualNetwork,
});

assert.ok(normalized, 'normalization succeeded');
let targetRef = codeRefWithAbsoluteIdentifier(
fieldDefinition.fieldOrCard,
relativeTo,
undefined,
virtualNetwork,
);
assert.deepEqual(normalized?.query.filter, {
any: [
Expand All @@ -350,14 +331,12 @@ module('normalizeQueryDefinition', function () {
fieldName: 'matchingItems',
resolvePathValue: (path) => resolvePath(instance, path),
relativeTo,
virtualNetwork,
});

let targetRef = codeRefWithAbsoluteIdentifier(
fieldDefinition.fieldOrCard,
relativeTo,
undefined,
virtualNetwork,
);
assert.deepEqual(normalized?.query.filter, {
in: { color: ['red', 'blue', 'green'] },
Expand All @@ -379,7 +358,6 @@ module('normalizeQueryDefinition', function () {
fieldName: 'matchingItems',
resolvePathValue: (path) => resolvePath(instance, path),
relativeTo,
virtualNetwork,
});

assert.strictEqual(
Expand All @@ -403,14 +381,12 @@ module('normalizeQueryDefinition', function () {
fieldName: 'favoriteCity',
resolvePathValue: (path) => resolvePath(instance, path),
relativeTo,
virtualNetwork,
});

let targetRef = codeRefWithAbsoluteIdentifier(
fieldDefinition.fieldOrCard,
relativeTo,
undefined,
virtualNetwork,
);
assert.deepEqual(normalized?.query.filter, {
eq: { city: 'Paris' },
Expand Down
20 changes: 5 additions & 15 deletions packages/runtime-common/query-field-utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { codeRefWithAbsoluteIdentifier, type CodeRef } from './code-ref.ts';
import { rri, type RealmResourceIdentifier } from './realm-identifiers.ts';
import type { VirtualNetwork } from './virtual-network.ts';
import type { FieldDefinition } from './definitions.ts';
import type {
FileMetaResource,
Expand Down Expand Up @@ -41,12 +40,6 @@ export interface NormalizeQueryDefinitionParams {
resolvePathValue: (path: string) => any;
resource?: LooseCardResource | FileMetaResource;
relativeTo?: RealmResourceIdentifier | URL;
// Optional: when supplied, the target code ref and the reference base are
// resolved through the VirtualNetwork to real URLs (legacy callers). When
// omitted, resolution happens in RRI space — identifiers pass through in
// their canonical form (prefix for mapped realms, URL otherwise), which the
// search index and the client-side filter matcher both tolerate.
virtualNetwork?: VirtualNetwork;
}

export interface NormalizedQueryDefinitionResult {
Expand All @@ -63,7 +56,6 @@ export function normalizeQueryDefinition({
resolvePathValue,
resource,
relativeTo,
virtualNetwork,
}: NormalizeQueryDefinitionParams): NormalizedQueryDefinitionResult | null {
let workingQuery: QueryWithInterpolations = JSON.parse(
JSON.stringify(queryDefinition),
Expand Down Expand Up @@ -239,18 +231,16 @@ export function normalizeQueryDefinition({

let resolvedRealm = resolveRealm(specifiedRealm);

// Resolve in RRI space: the resource's canonical id (prefix form for mapped
// realms, URL otherwise) is a valid base for relative code-ref resolution,
// and the resulting ref keeps its canonical spelling — which the search
// index and the client-side filter matcher both tolerate.
let relativeToBase: RealmResourceIdentifier | URL =
relativeTo ??
(resource?.id
? virtualNetwork
? virtualNetwork.toURL(resource.id)
: rri(resource.id)
: realmURL);
relativeTo ?? (resource?.id ? rri(resource.id) : realmURL);
let targetRef = codeRefWithAbsoluteIdentifier(
fieldDefinition.fieldOrCard,
relativeToBase,
undefined,
virtualNetwork,
);

let filter = queryAny.filter as Record<string, any> | undefined;
Expand Down
9 changes: 5 additions & 4 deletions packages/runtime-common/realm-index-query-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1046,6 +1046,11 @@ export class RealmIndexQueryEngine {
let fieldPath = fieldName.includes('.')
? fieldName.slice(0, fieldName.lastIndexOf('.'))
: '';
// Resolved in RRI space (no VirtualNetwork): the target code ref keeps its
// canonical spelling (prefix form for mapped realms), which the index
// matches via its equivalent-spelling tolerance, and the resulting
// `links.search` seed URL reconciles with the client's RRI-space rebuild
// of the same query.
let normalized = normalizeQueryDefinition({
fieldDefinition,
queryDefinition,
Expand All @@ -1054,10 +1059,6 @@ export class RealmIndexQueryEngine {
fieldName,
fieldPath,
resolvePathValue: (path) => getValueForResourcePath(resource, path),
relativeTo: resource.id
? this.#realm.virtualNetwork.toURL(resource.id)
: realmURL,
virtualNetwork: this.#realm.virtualNetwork,
});
if (!normalized) {
return { results: [], errors: [], searchURL: '' };
Expand Down
Loading