@briancray/belte 0.2.0 → 0.2.2
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/package.json +1 -1
- package/src/belteResolverPlugin.ts +26 -11
- package/src/lib/shared/belteImportName.test.ts +58 -0
- package/src/lib/shared/belteImportName.ts +45 -0
- package/src/lib/shared/beltePackageName.ts +7 -0
- package/src/lib/shared/prepareRpcModule.ts +14 -4
- package/src/lib/shared/prepareSocketModule.ts +16 -2
- package/src/lib/shared/writeRoutesDts.ts +7 -2
- package/template/package.json +1 -1
- package/template/src/app.ts +1 -1
- package/template/src/browser/pages/page.svelte +1 -1
- package/template/src/server/rpc/getHello.ts +2 -2
- package/template/svelte.config.js +1 -1
- package/template/tsconfig.json +1 -1
package/package.json
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { existsSync, statSync } from 'node:fs'
|
|
3
3
|
import type { BunPlugin } from 'bun'
|
|
4
4
|
import { Glob } from 'bun'
|
|
5
|
+
import { belteImportName } from './lib/shared/belteImportName.ts'
|
|
5
6
|
import { fileStem } from './lib/shared/fileStem.ts'
|
|
6
7
|
import { jsonSchemaForPromptArguments } from './lib/shared/jsonSchemaForPromptArguments.ts'
|
|
7
8
|
import { log } from './lib/shared/log.ts'
|
|
@@ -111,6 +112,13 @@ export function belteResolverPlugin({
|
|
|
111
112
|
const promptsDir = `${mcpDir}/prompts`
|
|
112
113
|
const resourcesDir = `${mcpDir}/resources`
|
|
113
114
|
|
|
115
|
+
/*
|
|
116
|
+
The bare specifier the project imports belte under (canonical
|
|
117
|
+
`@briancray/belte` or a package alias). Resolved once from the project's
|
|
118
|
+
package.json and threaded into every generated module so the codegen's
|
|
119
|
+
imports resolve regardless of which install style the project uses.
|
|
120
|
+
*/
|
|
121
|
+
const belteImportNameOnce = once(() => belteImportName(cwd))
|
|
114
122
|
/*
|
|
115
123
|
The whole-tree validation + per-leaf classification only needs to run
|
|
116
124
|
once per build. Memoise the promise so the virtual manifests
|
|
@@ -120,7 +128,11 @@ export function belteResolverPlugin({
|
|
|
120
128
|
*/
|
|
121
129
|
const scanPagesOnce = once(() =>
|
|
122
130
|
scanPages(pagesDir).then(async (scan) => {
|
|
123
|
-
await writeRoutesDts({
|
|
131
|
+
await writeRoutesDts({
|
|
132
|
+
cwd,
|
|
133
|
+
pageFiles: scan.pageFiles,
|
|
134
|
+
importName: await belteImportNameOnce(),
|
|
135
|
+
})
|
|
124
136
|
return scan
|
|
125
137
|
}),
|
|
126
138
|
)
|
|
@@ -176,7 +188,8 @@ export function belteResolverPlugin({
|
|
|
176
188
|
const relativePath = args.path.slice(rpcDir.length + 1)
|
|
177
189
|
const source = await Bun.file(args.path).text()
|
|
178
190
|
const url = rpcUrlForFile(relativePath)
|
|
179
|
-
const
|
|
191
|
+
const importName = await belteImportNameOnce()
|
|
192
|
+
const prepared = prepareRpcModule(source, importName)
|
|
180
193
|
if (!prepared) {
|
|
181
194
|
throw new Error(
|
|
182
195
|
`[belte] src/server/rpc/${relativePath} has no \`export const <name> = <VERB>(...)\` — every $rpc module must declare exactly one remote function`,
|
|
@@ -196,7 +209,7 @@ export function belteResolverPlugin({
|
|
|
196
209
|
so page imports resolve identically on both sides.
|
|
197
210
|
*/
|
|
198
211
|
if (target === 'client') {
|
|
199
|
-
const contents = `import { remoteProxy as __belteRemoteProxy__ } from '
|
|
212
|
+
const contents = `import { remoteProxy as __belteRemoteProxy__ } from '${importName}/browser/remoteProxy';
|
|
200
213
|
export const ${prepared.exportName} = __belteRemoteProxy__(${JSON.stringify(prepared.verb)}, ${JSON.stringify(url)});
|
|
201
214
|
`
|
|
202
215
|
return { contents, loader: 'ts' }
|
|
@@ -211,7 +224,7 @@ export const ${prepared.exportName} = __belteRemoteProxy__(${JSON.stringify(prep
|
|
|
211
224
|
tokenizer-driven so `GET` mentions inside strings and
|
|
212
225
|
comments are left alone.
|
|
213
226
|
*/
|
|
214
|
-
const banner = `import { defineVerb as __belteDefineVerb__ } from '
|
|
227
|
+
const banner = `import { defineVerb as __belteDefineVerb__ } from '${importName}/server/rpc/defineVerb';
|
|
215
228
|
`
|
|
216
229
|
return { contents: `${banner}${prepared.rewriteForServer(url)}`, loader: 'ts' }
|
|
217
230
|
})
|
|
@@ -223,7 +236,8 @@ export const ${prepared.exportName} = __belteRemoteProxy__(${JSON.stringify(prep
|
|
|
223
236
|
const relativePath = args.path.slice(socketsDir.length + 1)
|
|
224
237
|
const source = await Bun.file(args.path).text()
|
|
225
238
|
const name = socketNameForFile(relativePath)
|
|
226
|
-
const
|
|
239
|
+
const importName = await belteImportNameOnce()
|
|
240
|
+
const prepared = prepareSocketModule(source, importName)
|
|
227
241
|
if (!prepared) {
|
|
228
242
|
throw new Error(
|
|
229
243
|
`[belte] src/server/sockets/${relativePath} has no \`export const <name> = socket(...)\` — every $sockets module must declare exactly one socket`,
|
|
@@ -241,12 +255,12 @@ export const ${prepared.exportName} = __belteRemoteProxy__(${JSON.stringify(prep
|
|
|
241
255
|
clientPublish) are server-side state and don't
|
|
242
256
|
affect the client's wire behaviour.
|
|
243
257
|
*/
|
|
244
|
-
const contents = `import { socketProxy as __belteSocketProxy__ } from '
|
|
258
|
+
const contents = `import { socketProxy as __belteSocketProxy__ } from '${importName}/browser/socketProxy';
|
|
245
259
|
export const ${prepared.exportName} = __belteSocketProxy__(${JSON.stringify(name)});
|
|
246
260
|
`
|
|
247
261
|
return { contents, loader: 'ts' }
|
|
248
262
|
}
|
|
249
|
-
const banner = `import { defineSocket as __belteDefineSocket__ } from '
|
|
263
|
+
const banner = `import { defineSocket as __belteDefineSocket__ } from '${importName}/server/sockets/defineSocket';
|
|
250
264
|
`
|
|
251
265
|
return {
|
|
252
266
|
contents: `${banner}${prepared.rewriteForServer(name)}`,
|
|
@@ -277,6 +291,7 @@ export const ${prepared.exportName} = __belteSocketProxy__(${JSON.stringify(name
|
|
|
277
291
|
const relativePath = args.path.slice(promptsDir.length + 1)
|
|
278
292
|
const source = await Bun.file(args.path).text()
|
|
279
293
|
const name = promptNameForFile(relativePath)
|
|
294
|
+
const importName = await belteImportNameOnce()
|
|
280
295
|
const parsed = parsePromptMarkdown(source)
|
|
281
296
|
const jsonSchema = jsonSchemaForPromptArguments(parsed.arguments)
|
|
282
297
|
const optionLines = [
|
|
@@ -288,8 +303,8 @@ export const ${prepared.exportName} = __belteSocketProxy__(${JSON.stringify(name
|
|
|
288
303
|
]
|
|
289
304
|
.filter((line) => line !== undefined)
|
|
290
305
|
.join('\n')
|
|
291
|
-
const contents = `import { definePrompt as __belteDefinePrompt__ } from '
|
|
292
|
-
import { renderPromptTemplate as __belteRenderPromptTemplate__ } from '
|
|
306
|
+
const contents = `import { definePrompt as __belteDefinePrompt__ } from '${importName}/server/prompts/definePrompt'
|
|
307
|
+
import { renderPromptTemplate as __belteRenderPromptTemplate__ } from '${importName}/server/prompts/renderPromptTemplate'
|
|
293
308
|
const __template__ = ${JSON.stringify(parsed.body)}
|
|
294
309
|
export const prompt = __belteDefinePrompt__(${JSON.stringify(name)}, {
|
|
295
310
|
${optionLines}
|
|
@@ -574,9 +589,9 @@ export const footer = ${JSON.stringify(footer)}
|
|
|
574
589
|
from src/mcp/resources. createMcpServer is internal; there
|
|
575
590
|
is no user-authored server module.
|
|
576
591
|
*/
|
|
592
|
+
const importName = await belteImportNameOnce()
|
|
577
593
|
return {
|
|
578
|
-
contents:
|
|
579
|
-
"import { createMcpServer } from 'belte/mcp/createMcpServer'\nexport default createMcpServer()\n",
|
|
594
|
+
contents: `import { createMcpServer } from '${importName}/mcp/createMcpServer'\nexport default createMcpServer()\n`,
|
|
580
595
|
loader: 'js',
|
|
581
596
|
}
|
|
582
597
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { afterAll, expect, test } from 'bun:test'
|
|
2
|
+
import { mkdtempSync, rmSync } from 'node:fs'
|
|
3
|
+
import { tmpdir } from 'node:os'
|
|
4
|
+
import { belteImportName } from './belteImportName.ts'
|
|
5
|
+
|
|
6
|
+
const roots: string[] = []
|
|
7
|
+
afterAll(() => roots.forEach((root) => rmSync(root, { recursive: true, force: true })))
|
|
8
|
+
|
|
9
|
+
// Writes a package.json into a fresh temp dir and returns the dir.
|
|
10
|
+
async function projectWith(packageJson: unknown): Promise<string> {
|
|
11
|
+
const root = mkdtempSync(`${tmpdir()}/belte-import-name-`)
|
|
12
|
+
roots.push(root)
|
|
13
|
+
await Bun.write(`${root}/package.json`, JSON.stringify(packageJson))
|
|
14
|
+
return root
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
test('uses the canonical name for a direct dependency', async () => {
|
|
18
|
+
const cwd = await projectWith({ dependencies: { '@briancray/belte': '^0.2.0' } })
|
|
19
|
+
expect(await belteImportName(cwd)).toBe('@briancray/belte')
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
test('uses the `belte` alias key for an npm alias', async () => {
|
|
23
|
+
const cwd = await projectWith({ dependencies: { belte: 'npm:@briancray/belte@^0.2.0' } })
|
|
24
|
+
expect(await belteImportName(cwd)).toBe('belte')
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
test('uses the `belte` alias key for a workspace alias', async () => {
|
|
28
|
+
const cwd = await projectWith({ dependencies: { belte: 'workspace:@briancray/belte@*' } })
|
|
29
|
+
expect(await belteImportName(cwd)).toBe('belte')
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
test('uses a non-`belte` alias key when that is how belte is declared', async () => {
|
|
33
|
+
const cwd = await projectWith({ dependencies: { framework: 'npm:@briancray/belte' } })
|
|
34
|
+
expect(await belteImportName(cwd)).toBe('framework')
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
test('prefers the `belte` alias over a direct canonical dependency', async () => {
|
|
38
|
+
const cwd = await projectWith({
|
|
39
|
+
dependencies: { '@briancray/belte': '^0.2.0', belte: 'npm:@briancray/belte@^0.2.0' },
|
|
40
|
+
})
|
|
41
|
+
expect(await belteImportName(cwd)).toBe('belte')
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
test('finds the alias in devDependencies', async () => {
|
|
45
|
+
const cwd = await projectWith({ devDependencies: { belte: 'npm:@briancray/belte@^0.2.0' } })
|
|
46
|
+
expect(await belteImportName(cwd)).toBe('belte')
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
test('falls back to the canonical name when belte is absent', async () => {
|
|
50
|
+
const cwd = await projectWith({ dependencies: { svelte: '^5.0.0' } })
|
|
51
|
+
expect(await belteImportName(cwd)).toBe('@briancray/belte')
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
test('falls back to the canonical name when package.json is missing', async () => {
|
|
55
|
+
const root = mkdtempSync(`${tmpdir()}/belte-import-name-`)
|
|
56
|
+
roots.push(root)
|
|
57
|
+
expect(await belteImportName(root)).toBe('@briancray/belte')
|
|
58
|
+
})
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { beltePackageName } from './beltePackageName.ts'
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
Resolves the bare specifier prefix a consuming project imports belte under —
|
|
5
|
+
the name belte is installed as in its package.json. A project may depend on
|
|
6
|
+
belte directly (`@briancray/belte`) or behind a package alias
|
|
7
|
+
(`"belte": "npm:@briancray/belte@..."`, or `workspace:@briancray/belte@*`
|
|
8
|
+
inside this repo). An alias-only install resolves only under the alias key and
|
|
9
|
+
a direct install only under the canonical name, so the generated rpc / socket
|
|
10
|
+
/ prompt modules must import under whichever name the project actually
|
|
11
|
+
declared.
|
|
12
|
+
|
|
13
|
+
Prefers a `belte` alias (the ergonomic surface the docs use) when present, then
|
|
14
|
+
a direct canonical dependency, then any other alias targeting belte. Falls back
|
|
15
|
+
to the canonical name when belte isn't found in package.json — the build can't
|
|
16
|
+
resolve belte at all in that case, and the canonical name yields the clearest
|
|
17
|
+
resolution error.
|
|
18
|
+
*/
|
|
19
|
+
export async function belteImportName(cwd: string): Promise<string> {
|
|
20
|
+
const packageJsonPath = `${cwd}/package.json`
|
|
21
|
+
if (!(await Bun.file(packageJsonPath).exists())) {
|
|
22
|
+
return beltePackageName
|
|
23
|
+
}
|
|
24
|
+
const packageJson = (await Bun.file(packageJsonPath).json()) as {
|
|
25
|
+
dependencies?: Record<string, string>
|
|
26
|
+
devDependencies?: Record<string, string>
|
|
27
|
+
}
|
|
28
|
+
const dependencies = { ...packageJson.devDependencies, ...packageJson.dependencies }
|
|
29
|
+
/*
|
|
30
|
+
Alias entries whose target is belte — `npm:` for a published install,
|
|
31
|
+
`workspace:` for the in-repo examples. The key is the name the project
|
|
32
|
+
imports under; the version suffix (`@^0.2.0`, `@*`) is optional.
|
|
33
|
+
*/
|
|
34
|
+
const aliasPattern = new RegExp(`^(npm|workspace):${beltePackageName}(@.*)?$`)
|
|
35
|
+
const aliasNames = Object.entries(dependencies)
|
|
36
|
+
.filter(([, specifier]) => aliasPattern.test(specifier))
|
|
37
|
+
.map(([name]) => name)
|
|
38
|
+
if (aliasNames.includes('belte')) {
|
|
39
|
+
return 'belte'
|
|
40
|
+
}
|
|
41
|
+
if (beltePackageName in dependencies) {
|
|
42
|
+
return beltePackageName
|
|
43
|
+
}
|
|
44
|
+
return aliasNames[0] ?? beltePackageName
|
|
45
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/*
|
|
2
|
+
The package's published npm name. The codegen and the import-name resolver
|
|
3
|
+
match a consuming project's dependency (direct or aliased) against this to
|
|
4
|
+
decide which specifier to emit, so keeping it in one place means a future
|
|
5
|
+
rename touches a single constant.
|
|
6
|
+
*/
|
|
7
|
+
export const beltePackageName = '@briancray/belte'
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { HttpVerb } from '../server/rpc/types/HttpVerb.ts'
|
|
2
|
+
import { beltePackageName } from './beltePackageName.ts'
|
|
2
3
|
import { findExportCallSite } from './findExportCallSite.ts'
|
|
3
4
|
import { stripImport } from './stripImport.ts'
|
|
4
5
|
|
|
5
6
|
const VERB_NAMES = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD'] as const
|
|
6
7
|
const VERB_SET = new Set<string>(VERB_NAMES)
|
|
7
|
-
const VERB_IMPORT_PATHS = VERB_NAMES.map((verb) => `belte/server/${verb}`)
|
|
8
8
|
|
|
9
9
|
const SINGLE_EXPORT_ERROR =
|
|
10
10
|
'[belte] $rpc module contains more than one `<VERB>(...)` export — each file must declare exactly one remote function'
|
|
@@ -27,14 +27,24 @@ A regex pass would be tidier but it can't tell a `GET` mention inside a
|
|
|
27
27
|
docstring or template literal from the real call, and it can't follow
|
|
28
28
|
nested generics like `GET<Map<K, V>>(`.
|
|
29
29
|
*/
|
|
30
|
-
export function prepareRpcModule(
|
|
30
|
+
export function prepareRpcModule(
|
|
31
|
+
source: string,
|
|
32
|
+
importName: string,
|
|
33
|
+
): PreparedRpcModule | undefined {
|
|
31
34
|
/*
|
|
32
35
|
The "no barrels" surface places each verb at its own path
|
|
33
36
|
(`belte/server/GET`, `belte/server/POST`, …) — strip every one so
|
|
34
37
|
the user's verb import doesn't linger and side-effect-load the
|
|
35
|
-
stub module into the server bundle.
|
|
38
|
+
stub module into the server bundle. The user may import under the
|
|
39
|
+
project's chosen name or the canonical package name, so strip both.
|
|
36
40
|
*/
|
|
37
|
-
const
|
|
41
|
+
const importNames =
|
|
42
|
+
importName === beltePackageName ? [beltePackageName] : [importName, beltePackageName]
|
|
43
|
+
const stripped = importNames.reduce(
|
|
44
|
+
(current, name) =>
|
|
45
|
+
VERB_NAMES.reduce((acc, verb) => stripImport(acc, `${name}/server/${verb}`), current),
|
|
46
|
+
source,
|
|
47
|
+
)
|
|
38
48
|
const site = findExportCallSite(stripped, (ident) => VERB_SET.has(ident), SINGLE_EXPORT_ERROR)
|
|
39
49
|
if (!site) {
|
|
40
50
|
return undefined
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { beltePackageName } from './beltePackageName.ts'
|
|
1
2
|
import { findExportCallSite } from './findExportCallSite.ts'
|
|
2
3
|
import { stripImport } from './stripImport.ts'
|
|
3
4
|
|
|
@@ -17,8 +18,21 @@ original source). The single scan replaces the prior separate
|
|
|
17
18
|
extract + rewrite passes, so the resolver plugin only walks each source
|
|
18
19
|
character-by-character once.
|
|
19
20
|
*/
|
|
20
|
-
export function prepareSocketModule(
|
|
21
|
-
|
|
21
|
+
export function prepareSocketModule(
|
|
22
|
+
source: string,
|
|
23
|
+
importName: string,
|
|
24
|
+
): PreparedSocketModule | undefined {
|
|
25
|
+
/*
|
|
26
|
+
Strip the user's `socket` import under the project's chosen name and the
|
|
27
|
+
canonical package name so the dead import can't side-effect-load the
|
|
28
|
+
socket helper into the server bundle.
|
|
29
|
+
*/
|
|
30
|
+
const importNames =
|
|
31
|
+
importName === beltePackageName ? [beltePackageName] : [importName, beltePackageName]
|
|
32
|
+
const stripped = importNames.reduce(
|
|
33
|
+
(current, name) => stripImport(current, `${name}/server/socket`),
|
|
34
|
+
source,
|
|
35
|
+
)
|
|
22
36
|
const site = findExportCallSite(stripped, (ident) => ident === 'socket', SINGLE_EXPORT_ERROR)
|
|
23
37
|
if (!site) {
|
|
24
38
|
return undefined
|
|
@@ -30,14 +30,19 @@ page file in the project. Page picks this up as a discriminated union keyed
|
|
|
30
30
|
on `route`, so `if (page.route === '/media/[id]') page.params.id` is typed
|
|
31
31
|
automatically without consumers writing route types by hand.
|
|
32
32
|
The file is written to `src/.belte/routes.d.ts` so the consumer's existing
|
|
33
|
-
src tsconfig include picks it up with no extra configuration.
|
|
33
|
+
src tsconfig include picks it up with no extra configuration. The augmented
|
|
34
|
+
module is keyed on the name the project imports belte under (`importName`),
|
|
35
|
+
so the augmentation matches the consumer's `page` import whether belte is
|
|
36
|
+
installed directly (`@briancray/belte`) or behind an alias.
|
|
34
37
|
*/
|
|
35
38
|
export async function writeRoutesDts({
|
|
36
39
|
cwd,
|
|
37
40
|
pageFiles,
|
|
41
|
+
importName,
|
|
38
42
|
}: {
|
|
39
43
|
cwd: string
|
|
40
44
|
pageFiles: string[]
|
|
45
|
+
importName: string
|
|
41
46
|
}): Promise<void> {
|
|
42
47
|
const entries = pageFiles
|
|
43
48
|
.map((file) => ({
|
|
@@ -50,7 +55,7 @@ export async function writeRoutesDts({
|
|
|
50
55
|
)
|
|
51
56
|
.join('\n')
|
|
52
57
|
const contents = `// Generated by belte. Do not edit by hand.
|
|
53
|
-
declare module '
|
|
58
|
+
declare module '${importName}/browser/page' {
|
|
54
59
|
interface Routes {
|
|
55
60
|
${entries}
|
|
56
61
|
}
|
package/template/package.json
CHANGED
package/template/src/app.ts
CHANGED
|
@@ -7,7 +7,7 @@ module — no import is needed from your own code.
|
|
|
7
7
|
handle middleware wrapping the default request pipeline
|
|
8
8
|
handleError custom 500 fallback
|
|
9
9
|
*/
|
|
10
|
-
import type { AppModule } from 'belte/server/AppModule'
|
|
10
|
+
import type { AppModule } from '@briancray/belte/server/AppModule'
|
|
11
11
|
|
|
12
12
|
export const init: AppModule['init'] = ({ server }) => {
|
|
13
13
|
console.log(`server listening on http://localhost:${server.port}`)
|
|
@@ -3,7 +3,7 @@ Root page — served at GET /. Every folder under src/browser/pages/ that
|
|
|
3
3
|
contains a page.svelte mounts at that folder's URL.
|
|
4
4
|
-->
|
|
5
5
|
<script lang="ts">
|
|
6
|
-
import { cache } from 'belte/browser/cache'
|
|
6
|
+
import { cache } from '@briancray/belte/browser/cache'
|
|
7
7
|
import { getHello } from '$server/rpc/getHello.ts'
|
|
8
8
|
|
|
9
9
|
/*
|
|
@@ -27,7 +27,7 @@ Every rpc value also exposes `.raw(args?)` (returns the underlying
|
|
|
27
27
|
for callers that need headers/status or want to iterate SSE/JSONL frames.
|
|
28
28
|
*/
|
|
29
29
|
|
|
30
|
-
import { GET } from 'belte/server/GET'
|
|
31
|
-
import { json } from 'belte/server/json'
|
|
30
|
+
import { GET } from '@briancray/belte/server/GET'
|
|
31
|
+
import { json } from '@briancray/belte/server/json'
|
|
32
32
|
|
|
33
33
|
export const getHello = GET(() => json({ message: 'Hello from belte' }))
|
|
@@ -3,7 +3,7 @@ Optional Svelte compiler configuration. Same shape as upstream Svelte.
|
|
|
3
3
|
Delete this file to use defaults.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
/** @type {import('belte').SvelteConfig} */
|
|
6
|
+
/** @type {import('@briancray/belte').SvelteConfig} */
|
|
7
7
|
export default {
|
|
8
8
|
compilerOptions: {
|
|
9
9
|
// Opt in to top-level await inside Svelte components.
|
package/template/tsconfig.json
CHANGED