Skip to content
Open
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
50 changes: 14 additions & 36 deletions packages/base/card-api.gts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import { getLinksToManyComponent } from './links-to-many-component';
import {
assertIsSerializerName,
baseRef,
baseRealm,
CardContextName,
CardError,
CodeRef,
Expand All @@ -32,12 +31,12 @@ import {
getSerializer,
humanReadable,
identifyCard,
normalizeCodeRef,
isBaseInstance,
isCardError,
isCardInstance as _isCardInstance,
isCardResource,
isFileMetaResource,
isFileDef,
isField,
isFieldInstance,
isRelationship,
Expand Down Expand Up @@ -167,6 +166,7 @@ export {
getFields,
isCard,
isField,
isFileDef,
localId,
meta,
primitive,
Expand Down Expand Up @@ -333,28 +333,6 @@ export function instanceOf(instance: BaseDef, clazz: typeof BaseDef): boolean {
return false;
}

export function isFileDefConstructor(card: typeof BaseDef): boolean {
let baseFileDefRef = {
module: `${baseRealm.url}file-api`,
name: 'FileDef',
};
let current: typeof BaseDef | undefined = card;
while (current) {
let ref = identifyCard(current);
if (ref) {
let normalized = normalizeCodeRef(ref);
if (
normalized.module === baseFileDefRef.module &&
normalized.name === baseFileDefRef.name
) {
return true;
}
}
current = getAncestor(current) as typeof BaseDef | undefined;
}
return false;
}

class Logger {
private promises: Promise<any>[] = [];

Expand Down Expand Up @@ -1087,7 +1065,7 @@ class LinksTo<CardT extends LinkableDefConstructor> implements Field<CardT> {
visited: Set<string>,
opts?: SerializeOpts,
) {
let relationshipType = isFileDefConstructor(this.card as typeof BaseDef)
let relationshipType = isFileDef(this.card)
? FileMetaResourceType
: CardResourceType;
if (isNotLoadedValue(value)) {
Expand All @@ -1110,7 +1088,7 @@ class LinksTo<CardT extends LinkableDefConstructor> implements Field<CardT> {
},
};
}
if (isFileDefConstructor(this.card as typeof BaseDef) && !value.id) {
if (isFileDef(this.card) && !value.id) {
throw new Error(
`linksTo field '${this.name}' cannot serialize a FileDef without an id`,
);
Expand Down Expand Up @@ -1266,7 +1244,7 @@ class LinksTo<CardT extends LinkableDefConstructor> implements Field<CardT> {
if (isNotLoadedValue(value)) {
return value;
}
if (isFileDefConstructor(this.card as typeof BaseDef) && !value.id) {
if (isFileDef(this.card) && !value.id) {
throw new Error(
`field validation error: the linksTo field '${this.name}' cannot reference a FileDef without an id`,
);
Expand Down Expand Up @@ -1310,7 +1288,7 @@ class LinksTo<CardT extends LinkableDefConstructor> implements Field<CardT> {
let innerModel = model.field(fieldName);
return innerModel as unknown as Box<CardDef | null>;
};
let isFileDef = isFileDefConstructor(linksToField.card as typeof BaseDef);
let isFileDefField = isFileDef(linksToField.card);
function shouldRenderEditor(
format: Format | undefined,
defaultFormat: Format,
Expand All @@ -1323,14 +1301,14 @@ class LinksTo<CardT extends LinkableDefConstructor> implements Field<CardT> {
format: Format | undefined,
defaultFormat: Format,
model: Box<FieldDef>,
isFileDef: boolean,
isFileDefField: boolean,
) {
let effectiveFormat = format ?? defaultFormat;
if (
effectiveFormat === 'edit' &&
(('isCardDef' in model.value.constructor &&
model.value.constructor.isCardDef) ||
isFileDef)
isFileDefField)
) {
return 'fitted';
}
Expand All @@ -1352,7 +1330,7 @@ class LinksTo<CardT extends LinkableDefConstructor> implements Field<CardT> {
<DefaultFormatsConsumer as |defaultFormats|>
{{#if
(shouldRenderEditor
@format defaultFormats.cardDef isComputed isFileDef
@format defaultFormats.cardDef isComputed isFileDefField
)
}}
<LinksToEditor
Expand All @@ -1369,7 +1347,7 @@ class LinksTo<CardT extends LinkableDefConstructor> implements Field<CardT> {
@format
defaultFormats.cardDef
model
isFileDef
isFileDefField
}}
@displayContainer={{@displayContainer}}
...attributes
Expand Down Expand Up @@ -1580,7 +1558,7 @@ class LinksToMany<FieldT extends LinkableDefConstructor>
throw new Error(`Expected array for field value ${this.name}`);
}

let relationshipType = isFileDefConstructor(this.card as typeof BaseDef)
let relationshipType = isFileDef(this.card)
? FileMetaResourceType
: CardResourceType;
let relationships: Record<string, Relationship> = {};
Expand All @@ -1603,7 +1581,7 @@ class LinksToMany<FieldT extends LinkableDefConstructor>
};
return;
}
if (isFileDefConstructor(this.card as typeof BaseDef) && !value.id) {
if (isFileDef(this.card) && !value.id) {
throw new Error(
`linksToMany field '${this.name}' cannot serialize a FileDef without an id`,
);
Expand Down Expand Up @@ -1815,7 +1793,7 @@ class LinksToMany<FieldT extends LinkableDefConstructor>
if (
!isNotLoadedValue(value) &&
value != null &&
isFileDefConstructor(expectedCard as typeof BaseDef) &&
isFileDef(expectedCard) &&
!value.id
) {
throw new Error(
Expand Down Expand Up @@ -2770,7 +2748,7 @@ function lazilyLoadLink(
),
);
(async () => {
let isFileLink = isFileDefConstructor(field.card as typeof BaseDef);
let isFileLink = isFileDef(field.card);
try {
let fieldValue: CardDef | FileDef;
if (isFileLink) {
Expand Down
2 changes: 1 addition & 1 deletion packages/base/links-to-editor.gts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import GlimmerComponent from '@glimmer/component';
import { hash } from '@ember/helper';
import { on } from '@ember/modifier';
import {
restartableTask,
Expand Down Expand Up @@ -32,7 +33,6 @@ import {
import { Button, IconButton } from '@cardstack/boxel-ui/components';
import { IconMinusCircle } from '@cardstack/boxel-ui/icons';
import { consume } from 'ember-provide-consume-context';
import { hash } from '@ember/helper';

interface Signature {
Element: HTMLElement;
Expand Down
8 changes: 4 additions & 4 deletions packages/base/links-to-many-component.gts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
type LinkableDefConstructor,
CreateCardFn,
CardCrudFunctions,
isFileDefConstructor,
isFileDef,
} from './card-api';
import {
BoxComponentSignature,
Expand Down Expand Up @@ -515,13 +515,13 @@ export function getLinksToManyComponent({
getBoxComponent(cardTypeFor(field, child), child, field),
); // Wrap the the components in a function so that the template is reactive to changes in the model (this is essentially a helper)
let isComputed = !!field.computeVia || !!field.queryDefinition;
let isFileDef = isFileDefConstructor(field.card as typeof BaseDef);
let isFileDefField = isFileDef(field.card);
let linksToManyComponent = class LinksToManyComponent extends GlimmerComponent<BoxComponentSignature> {
<template>
<DefaultFormatsConsumer as |defaultFormats|>
{{#if
(shouldRenderEditor
@format defaultFormats.cardDef isComputed isFileDef
@format defaultFormats.cardDef isComputed isFileDefField
)
}}
<LinksToManyEditor
Expand Down Expand Up @@ -559,7 +559,7 @@ export function getLinksToManyComponent({
@format={{getPluralChildFormat
effectiveFormat
model
isFileDef
isFileDefField
}}
@displayContainer={{@displayContainer}}
class='linksToMany-item'
Expand Down
7 changes: 1 addition & 6 deletions packages/host/app/lib/gc-card-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { TrackedMap } from 'tracked-built-ins';
import {
isPrimitive,
isCardInstance,
isFileDefInstance,
isLocalId,
localId as localIdSymbol,
loadCardDocument,
Expand Down Expand Up @@ -54,12 +55,6 @@ type StoreHooks = {
): StoreSearchResource<T>;
};

function isFileDefInstance(item: unknown): item is FileDef {
return Boolean(
(item as { constructor?: { isFileDef?: boolean } })?.constructor?.isFileDef,
);
}

function isCardOrFileInstance(item: unknown): item is StoredInstance {
return isCardInstance(item) || isFileDefInstance(item);
}
Expand Down
10 changes: 1 addition & 9 deletions packages/host/app/resources/card-resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,12 @@ import { service } from '@ember/service';

import { Resource } from 'ember-modify-based-class-resource';

import { isCardInstance } from '@cardstack/runtime-common';
import { isCardInstance, isFileDefInstance } from '@cardstack/runtime-common';

import type { BaseDef } from 'https://cardstack.com/base/card-api';
import type { FileDef } from 'https://cardstack.com/base/file-api';

import type StoreService from '../services/store';

function isFileDefInstance(value: unknown): value is FileDef {
return Boolean(
(value as { constructor?: { isFileDef?: boolean } })?.constructor
?.isFileDef,
);
}

interface Args {
named: {
id: string | undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,7 @@ module('Integration | card-basics', function (hooks) {

test('linksTo FileDef renders delegated view from realm file meta', async function (assert) {
class Gallery extends CardDef {
@field hero = linksTo(FileDef as unknown as typeof CardDef);
@field hero = linksTo(FileDef);
static fitted = class Fitted extends Component<typeof this> {
<template>
<div data-test-gallery-fitted>
Expand Down
11 changes: 11 additions & 0 deletions packages/runtime-common/code-ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {
FieldDef,
FieldConstructor,
} from 'https://cardstack.com/base/card-api';
import type { FileDef } from 'https://cardstack.com/base/file-api';
import { Loader } from './loader';
import {
isField,
Expand Down Expand Up @@ -109,12 +110,22 @@ export function isFieldDef(field: any): field is typeof FieldDef {
return isBaseDef(field) && 'isFieldDef' in field;
}

export function isFileDef(def: any): def is typeof FileDef {
return isBaseDef(def) && 'isFileDef' in def;
}

export function isFieldInstance<T extends FieldDef>(
fieldInstance: any,
): fieldInstance is T {
return isFieldDef(fieldInstance?.constructor);
}

export function isFileDefInstance<T extends FileDef>(
fileInstance: any,
): fileInstance is T {
return isFileDef(fileInstance?.constructor);
}

export function isPrimitive(def: any) {
return isBaseDef(def) && primitive in def;
}
Expand Down
Loading