Merge remote-tracking branch 'origin/worktree/ci-native-windows-20260808' into worktree/ci-native-windows-coverage-20260808
This commit is contained in:
@@ -694,32 +694,61 @@ function renderRuntimeApi(
|
||||
lines.push(']', '')
|
||||
return lines.join('\n')
|
||||
}
|
||||
/** Render the cross-link "Types:" line for a signature, or '' if none apply. */
|
||||
function typeLinks(signature: string, linkedTypePages: Readonly<Record<string, string>>): string {
|
||||
/** Opening region delimiter; injected content lives between the pair and the page owns everything outside. */
|
||||
export const REGION_BEGIN = '<!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->'
|
||||
/** Closing region delimiter matching {@link REGION_BEGIN}. */
|
||||
export const REGION_END = '<!-- END GENERATED cordis-surface -->'
|
||||
|
||||
/**
|
||||
* Render the cross-link "Types:" line for a signature relative to one
|
||||
* subsystems page, or '' if none apply. A type whose primary page IS the
|
||||
* rendering page would link as a fragmentless self-link readers already sit
|
||||
* on, so it is dropped instead.
|
||||
*/
|
||||
function typeLinks(signature: string, onPage: string, linkedTypePages: Readonly<Record<string, string>>): string {
|
||||
const seen = new Set<string>()
|
||||
for (const name of Object.keys(linkedTypePages)) {
|
||||
if (new RegExp(`\\b${name}\\b`).test(signature)) seen.add(name)
|
||||
}
|
||||
if (seen.size === 0) return ''
|
||||
const links = [...seen].sort().map(n => `[${n}](../core-data-structures/${linkedTypePages[n]})`)
|
||||
const links = [...seen].sort()
|
||||
.filter(name => linkedTypePages[name] !== onPage)
|
||||
.map(name => `[${name}](${linkedTypePages[name]})`)
|
||||
if (links.length === 0) return ''
|
||||
return `Types: ${links.join(' · ')}`
|
||||
}
|
||||
|
||||
/** Render one harness event entry. */
|
||||
function renderEvent(e: EventEntry, linkedTypePages: Readonly<Record<string, string>>): string[] {
|
||||
const out = [`### \`${e.name}\` — ${e.mode}`, '']
|
||||
/**
|
||||
* GitHub's heading-slug algorithm (lowercase; drop everything but letters,
|
||||
* numbers, spaces, hyphens; spaces become hyphens). Region headings carry
|
||||
* backticks and em-dashes, which VitePress slugifies differently, so each
|
||||
* generated heading is preceded by an explicit `<a id>` carrying this slug —
|
||||
* the historical flat-catalog anchor — making `#ctx<key>--<class>` fragments
|
||||
* resolve identically on GitHub and the published site.
|
||||
*/
|
||||
function githubSlug(heading: string): string {
|
||||
return heading.toLowerCase().replace(/[^\p{L}\p{N} -]/gu, '').replaceAll(' ', '-')
|
||||
}
|
||||
|
||||
/** The explicit-anchor line emitted before one generated heading. */
|
||||
function anchorFor(headingText: string): string[] {
|
||||
return [`<a id="${githubSlug(headingText)}"></a>`, '']
|
||||
}
|
||||
|
||||
/** Render one harness event entry onto its owning page, nested under its scope heading. */
|
||||
function renderEvent(e: EventEntry, onPage: string, linkedTypePages: Readonly<Record<string, string>>): string[] {
|
||||
const out = [...anchorFor(`${e.name} — ${e.mode}`), `#### \`${e.name}\` — ${e.mode}`, '']
|
||||
if (e.doc) out.push(e.doc, '')
|
||||
out.push('```' + FENCE, e.jsDoc, e.signature, '```', '')
|
||||
const links = typeLinks(e.signature, linkedTypePages)
|
||||
const links = typeLinks(e.signature, onPage, linkedTypePages)
|
||||
if (links) out.push(links, '')
|
||||
out.push(`Source: [\`${e.source}\`](../../${e.source.split(':')[0]})`, '')
|
||||
return out
|
||||
}
|
||||
|
||||
/** Render one harness service entry. */
|
||||
function renderService(s: ServiceEntry, linkedTypePages: Readonly<Record<string, string>>): string[] {
|
||||
/** Render one harness service entry onto its owning page. */
|
||||
function renderService(s: ServiceEntry, onPage: string, linkedTypePages: Readonly<Record<string, string>>): string[] {
|
||||
const kind = s.abstract ? ' (abstract seam)' : ''
|
||||
const out = [`## \`ctx.${s.key}\` — \`${s.type}\`${kind}`, '']
|
||||
const out = [...anchorFor(`ctx.${s.key} — ${s.type}${kind}`), `### \`ctx.${s.key}\` — \`${s.type}\`${kind}`, '']
|
||||
if (s.doc) out.push(s.doc, '')
|
||||
if (s.methods.length) {
|
||||
const declarations = s.methods.flatMap((method, index) => [
|
||||
@@ -728,7 +757,7 @@ function renderService(s: ServiceEntry, linkedTypePages: Readonly<Record<string,
|
||||
method.signature,
|
||||
])
|
||||
out.push('```' + FENCE, ...declarations, '```', '')
|
||||
const links = typeLinks(s.methods.map(method => method.signature).join('\n'), linkedTypePages)
|
||||
const links = typeLinks(s.methods.map(method => method.signature).join('\n'), onPage, linkedTypePages)
|
||||
if (links) out.push(links, '')
|
||||
}
|
||||
out.push(`Source: [\`${s.source}\`](../../${s.source.split(':')[0]})`, '')
|
||||
@@ -746,36 +775,62 @@ const BANNER = [
|
||||
const GATE_NOTICE = 'This file is GENERATED from source (`scripts/gen-cordis-catalog.ts`) and verified fresh by `pnpm run verify-cordis-catalog` (part of `doc-sync`) — do not edit it by hand. Signature blocks use a `ts cordis-catalog` fence and include the original source JSDoc immediately before each event or service method. doc-typecheck skips these bare declaration fragments; type names in a signature link to the page that documents them.'
|
||||
|
||||
/**
|
||||
* Render the events catalog deterministically.
|
||||
* @param events - validated event entries to render.
|
||||
* @param policy - type links and inherited events supplied by the caller.
|
||||
* Render one page's generated `cordis-surface` region: the services mapped to
|
||||
* the page, then the event scopes mapped to it, markers included. Pure and
|
||||
* deterministic given sorted inputs; identical bytes land in both pair sides.
|
||||
* @param page - the owning `docs/subsystems/` page basename, e.g. `core.md`.
|
||||
* @param services - validated services mapped to this page.
|
||||
* @param events - validated events whose scopes map to this page.
|
||||
* @param policy - type links supplied by the caller.
|
||||
* @returns the complete marker-delimited region text.
|
||||
*/
|
||||
export function renderPageRegion(page: string, services: ServiceEntry[], events: EventEntry[], policy: CordisCatalogPolicy): string {
|
||||
const lines: string[] = [
|
||||
REGION_BEGIN,
|
||||
'',
|
||||
'<a id="cordis-surface"></a>',
|
||||
'',
|
||||
'## Cordis surface',
|
||||
'',
|
||||
'Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` surface lives in [cordis-api/inherited.md](../cordis-api/inherited.md).',
|
||||
'',
|
||||
]
|
||||
for (const s of services) lines.push(...renderService(s, page, policy.linkedTypePages))
|
||||
const scopes = [...new Set(events.map(e => e.scope))].sort()
|
||||
for (const scope of scopes) {
|
||||
lines.push(...anchorFor(`${scope}/* events`), `### \`${scope}/*\` events`, '')
|
||||
for (const e of events.filter(x => x.scope === scope).sort((a, b) => a.name.localeCompare(b.name))) {
|
||||
lines.push(...renderEvent(e, page, policy.linkedTypePages))
|
||||
}
|
||||
}
|
||||
while (lines.at(-1) === '') lines.pop()
|
||||
lines.push(REGION_END)
|
||||
return lines.join('\n')
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the inherited (pinned vendor) tier as its own generated page.
|
||||
* @param policy - inherited events and services supplied by the caller.
|
||||
* @returns the complete generated Markdown document.
|
||||
*/
|
||||
export function renderEvents(events: EventEntry[], policy: CordisCatalogPolicy): string {
|
||||
export function renderInheritedPage(policy: CordisCatalogPolicy): string {
|
||||
const lines: string[] = [
|
||||
...BANNER,
|
||||
'# Cordis Events Catalog',
|
||||
'# Inherited Cordis Surface',
|
||||
'',
|
||||
'Every cordis event a plugin can listen to: exact signature, dispatch mode, and original declaration JSDoc. This is one axis of the **wiring** reference a plugin author works against — the callable `ctx.<key>` surface is the sibling [services catalog](services.md), and [core-data-structures/](../core-data-structures/core.md) catalogs the *data structures* these signatures move around.',
|
||||
'The framework `ctx` members and events every plugin sees beyond the harness tier — pinned vendor source ([vendoring policy](../../vendor/README.md)), summarized tersely so the harness pages stay focused on repository-owned vocabulary. Detailed Context, Fiber, Registry, and Service APIs are generated in [context.md](context.md), [fiber.md](fiber.md), [registry.md](registry.md), and [service.md](service.md); the event-dispatch methods in [events.md](events.md).',
|
||||
'',
|
||||
GATE_NOTICE,
|
||||
'',
|
||||
'The **harness tier** below (the `@deepseek-ai/dsh-*` packages) is the vocabulary this repo owns, grouped by scope. The **inherited tier** at the end is the cordis-core + loader/hmr/timer event surface a plugin also sees — pinned vendor source, summarized tersely. The event-dispatch methods themselves are generated in the [Cordis core Events API](core/events.md).',
|
||||
'',
|
||||
'Dispatch modes: **emit** (fire-and-forget), **waterfall** (each listener gets `next()` and may transform or veto — see [waterfall semantics](../cordis-primer.md#cordis-waterfall-semantics)), **parallel** (awaited fan-out; all listeners run), **serial** (awaited in registration order until one returns a bail value — anything other than `null`, `false`, or `undefined`).',
|
||||
'## Inherited `ctx` members (cordis core + loader/hmr/timer)',
|
||||
'',
|
||||
]
|
||||
const scopes = [...new Set(events.map(e => e.scope))].sort()
|
||||
for (const scope of scopes) {
|
||||
lines.push(`## \`${scope}/*\``, '')
|
||||
for (const e of events.filter(x => x.scope === scope).sort((a, b) => a.name.localeCompare(b.name))) {
|
||||
lines.push(...renderEvent(e, policy.linkedTypePages))
|
||||
}
|
||||
for (const s of policy.inheritedServices) {
|
||||
lines.push(`- \`${s.name}\` — ${s.summary} ([\`${s.source}\`](../../${s.source.split(':')[0]}))`)
|
||||
}
|
||||
lines.push(
|
||||
'## Inherited events (cordis core + loader/hmr/timer)',
|
||||
'',
|
||||
'The framework events every plugin also sees, beyond the harness vocabulary above. This is pinned vendor source ([vendoring policy](../../vendor/README.md)); it is summarized here so the page is a complete picture of the event bus, without elevating framework internals to the harness tier\'s prominence.',
|
||||
'## Inherited events (cordis core + loader/hmr/timer)',
|
||||
'',
|
||||
)
|
||||
for (const e of policy.inheritedEvents) {
|
||||
@@ -784,35 +839,3 @@ export function renderEvents(events: EventEntry[], policy: CordisCatalogPolicy):
|
||||
lines.push('')
|
||||
return lines.join('\n')
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the services catalog deterministically.
|
||||
* @param services - validated service entries to render.
|
||||
* @param policy - type links and inherited services supplied by the caller.
|
||||
* @returns the complete generated Markdown document.
|
||||
*/
|
||||
export function renderServices(services: ServiceEntry[], policy: CordisCatalogPolicy): string {
|
||||
const lines: string[] = [
|
||||
...BANNER,
|
||||
'# Cordis Services Catalog',
|
||||
'',
|
||||
'Every `ctx.<key>` service a plugin can call: the exact public interface with original method JSDoc, plus the class JSDoc. This is one axis of the **wiring** reference a plugin author works against — the events a plugin listens to are the sibling [events catalog](events.md), and [core-data-structures/](../core-data-structures/core.md) catalogs the *data structures* these signatures move around. An abstract seam (e.g. `ctx.bash`) is implemented by a separate package; the interface is what consumers code against.',
|
||||
'',
|
||||
GATE_NOTICE,
|
||||
'',
|
||||
'The **harness tier** below (the `@deepseek-ai/dsh-*` packages) is the vocabulary this repo owns. The **inherited tier** at the end is the cordis-core + loader/hmr/timer `ctx` surface a plugin also sees — pinned vendor source, summarized tersely. Detailed Context, Fiber, Registry, and Service APIs are generated in the [Cordis core API](core/context.md).',
|
||||
'',
|
||||
]
|
||||
for (const s of services) lines.push(...renderService(s, policy.linkedTypePages))
|
||||
lines.push(
|
||||
'## Inherited `ctx` members (cordis core + loader/hmr/timer)',
|
||||
'',
|
||||
'The framework `ctx` surface every plugin also sees, beyond the harness services above. This is pinned vendor source ([vendoring policy](../../vendor/README.md)); it is summarized here so the page is a complete picture of what `ctx` offers, without elevating framework internals to the harness tier\'s prominence.',
|
||||
'',
|
||||
)
|
||||
for (const s of policy.inheritedServices) {
|
||||
lines.push(`- \`${s.name}\` — ${s.summary} ([\`${s.source}\`](../../${s.source.split(':')[0]}))`)
|
||||
}
|
||||
lines.push('')
|
||||
return lines.join('\n')
|
||||
}
|
||||
|
||||
@@ -10,8 +10,7 @@ import { afterEach, describe, expect, it } from 'vitest'
|
||||
import {
|
||||
collectEvents as collectEventsWithPolicy,
|
||||
collectServices as collectServicesWithPolicy,
|
||||
renderEvents as renderEventsWithPolicy,
|
||||
renderServices as renderServicesWithPolicy,
|
||||
renderPageRegion,
|
||||
} from '../src/cordis-catalog.ts'
|
||||
import type {
|
||||
CordisCatalogPolicy,
|
||||
@@ -35,12 +34,12 @@ function collectServices(root: string): ServiceEntry[] {
|
||||
return collectServicesWithPolicy(root, TEST_POLICY)
|
||||
}
|
||||
|
||||
function renderEvents(events: EventEntry[]): string {
|
||||
return renderEventsWithPolicy(events, TEST_POLICY)
|
||||
function renderEvents(events: EventEntry[], onPage = 'bash.md'): string {
|
||||
return renderPageRegion(onPage, [], events, TEST_POLICY)
|
||||
}
|
||||
|
||||
function renderServices(services: ServiceEntry[]): string {
|
||||
return renderServicesWithPolicy(services, TEST_POLICY)
|
||||
function renderServices(services: ServiceEntry[], onPage = 'bash.md'): string {
|
||||
return renderPageRegion(onPage, services, [], TEST_POLICY)
|
||||
}
|
||||
|
||||
const TYPE_FIXTURES = [
|
||||
@@ -152,10 +151,11 @@ describe.skip('gen-cordis-catalog collectEvents', { timeout: 60_000 }, () => {
|
||||
|
||||
it('accepts linked, foundation, generic-parameter, and explicitly exempt signature types', () => {
|
||||
const events = collectEvents(make(
|
||||
' /**\n * Carry linked and foundation types.\n * @param value - the linked value.\n * @param preset - deployment metadata outside the core catalog.\n * @param signal - cancellation.\n * @mode parallel\n */\n \'fix/typed\'<T extends SessionEvent>(value: Readonly<T>, preset: PresetSpec, signal: AbortSignal): Promise<T>',
|
||||
' /**\n * Carry linked and foundation types.\n * @param value - the linked value.\n * @param preset - deployment metadata documented outside the subsystems catalog.\n * @param signal - cancellation.\n * @mode parallel\n */\n \'fix/typed\'<T extends SessionEvent>(value: Readonly<T>, preset: PresetSpec, signal: AbortSignal): Promise<T>',
|
||||
))
|
||||
expect(events).toHaveLength(1)
|
||||
expect(renderEvents(events)).toContain('Types: [SessionEvent](../core-data-structures/core.md)')
|
||||
expect(renderEvents(events)).toContain('Types: [SessionEvent](core.md)')
|
||||
expect(renderEvents(events, 'core.md')).not.toContain('Types: [SessionEvent]')
|
||||
expect(renderEvents(events)).not.toContain('[PresetSpec]')
|
||||
})
|
||||
|
||||
|
||||
@@ -3,10 +3,10 @@ import { join, resolve } from 'node:path'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import {
|
||||
projectCordisCatalog,
|
||||
renderEvents,
|
||||
renderServices,
|
||||
renderInheritedPage,
|
||||
renderPageRegion,
|
||||
} from '../src/cordis-catalog.ts'
|
||||
import { CORDIS_CATALOG_POLICY } from '../../../../scripts/gen-cordis-catalog.ts'
|
||||
import { CORDIS_CATALOG_POLICY, EVENT_SCOPE_PAGE, REGION_BEGIN, REGION_END, SERVICE_PAGE } from '../../../../scripts/gen-cordis-catalog.ts'
|
||||
|
||||
const workspaceRoot = resolve(import.meta.dirname, '../../../..')
|
||||
|
||||
@@ -15,10 +15,24 @@ describe('Typert-backed Cordis catalog', () => {
|
||||
const { projector, model } = projectCordisCatalog(workspaceRoot, CORDIS_CATALOG_POLICY)
|
||||
const expected = (path: string): string => readFileSync(join(workspaceRoot, path), 'utf8')
|
||||
|
||||
expect(renderEvents([...model.events], CORDIS_CATALOG_POLICY)).toBe(expected('docs/cordis-catalog/events.md'))
|
||||
expect(renderServices([...model.services], CORDIS_CATALOG_POLICY)).toBe(expected('docs/cordis-catalog/services.md'))
|
||||
expect(renderInheritedPage(CORDIS_CATALOG_POLICY)).toBe(expected('docs/cordis-api/inherited.md'))
|
||||
for (const page of [...new Set([...Object.values(SERVICE_PAGE), ...Object.values(EVENT_SCOPE_PAGE)])].sort()) {
|
||||
const region = renderPageRegion(
|
||||
page,
|
||||
[...model.services].filter(s => SERVICE_PAGE[s.key] === page),
|
||||
[...model.events].filter(e => EVENT_SCOPE_PAGE[e.scope] === page),
|
||||
CORDIS_CATALOG_POLICY,
|
||||
)
|
||||
for (const side of [page, page.replace(/\.md$/, '.zh.md')]) {
|
||||
const committed = expected(`docs/subsystems/${side}`)
|
||||
const begin = committed.indexOf(REGION_BEGIN)
|
||||
const end = committed.indexOf(REGION_END)
|
||||
expect(begin, `docs/subsystems/${side} carries the region`).toBeGreaterThanOrEqual(0)
|
||||
expect(committed.slice(begin, end + REGION_END.length)).toBe(region)
|
||||
}
|
||||
}
|
||||
expect(projector.renderRuntimeApi(model)).toBe(
|
||||
expected('packages/cordis/tool-cordis/src/api-catalog.ts'),
|
||||
expected('packages/self-modification/tool-cordis/src/api-catalog.ts'),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -424,7 +424,7 @@ describe('WorkspaceAnalyzer', { timeout: 60_000 }, () => {
|
||||
|
||||
it('rejects relative imports across face boundaries', () => {
|
||||
const root = copyFixture('typert-relative-face-')
|
||||
const sourcePath = join(root, 'packages/client/src/index.ts')
|
||||
const sourcePath = join(root, 'packages/client', 'src/index.ts')
|
||||
const source = readFileSync(sourcePath, 'utf8')
|
||||
.replace("from '@fixture/host'", "from '../../host/src/index.ts'")
|
||||
writeFileSync(sourcePath, source)
|
||||
@@ -440,7 +440,7 @@ describe('WorkspaceAnalyzer', { timeout: 60_000 }, () => {
|
||||
join(root, 'packages/host/src/private.ts'),
|
||||
'export interface PrivateHost { readonly value: string }\n',
|
||||
)
|
||||
const sourcePath = join(root, 'packages/client/src/index.ts')
|
||||
const sourcePath = join(root, 'packages/client', 'src/index.ts')
|
||||
const source = readFileSync(sourcePath, 'utf8')
|
||||
.replace(
|
||||
"import type { HostAgent, Payload } from '@fixture/host'",
|
||||
@@ -463,7 +463,7 @@ describe('WorkspaceAnalyzer', { timeout: 60_000 }, () => {
|
||||
join(root, 'packages/host/src/private.ts'),
|
||||
'export interface PrivateHost { readonly value: string }\n',
|
||||
)
|
||||
const sourcePath = join(root, 'packages/client/src/index.ts')
|
||||
const sourcePath = join(root, 'packages/client', 'src/index.ts')
|
||||
writeFileSync(sourcePath, [
|
||||
readFileSync(sourcePath, 'utf8'),
|
||||
"export type { PrivateHost } from '@fixture/host/private'",
|
||||
@@ -477,7 +477,7 @@ describe('WorkspaceAnalyzer', { timeout: 60_000 }, () => {
|
||||
|
||||
it('rejects cross-face namespace re-exports until the model has a namespace target', () => {
|
||||
const root = copyFixture('typert-namespace-reexport-')
|
||||
const sourcePath = join(root, 'packages/client/src/index.ts')
|
||||
const sourcePath = join(root, 'packages/client', 'src/index.ts')
|
||||
writeFileSync(sourcePath, [
|
||||
readFileSync(sourcePath, 'utf8'),
|
||||
"export type * as HostNamespace from '@fixture/host'",
|
||||
@@ -492,10 +492,10 @@ describe('WorkspaceAnalyzer', { timeout: 60_000 }, () => {
|
||||
it('ignores cross-face namespace exports that are not package exports', () => {
|
||||
const root = copyFixture('typert-private-namespace-reexport-')
|
||||
writeFileSync(
|
||||
join(root, 'packages/client/src/internal.ts'),
|
||||
join(root, 'packages/client', 'src/internal.ts'),
|
||||
"export type * as HiddenHostNamespace from '@fixture/host'\n",
|
||||
)
|
||||
const sourcePath = join(root, 'packages/client/src/index.ts')
|
||||
const sourcePath = join(root, 'packages/client', 'src/index.ts')
|
||||
writeFileSync(sourcePath, [
|
||||
"import './internal.ts'",
|
||||
readFileSync(sourcePath, 'utf8'),
|
||||
@@ -508,7 +508,7 @@ describe('WorkspaceAnalyzer', { timeout: 60_000 }, () => {
|
||||
|
||||
it('records public symbols from explicit cross-face star re-exports', () => {
|
||||
const root = copyFixture('typert-star-reexport-')
|
||||
const sourcePath = join(root, 'packages/client/src/index.ts')
|
||||
const sourcePath = join(root, 'packages/client', 'src/index.ts')
|
||||
writeFileSync(
|
||||
sourcePath,
|
||||
readFileSync(sourcePath, 'utf8')
|
||||
@@ -1143,7 +1143,7 @@ describe('WorkspaceTypertGenerator', { timeout: 60_000 }, () => {
|
||||
|
||||
it('rejects a public Typert subpath that points outside the root-level face artifact', () => {
|
||||
const root = copyFixture('typert-artifact-path-')
|
||||
const manifestPath = join(root, 'packages/client/package.json')
|
||||
const manifestPath = join(root, 'packages/client', 'package.json')
|
||||
const manifest = JSON.parse(readFileSync(manifestPath, 'utf8')) as {
|
||||
exports: Record<string, { types: string; default: string }>
|
||||
}
|
||||
@@ -1159,7 +1159,7 @@ describe('WorkspaceTypertGenerator', { timeout: 60_000 }, () => {
|
||||
|
||||
it('rejects absent Typert exports and package file entries', () => {
|
||||
const noSubpathRoot = copyFixture('typert-missing-artifact-export-')
|
||||
const noSubpathManifest = join(noSubpathRoot, 'packages/client/package.json')
|
||||
const noSubpathManifest = join(noSubpathRoot, 'packages/client', 'package.json')
|
||||
const noSubpath = JSON.parse(readFileSync(noSubpathManifest, 'utf8')) as Record<string, unknown>
|
||||
noSubpath.exports = './lib/index.js'
|
||||
writeFileSync(noSubpathManifest, `${JSON.stringify(noSubpath, null, 2)}\n`)
|
||||
@@ -1168,7 +1168,7 @@ describe('WorkspaceTypertGenerator', { timeout: 60_000 }, () => {
|
||||
)
|
||||
|
||||
const invalidSubpathRoot = copyFixture('typert-invalid-artifact-export-')
|
||||
const invalidSubpathManifest = join(invalidSubpathRoot, 'packages/client/package.json')
|
||||
const invalidSubpathManifest = join(invalidSubpathRoot, 'packages/client', 'package.json')
|
||||
const invalidSubpath = JSON.parse(readFileSync(invalidSubpathManifest, 'utf8')) as {
|
||||
exports: Record<string, unknown>
|
||||
}
|
||||
@@ -1179,7 +1179,7 @@ describe('WorkspaceTypertGenerator', { timeout: 60_000 }, () => {
|
||||
)
|
||||
|
||||
const noFilesRoot = copyFixture('typert-missing-artifact-files-')
|
||||
const noFilesManifest = join(noFilesRoot, 'packages/client/package.json')
|
||||
const noFilesManifest = join(noFilesRoot, 'packages/client', 'package.json')
|
||||
const noFiles = JSON.parse(readFileSync(noFilesManifest, 'utf8')) as Record<string, unknown>
|
||||
delete noFiles.files
|
||||
writeFileSync(noFilesManifest, `${JSON.stringify(noFiles, null, 2)}\n`)
|
||||
@@ -1269,14 +1269,14 @@ function configureDualRuntimeClient(root: string, splitProjects: boolean): void
|
||||
const hostAggregate = JSON.parse(readFileSync(hostAggregatePath, 'utf8')) as {
|
||||
references: { path: string }[]
|
||||
}
|
||||
hostAggregate.references.push({ path: './packages/client/tsconfig.host.json' })
|
||||
hostAggregate.references.push({ path: ['.', 'packages', 'client', 'tsconfig.host.json'].join('/') })
|
||||
writeFileSync(hostAggregatePath, `${JSON.stringify(hostAggregate, null, 2)}\n`)
|
||||
|
||||
const clientAggregatePath = join(root, 'tsconfig.client.json')
|
||||
const clientAggregate = JSON.parse(readFileSync(clientAggregatePath, 'utf8')) as {
|
||||
references: { path: string }[]
|
||||
}
|
||||
clientAggregate.references = [{ path: './packages/client/tsconfig.client.json' }]
|
||||
clientAggregate.references = [{ path: ['.', 'packages', 'client', 'tsconfig.client.json'].join('/') }]
|
||||
writeFileSync(clientAggregatePath, `${JSON.stringify(clientAggregate, null, 2)}\n`)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user