diff --git a/packages/runtime-common/catalog.ts b/packages/runtime-common/catalog.ts index 0b4040b8b3..85f42adddf 100644 --- a/packages/runtime-common/catalog.ts +++ b/packages/runtime-common/catalog.ts @@ -9,6 +9,7 @@ import { realmURL } from './constants'; import { logger } from './log'; import type { LocalPath } from './paths'; import { cardIdToURL } from './card-reference-resolver'; +import type { RealmResourceIdentifier } from './card-reference-resolver'; // @ts-ignore TODO: fix catalog types in runtime-common import type { Listing } from '@cardstack/catalog/listing/listing'; @@ -176,7 +177,7 @@ function resolveTargetCodeRef( let targetModule = resolver.target(cardIdToURL(codeRef.module).href); return { name: codeRef.name, - module: targetModule, + module: targetModule as RealmResourceIdentifier, }; } } @@ -189,7 +190,10 @@ export function planModuleInstall( return new InstallPlan([], []); } let codeRefs: ResolvedCodeRef[] = specs.map((s) => { - return { module: s.moduleHref, name: s.ref.name }; + return { + module: s.moduleHref as RealmResourceIdentifier, + name: s.ref.name, + }; }); let modulesCopy = codeRefs.flatMap((sourceCodeRef: ResolvedCodeRef) => { if (baseRealmPath.inRealm(cardIdToURL(sourceCodeRef.module))) { diff --git a/packages/runtime-common/code-ref.ts b/packages/runtime-common/code-ref.ts index 3244abfd06..644600351b 100644 --- a/packages/runtime-common/code-ref.ts +++ b/packages/runtime-common/code-ref.ts @@ -20,13 +20,14 @@ import { } from './constants'; import { CardError } from './error'; import { cardIdToURL } from './card-reference-resolver'; +import type { RealmResourceIdentifier } from './card-reference-resolver'; import type { LooseCardResource, FileMetaResource } from './index'; import { trimExecutableExtension } from './index'; import { resolveCardReference } from './card-reference-resolver'; import type { RuntimeDependencyTrackingContext } from './dependency-tracker'; export type ResolvedCodeRef = { - module: string; + module: RealmResourceIdentifier; name: string; }; @@ -171,7 +172,7 @@ export function codeRefWithAbsoluteURL( if (opts?.trimExecutableExtension) { moduleURL = trimExecutableExtension(moduleURL); } - return { ...ref, module: moduleURL.href }; + return { ...ref, module: moduleURL.href as RealmResourceIdentifier }; } catch { return { ...ref }; } @@ -243,10 +244,17 @@ export function identifyCard( } visited.add(card); - let ref = Loader.identify(card); - if (ref) { + let identified = Loader.identify(card); + if (identified) { + let ref = { + ...identified, + module: identified.module as RealmResourceIdentifier, + }; return maybeRelativeURL - ? { ...ref, module: maybeRelativeURL(ref.module) } + ? { + ...ref, + module: maybeRelativeURL(ref.module) as RealmResourceIdentifier, + } : ref; } @@ -482,8 +490,8 @@ function isRelativePath(moduleId: unknown): moduleId is string { } type VisitModuleDep = ( - moduleURL: string, - setModuleURL: (newURL: string) => void, + moduleURL: RealmResourceIdentifier, + setModuleURL: (newURL: RealmResourceIdentifier) => void, ) => void; function visitCodeRef(codeRef: CodeRef, visit: VisitModuleDep): void { diff --git a/packages/runtime-common/command-parsing-utils.ts b/packages/runtime-common/command-parsing-utils.ts index 7b95f0ffaa..96b8c1c350 100644 --- a/packages/runtime-common/command-parsing-utils.ts +++ b/packages/runtime-common/command-parsing-utils.ts @@ -1,4 +1,5 @@ import type { ResolvedCodeRef } from './code-ref'; +import type { RealmResourceIdentifier } from './card-reference-resolver'; import { ensureTrailingSlash } from './paths'; export function parseBoxelHostCommandSpecifier( @@ -11,7 +12,8 @@ export function parseBoxelHostCommandSpecifier( return undefined; } return { - module: `@cardstack/boxel-host/commands/${match[1]}`, + module: + `@cardstack/boxel-host/commands/${match[1]}` as RealmResourceIdentifier, name: match[2], }; } @@ -45,7 +47,8 @@ export function commandUrlToCodeRef( } return { - module: `${ensureTrailingSlash(realmURL)}commands/${parsedPath.commandName}`, + module: + `${ensureTrailingSlash(realmURL)}commands/${parsedPath.commandName}` as RealmResourceIdentifier, name: parsedPath.exportName, }; } diff --git a/packages/runtime-common/constants.ts b/packages/runtime-common/constants.ts index fdc477bc13..9f79c9fd03 100644 --- a/packages/runtime-common/constants.ts +++ b/packages/runtime-common/constants.ts @@ -1,5 +1,6 @@ import { RealmPaths } from './paths'; import type { ResolvedCodeRef } from './code-ref'; +import type { RealmResourceIdentifier } from './card-reference-resolver'; import type { RealmPermissions } from './index'; export const baseRealm = new RealmPaths(new URL('https://cardstack.com/base/')); @@ -8,27 +9,27 @@ export const devSkillLocalPath = 'Skill/boxel-development'; export const envSkillLocalPath = 'Skill/boxel-environment'; export const baseRef: ResolvedCodeRef = { - module: `${baseRealm.url}card-api`, + module: `${baseRealm.url}card-api` as RealmResourceIdentifier, name: 'BaseDef', }; export const specRef: ResolvedCodeRef = { - module: `${baseRealm.url}spec`, + module: `${baseRealm.url}spec` as RealmResourceIdentifier, name: 'Spec', }; export const baseCardRef: ResolvedCodeRef = { - module: `${baseRealm.url}card-api`, + module: `${baseRealm.url}card-api` as RealmResourceIdentifier, name: 'CardDef', }; export const baseFieldRef: ResolvedCodeRef = { - module: `${baseRealm.url}card-api`, + module: `${baseRealm.url}card-api` as RealmResourceIdentifier, name: 'FieldDef', }; export const skillCardRef: ResolvedCodeRef = { - module: `${baseRealm.url}skill`, + module: `${baseRealm.url}skill` as RealmResourceIdentifier, name: 'Skill', }; export const baseFileRef: ResolvedCodeRef = { - module: `${baseRealm.url}card-api`, + module: `${baseRealm.url}card-api` as RealmResourceIdentifier, name: 'FileDef', }; diff --git a/packages/runtime-common/definition-lookup.ts b/packages/runtime-common/definition-lookup.ts index ffbbbabc5f..df304eac03 100644 --- a/packages/runtime-common/definition-lookup.ts +++ b/packages/runtime-common/definition-lookup.ts @@ -29,6 +29,7 @@ import { isRegisteredPrefix, cardIdToURL, resolveCardReference, + type RealmResourceIdentifier, } from './card-reference-resolver'; import type { VirtualNetwork } from './virtual-network'; @@ -224,7 +225,10 @@ export class CachingDefinitionLookup implements DefinitionLookup { let canonicalCodeRef = canonicalModuleURL === codeRef.module ? codeRef - : { ...codeRef, module: canonicalModuleURL }; + : { + ...codeRef, + module: canonicalModuleURL as RealmResourceIdentifier, + }; let moduleId = internalKeyFor(canonicalCodeRef, undefined); let entry = cached.definitions[moduleId]; if (entry && 'definition' in entry) { @@ -386,7 +390,7 @@ export class CachingDefinitionLookup implements DefinitionLookup { let canonicalCodeRef = canonicalModuleURL === codeRef.module ? codeRef - : { ...codeRef, module: canonicalModuleURL }; + : { ...codeRef, module: canonicalModuleURL as RealmResourceIdentifier }; let context = await this.buildLookupContext( canonicalModuleURL, contextOpts, diff --git a/packages/runtime-common/document.ts b/packages/runtime-common/document.ts index bd5db03fd2..c98592d37c 100644 --- a/packages/runtime-common/document.ts +++ b/packages/runtime-common/document.ts @@ -7,6 +7,7 @@ import { isCardError, } from './index'; import { cardIdToURL } from './card-reference-resolver'; +import type { RealmResourceIdentifier } from './card-reference-resolver'; async function loadDocumentWithRequest( fetch: typeof globalThis.fetch, @@ -94,7 +95,7 @@ export async function loadCardDocument( } if (!json.data.id) { // card source format is not serialized with the ID, so we add that back in. - json.data.id = url; + json.data.id = url as RealmResourceIdentifier; } return json; } @@ -124,7 +125,7 @@ export async function loadFileMetaDocument( } if (!json.data.id) { // card source format is not serialized with the ID, so we add that back in. - json.data.id = url; + json.data.id = url as RealmResourceIdentifier; } return json; } diff --git a/packages/runtime-common/file-def-code-ref.ts b/packages/runtime-common/file-def-code-ref.ts index a559e8952e..757cdf77da 100644 --- a/packages/runtime-common/file-def-code-ref.ts +++ b/packages/runtime-common/file-def-code-ref.ts @@ -1,72 +1,37 @@ import { baseRealm, baseFileRef } from './constants'; import type { ResolvedCodeRef } from './code-ref'; -import { resolveCardReference } from './card-reference-resolver'; +import { + resolveCardReference, + type RealmResourceIdentifier, +} from './card-reference-resolver'; export const BASE_FILE_DEF_CODE_REF = baseFileRef; +function baseModule(name: string): RealmResourceIdentifier { + return `${baseRealm.url}${name}` as RealmResourceIdentifier; +} + const FILEDEF_CODE_REF_BY_EXTENSION: Record = { // TODO: Replace with realm metadata configuration. - '.markdown': { - module: `${baseRealm.url}markdown-file-def`, - name: 'MarkdownDef', - }, - '.md': { - module: `${baseRealm.url}markdown-file-def`, - name: 'MarkdownDef', - }, - '.png': { - module: `${baseRealm.url}png-image-def`, - name: 'PngDef', - }, - '.jpg': { - module: `${baseRealm.url}jpg-image-def`, - name: 'JpgDef', - }, - '.jpeg': { - module: `${baseRealm.url}jpg-image-def`, - name: 'JpgDef', - }, - '.svg': { - module: `${baseRealm.url}svg-image-def`, - name: 'SvgDef', - }, - '.gif': { - module: `${baseRealm.url}gif-image-def`, - name: 'GifDef', - }, - '.webp': { - module: `${baseRealm.url}webp-image-def`, - name: 'WebpDef', - }, - '.avif': { - module: `${baseRealm.url}avif-image-def`, - name: 'AvifDef', - }, - '.ts': { - module: `${baseRealm.url}ts-file-def`, - name: 'TsFileDef', - }, - '.gts': { - module: `${baseRealm.url}gts-file-def`, - name: 'GtsFileDef', - }, - '.txt': { - module: `${baseRealm.url}text-file-def`, - name: 'TextFileDef', - }, - '.text': { - module: `${baseRealm.url}text-file-def`, - name: 'TextFileDef', - }, - '.json': { - module: `${baseRealm.url}json-file-def`, - name: 'JsonFileDef', - }, - '.csv': { - module: `${baseRealm.url}csv-file-def`, - name: 'CsvFileDef', + '.markdown': { module: baseModule('markdown-file-def'), name: 'MarkdownDef' }, + '.md': { module: baseModule('markdown-file-def'), name: 'MarkdownDef' }, + '.png': { module: baseModule('png-image-def'), name: 'PngDef' }, + '.jpg': { module: baseModule('jpg-image-def'), name: 'JpgDef' }, + '.jpeg': { module: baseModule('jpg-image-def'), name: 'JpgDef' }, + '.svg': { module: baseModule('svg-image-def'), name: 'SvgDef' }, + '.gif': { module: baseModule('gif-image-def'), name: 'GifDef' }, + '.webp': { module: baseModule('webp-image-def'), name: 'WebpDef' }, + '.avif': { module: baseModule('avif-image-def'), name: 'AvifDef' }, + '.ts': { module: baseModule('ts-file-def'), name: 'TsFileDef' }, + '.gts': { module: baseModule('gts-file-def'), name: 'GtsFileDef' }, + '.txt': { module: baseModule('text-file-def'), name: 'TextFileDef' }, + '.text': { module: baseModule('text-file-def'), name: 'TextFileDef' }, + '.json': { module: baseModule('json-file-def'), name: 'JsonFileDef' }, + '.csv': { module: baseModule('csv-file-def'), name: 'CsvFileDef' }, + '.mismatch': { + module: './filedef-mismatch' as RealmResourceIdentifier, + name: 'FileDef', }, - '.mismatch': { module: './filedef-mismatch', name: 'FileDef' }, }; export function resolveFileDefCodeRef(fileURL: URL): ResolvedCodeRef { @@ -84,6 +49,9 @@ export function resolveFileDefCodeRef(fileURL: URL): ResolvedCodeRef { } return { ...mapping, - module: resolveCardReference(mapping.module, fileURL), + module: resolveCardReference( + mapping.module, + fileURL, + ) as RealmResourceIdentifier, }; } diff --git a/packages/runtime-common/index-query-engine.ts b/packages/runtime-common/index-query-engine.ts index 87d48677c6..8bccf322b6 100644 --- a/packages/runtime-common/index-query-engine.ts +++ b/packages/runtime-common/index-query-engine.ts @@ -2,6 +2,7 @@ import type * as JSONTypes from 'json-typescript'; import flatten from 'lodash/flatten'; import stringify from 'safe-stable-stringify'; import type { ResolvedCodeRef } from './index'; +import type { RealmResourceIdentifier } from './card-reference-resolver'; import { type CardResource, type CodeRef, @@ -675,7 +676,7 @@ export class IndexQueryEngine { module: card.used_render_type.substring( 0, moduleNameSeparatorIndex, - ), + ) as RealmResourceIdentifier, name: card.used_render_type.substring(moduleNameSeparatorIndex + 1), }; } diff --git a/packages/runtime-common/index-writer.ts b/packages/runtime-common/index-writer.ts index 1a43bf1471..588e7329a6 100644 --- a/packages/runtime-common/index-writer.ts +++ b/packages/runtime-common/index-writer.ts @@ -14,6 +14,8 @@ import { import { isRegisteredPrefix, unresolveCardReference, + type RealmResourceIdentifier, + type RealmIdentifier, } from './card-reference-resolver'; import { getCreatedTime, ensureFileCreatedAt } from './file-meta'; import { @@ -228,13 +230,13 @@ export class Batch { entry.pristine_doc = entry.pristine_doc ? { ...entry.pristine_doc, - id: copyURL(entry.pristine_doc.id!), // these will always have an ID + id: copyURL(entry.pristine_doc.id!) as RealmResourceIdentifier, // these will always have an ID } : entry.pristine_doc; if (entry.type === 'instance' && entry.pristine_doc) { entry.pristine_doc.meta = { ...entry.pristine_doc.meta, - realmURL: this.realmURL.href, + realmURL: this.realmURL.href as RealmIdentifier, }; } entry.fitted_html = entry.fitted_html diff --git a/packages/runtime-common/index.ts b/packages/runtime-common/index.ts index 510877fafe..806b1090ab 100644 --- a/packages/runtime-common/index.ts +++ b/packages/runtime-common/index.ts @@ -14,6 +14,7 @@ import { resolveCardReference, unresolveCardReference, isRegisteredPrefix, + type RealmResourceIdentifier, } from './card-reference-resolver'; import type { RealmEventContent } from 'https://cardstack.com/base/matrix-event'; @@ -709,7 +710,7 @@ export function codeRefFromInternalKey( return; } return { - module: internalKey.slice(0, lastSlash), + module: internalKey.slice(0, lastSlash) as RealmResourceIdentifier, name: internalKey.slice(lastSlash + 1), }; } diff --git a/packages/runtime-common/module-syntax.ts b/packages/runtime-common/module-syntax.ts index 5e8a77b2f7..572aa363a3 100644 --- a/packages/runtime-common/module-syntax.ts +++ b/packages/runtime-common/module-syntax.ts @@ -27,6 +27,7 @@ import { baseCardRef, baseFieldRef, type CodeRef, + type ResolvedCodeRef, } from './index'; import { resolveCardReference } from './card-reference-resolver'; //@ts-ignore unsure where these types live @@ -116,7 +117,7 @@ export class ModuleSyntax { }: { cardBeingModified: CodeRef; fieldName: string; - fieldRef: { name: string; module: string }; // module could be a relative path + fieldRef: ResolvedCodeRef; // module could be a relative path fieldType: FieldType; fieldDefinitionType: 'card' | 'field'; incomingRelativeTo: URL | undefined; // can be undefined when you know the url is not going to be relative @@ -386,7 +387,7 @@ function makeNewField({ computedFieldFunctionSourceCode, }: { target: NodePath; - fieldRef: { name: string; module: string }; + fieldRef: ResolvedCodeRef; fieldDefinitionType: 'card' | 'field'; fieldType: FieldType; fieldName: string; diff --git a/packages/runtime-common/realm-index-query-engine.ts b/packages/runtime-common/realm-index-query-engine.ts index bf5d0a12a2..8f6b7d6cc1 100644 --- a/packages/runtime-common/realm-index-query-engine.ts +++ b/packages/runtime-common/realm-index-query-engine.ts @@ -32,6 +32,10 @@ import { import type { Realm } from './realm'; import { FILE_META_RESERVED_KEYS } from './realm'; import { RealmPaths } from './paths'; +import type { + RealmResourceIdentifier, + RealmIdentifier, +} from './card-reference-resolver'; import type { Filter, Query } from './query'; import { CardError, type SerializedError } from './error'; import { @@ -1025,7 +1029,9 @@ export class RealmIndexQueryEngine { absolutizeInstanceURL(url, rewrittenResource.id, setURL), ); visitModuleDeps(rewrittenResource, (url, setURL) => - absolutizeInstanceURL(url, rewrittenResource.id, setURL), + absolutizeInstanceURL(url, rewrittenResource.id, (newURL) => + setURL(newURL as RealmResourceIdentifier), + ), ); included.push(rewrittenResource); } @@ -1178,7 +1184,13 @@ function relativizeResource( let absoluteModuleURL = new URL( resolveCardReference(moduleURL, resourceURL), ); - setModuleURL(maybeRelativeURL(absoluteModuleURL, primaryURL, realmURL)); + setModuleURL( + maybeRelativeURL( + absoluteModuleURL, + primaryURL, + realmURL, + ) as RealmResourceIdentifier, + ); }); } @@ -1252,14 +1264,14 @@ function fileResourceFromIndex( attributes[key] = value; } return { - id: fileURL.href, + id: fileURL.href as RealmResourceIdentifier, type: 'file-meta', attributes: { ...attributes, }, meta: { - adoptsFrom, - realmURL: fileEntry.realmURL, + adoptsFrom: adoptsFrom as CodeRef, + realmURL: fileEntry.realmURL as RealmIdentifier, }, links: { self: fileURL.href }, }; diff --git a/packages/runtime-common/realm.ts b/packages/runtime-common/realm.ts index a87cf8b548..eb1bf2d07b 100644 --- a/packages/runtime-common/realm.ts +++ b/packages/runtime-common/realm.ts @@ -1,5 +1,9 @@ import { Deferred } from './deferred'; -import { resolveCardReference } from './card-reference-resolver'; +import { + resolveCardReference, + type RealmResourceIdentifier, + type RealmIdentifier, +} from './card-reference-resolver'; import { collectDependentModuleCacheInvalidations, extractModuleDependencyKeys, @@ -2597,7 +2601,7 @@ export class Realm { let doc: SingleFileMetaDocument = { data: { type: 'file-meta', - id: fileURL, + id: fileURL as RealmResourceIdentifier, attributes: { name, url: fileURL, @@ -2611,7 +2615,7 @@ export class Realm { meta: { adoptsFrom: fileDefCodeRef, realmInfo, - realmURL: this.url, + realmURL: this.url as RealmIdentifier, }, links: { self: fileURL }, }, @@ -2687,14 +2691,14 @@ export class Realm { let doc: SingleFileMetaDocument = { data: { type: 'file-meta', - id: fileURL, + id: fileURL as RealmResourceIdentifier, attributes: { ...attributes, }, meta: { adoptsFrom, realmInfo, - realmURL: this.url, + realmURL: this.url as RealmIdentifier, ...(fileEntry.resource?.meta?.queryFieldDefs ? { queryFieldDefs: fileEntry.resource.meta.queryFieldDefs } : {}), @@ -3044,7 +3048,12 @@ export class Realm { realmURL: new URL(this.url), }); visitModuleDeps(resource, (moduleURL, setModuleURL) => { - setModuleURL(resolveCardReference(moduleURL, instanceURL)); + setModuleURL( + resolveCardReference( + moduleURL, + instanceURL, + ) as RealmResourceIdentifier, + ); }); } let fileSerialization: LooseSingleCardDocument | undefined; diff --git a/packages/runtime-common/resource-types.ts b/packages/runtime-common/resource-types.ts index db4ce80efa..e2c28468b1 100644 --- a/packages/runtime-common/resource-types.ts +++ b/packages/runtime-common/resource-types.ts @@ -1,6 +1,10 @@ import type { RealmInfo } from './realm'; import { type CodeRef, isCodeRef, moduleFrom } from './code-ref'; import { resolveCardReference } from './card-reference-resolver'; +import type { + RealmResourceIdentifier, + RealmIdentifier, +} from './card-reference-resolver'; import type { Query } from './query'; // Metadata for a query-based linksTo/linksToMany field on a FileDef subclass, @@ -31,8 +35,8 @@ export interface ModuleResource { } //cards -export type Saved = string; -export type Unsaved = string | undefined; +export type Saved = RealmResourceIdentifier; +export type Unsaved = RealmResourceIdentifier | undefined; export interface Meta { adoptsFrom: CodeRef; fields?: CardFields; @@ -69,12 +73,12 @@ export type CardResourceMeta = Meta & { lastModified?: number; resourceCreatedAt?: number; realmInfo?: RealmInfo; - realmURL?: string; + realmURL?: RealmIdentifier; }; export type FileMetaResourceResourceMeta = Meta & { realmInfo?: RealmInfo; - realmURL?: string; + realmURL?: RealmIdentifier; queryFieldDefs?: Record; };