JSR rejects `import ... with { type: "text" }`, which starter_template.ts used
for all ~30 template files (this is why local dry-run passed but the real
publish failed on the module graph). Load the template files at runtime instead
— Deno.readTextFile from a source checkout, fetch from the published JSR package
— via import.meta.resolve.
The text import of env.d.ts had also been masking its ambient ImportMeta
augmentation; boot.ts/pwa.ts now reference it explicitly, and env.d.ts scopes
itself to the app's VITE_* vars so MODE/DEV/PROD come from astro/client without
a modifier conflict.- commit
- 8180d757545a98fc2a290e444124861687f793c2
- parent
- 59d40e92986a27500b68ec590cec34d0a3bfb5ec
- author
- Dami <dami.etoile@gmail.com>
| M | apps/ | 1 | + |
| M | apps/ | 2 | + |
| M | apps/ | 3 | - |
| M | package/ | 5 | +- |
| M | package/ | 159 | +++++++++++------------------- |
| M | package/ | 6 | +- |
@@ -1,5 +1,5 @@
11 import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";2-import { STARTER_TEMPLATE } from "./starter_template.ts";2+import { readStarterFile, STARTER_FILES } from "./starter_template.ts";33 import { LOFI_PACKAGE_PREFIX } from "./version.ts";44 55 export type CreateProjectOptions = {@@ -153,7 +153,8 @@ async function assertNoSymlinkPath(cwd: string, segments: readonly string[]): Pr
153153 }154154 155155 async function writeTemplate(destination: string): Promise<void> {156- for (const [relativePath, content] of Object.entries(STARTER_TEMPLATE)) {156+ for (const relativePath of STARTER_FILES) {157+ const content = await readStarterFile(relativePath);157158 const path = join(destination, relativePath);158159 await Deno.mkdir(dirname(path), { recursive: true });159160 await Deno.writeTextFile(path, content);@@ -1,100 +1,61 @@
1-import denoConfig from "../apps/reference/deno.json" with { type: "text" };2-import astroConfig from "../apps/reference/astro.config.ts" with { type: "text" };3-import favicon from "../apps/reference/public/favicon.svg" with { type: "text" };4-import manifest from "../apps/reference/public/manifest.webmanifest" with { type: "text" };5-import serviceWorker from "../apps/reference/public/sw.js" with { type: "text" };6-import deviceStatus from "../apps/reference/src/_lofi/DeviceStatus.tsx" with { type: "text" };7-import shell from "../apps/reference/src/_lofi/Shell.astro" with { type: "text" };8-import boot from "../apps/reference/src/_lofi/boot.ts" with { type: "text" };9-import config from "../apps/reference/src/_lofi/config.ts" with { type: "text" };10-import diagnostics from "../apps/reference/src/_lofi/diagnostics.ts" with { type: "text" };11-import tableStore from "../apps/reference/src/_lofi/table-store.ts" with { type: "text" };12-import tableStoreTest from "../apps/reference/src/_lofi/table-store_test.ts" with {13- type: "text",14-};15-import deviceCapabilities from "../apps/reference/src/_lofi/device-capabilities.ts" with {16- type: "text",17-};18-import deviceCapabilitiesTest from "../apps/reference/src/_lofi/device-capabilities_test.ts" with {19- type: "text",20-};21-import inspector from "../apps/reference/src/_lofi/inspector.ts" with { type: "text" };22-import inspectorTest from "../apps/reference/src/_lofi/inspector_test.ts" with { type: "text" };23-import probe from "../apps/reference/src/_lofi/probe.ts" with { type: "text" };24-import pwa from "../apps/reference/src/_lofi/pwa.ts" with { type: "text" };25-import pwaTest from "../apps/reference/src/_lofi/pwa_test.ts" with { type: "text" };26-import resourceLifecycle from "../apps/reference/src/_lofi/resource-lifecycle.ts" with {27- type: "text",28-};29-import resourceLifecycleTest from "../apps/reference/src/_lofi/resource-lifecycle_test.ts" with {30- type: "text",31-};32-import runtime from "../apps/reference/src/_lofi/runtime.ts" with { type: "text" };33-import testAssert from "../apps/reference/src/_lofi/test-assert.ts" with { type: "text" };34-import uiMutation from "../apps/reference/src/_lofi/ui-mutation.ts" with { type: "text" };35-import uiMutationTest from "../apps/reference/src/_lofi/ui-mutation_test.ts" with {36- type: "text",37-};38-import useDeviceCapabilities from "../apps/reference/src/_lofi/use-device-capabilities.ts" with {39- type: "text",40-};41-import useTasks from "../apps/reference/src/islands/use-tasks.ts" with { type: "text" };42-import app from "../apps/reference/src/app.ts" with { type: "text" };43-import environmentTypes from "../apps/reference/src/env.d.ts" with { type: "text" };44-import taskList from "../apps/reference/src/islands/TaskList.tsx" with { type: "text" };45-import indexPage from "../apps/reference/src/pages/index.astro" with { type: "text" };46-import permissions from "../apps/reference/src/permissions.ts" with { type: "text" };47-import schema from "../apps/reference/src/schema.ts" with { type: "text" };48-import globalStyles from "../apps/reference/src/styles/global.css" with { type: "text" };49-import authorBoundaryTest from "../apps/reference/tests/author-boundary_test.ts" with {50- type: "text",51-};52-import testingContractTest from "../apps/reference/tests/testing-contract_test.ts" with {53- type: "text",54-};55-import convergenceExample from "../apps/reference/tests/convergence_e2e_test.ts" with {56- type: "text",57-};58-import tsconfig from "../apps/reference/tsconfig.json" with { type: "text" };1+/**2+ * Every source-controlled file copied from the validated reference app into a3+ * new project, by its path relative to both the reference app and the generated4+ * project. The contents are read at runtime (see {@link readStarterFile}) rather5+ * than imported with `type: "text"`, which JSR does not support when publishing.6+ */7+export const STARTER_FILES: readonly string[] = [8+ "deno.json",9+ "astro.config.ts",10+ "tsconfig.json",11+ "public/favicon.svg",12+ "public/manifest.webmanifest",13+ "public/sw.js",14+ "src/app.ts",15+ "src/env.d.ts",16+ "src/permissions.ts",17+ "src/schema.ts",18+ "src/pages/index.astro",19+ "src/styles/global.css",20+ "src/islands/TaskList.tsx",21+ "src/islands/use-tasks.ts",22+ "src/_lofi/DeviceStatus.tsx",23+ "src/_lofi/Shell.astro",24+ "src/_lofi/boot.ts",25+ "src/_lofi/config.ts",26+ "src/_lofi/diagnostics.ts",27+ "src/_lofi/device-capabilities.ts",28+ "src/_lofi/device-capabilities_test.ts",29+ "src/_lofi/inspector.ts",30+ "src/_lofi/inspector_test.ts",31+ "src/_lofi/probe.ts",32+ "src/_lofi/pwa.ts",33+ "src/_lofi/pwa_test.ts",34+ "src/_lofi/resource-lifecycle.ts",35+ "src/_lofi/resource-lifecycle_test.ts",36+ "src/_lofi/runtime.ts",37+ "src/_lofi/table-store.ts",38+ "src/_lofi/table-store_test.ts",39+ "src/_lofi/test-assert.ts",40+ "src/_lofi/ui-mutation.ts",41+ "src/_lofi/ui-mutation_test.ts",42+ "src/_lofi/use-device-capabilities.ts",43+ "tests/author-boundary_test.ts",44+ "tests/convergence_e2e_test.ts",45+ "tests/testing-contract_test.ts",46+];5947 60-/** Every source-controlled file copied from the validated reference app into a new project. */61-export const STARTER_TEMPLATE: Readonly<Record<string, string>> = {62- "deno.json": denoConfig,63- "astro.config.ts": astroConfig,64- "public/favicon.svg": favicon,65- "public/manifest.webmanifest": manifest,66- "public/sw.js": serviceWorker,67- "src/_lofi/DeviceStatus.tsx": deviceStatus,68- "src/_lofi/Shell.astro": shell,69- "src/_lofi/boot.ts": boot,70- "src/_lofi/config.ts": config,71- "src/_lofi/diagnostics.ts": diagnostics,72- "src/_lofi/device-capabilities.ts": deviceCapabilities,73- "src/_lofi/device-capabilities_test.ts": deviceCapabilitiesTest,74- "src/_lofi/inspector.ts": inspector,75- "src/_lofi/inspector_test.ts": inspectorTest,76- "src/_lofi/probe.ts": probe,77- "src/_lofi/pwa.ts": pwa,78- "src/_lofi/pwa_test.ts": pwaTest,79- "src/_lofi/resource-lifecycle.ts": resourceLifecycle,80- "src/_lofi/resource-lifecycle_test.ts": resourceLifecycleTest,81- "src/_lofi/runtime.ts": runtime,82- "src/_lofi/table-store.ts": tableStore,83- "src/_lofi/table-store_test.ts": tableStoreTest,84- "src/_lofi/test-assert.ts": testAssert,85- "src/_lofi/ui-mutation.ts": uiMutation,86- "src/_lofi/ui-mutation_test.ts": uiMutationTest,87- "src/_lofi/use-device-capabilities.ts": useDeviceCapabilities,88- "src/app.ts": app,89- "src/env.d.ts": environmentTypes,90- "src/islands/TaskList.tsx": taskList,91- "src/islands/use-tasks.ts": useTasks,92- "src/pages/index.astro": indexPage,93- "src/permissions.ts": permissions,94- "src/schema.ts": schema,95- "src/styles/global.css": globalStyles,96- "tests/author-boundary_test.ts": authorBoundaryTest,97- "tests/convergence_e2e_test.ts": convergenceExample,98- "tests/testing-contract_test.ts": testingContractTest,99- "tsconfig.json": tsconfig,100-};48+/**49+ * Reads a starter file's contents, resolving it relative to the reference app.50+ * Works both from a source checkout (a `file:` URL read from disk) and from the51+ * published package (an `https:` JSR URL fetched over the network).52+ */53+export async function readStarterFile(relativePath: string): Promise<string> {54+ const url = import.meta.resolve(`../apps/reference/${relativePath}`);55+ if (url.startsWith("file:")) return await Deno.readTextFile(new URL(url));56+ const response = await fetch(url);57+ if (!response.ok) {58+ throw new Error(`failed to read starter file ${relativePath}: HTTP ${response.status}`);59+ }60+ return await response.text();61+}@@ -7,7 +7,7 @@
77 "public/manifest.webmanifest": "7d492285fd982e6e68fa04f12d78cd4f0bef4343f0408e314f1582029f3ea407",88 "public/sw.js": "d816161fd5a35f2c477ca72eaa5ba58eb8d94795a4399d29a19838e886dafa31",99 "README.md": "6a116909a8e9a92a4d48932d2d9672882171cfe1eb1d9d7caa8d36a6e4af8348",10- "src/_lofi/boot.ts": "dd66bd1e5ddb88599a0cbadb2c2cf932993734843c7e5cf41d28b389560a32c7",10+ "src/_lofi/boot.ts": "be739dbb65a963711f47c1ac801fda3afe3b32fb66b70d0a4c3552022adad6ad",1111 "src/_lofi/config.ts": "3ae7e31b3915e12eb595eeea158c0dbd026f4f0f8bf7b0f4809117bec9752f1a",1212 "src/_lofi/device-capabilities_test.ts": "0eece375a0645e915294c7647cba4666e992a8a471cb636cf889bcd323a65ee5",1313 "src/_lofi/device-capabilities.ts": "91b03f9bed813d3770061416d40066ed6f21829877293e5395eff8f0f98fc11e",@@ -17,7 +17,7 @@
1717 "src/_lofi/inspector.ts": "19fbe4f2d300ca4886ad90f16f6539cc0ad04ba1f38ac28bd9dec269c3f872bd",1818 "src/_lofi/probe.ts": "9bb284f4543e631acbfb22bb661b5cfc0798d561b0e95ee09796b36ebb5865b0",1919 "src/_lofi/pwa_test.ts": "092d9ff442d82086a03cf45c6ed0256ab0f1ce8db42fe7e636d4b93d6ebae63e",20- "src/_lofi/pwa.ts": "185a0668528b49eae2dd0aa905a5a2e491b3787da335d491ffecaf8bfadec430",20+ "src/_lofi/pwa.ts": "de48d0653890eb735067a161e907f8c957cb11719ff99e5faf4394efb67cf681",2121 "src/_lofi/resource-lifecycle_test.ts": "9a43053351b8b90f3b67a2953c3ff159e0337ab8009f1d061e9e2bf7382abf43",2222 "src/_lofi/resource-lifecycle.ts": "4e017f4391f18854486044709041f163308fa3fc84e08d5ec7f45c39e3ae3cb5",2323 "src/_lofi/runtime.ts": "db204517acc708f5145f48ed5cbd1ab95c01e35ddedb09dc0ba9617ea8bc1f79",@@ -29,7 +29,7 @@
2929 "src/_lofi/ui-mutation.ts": "3273053a796160556045d06d672f4c79d9597e1f822928f1ee71a7d31865dc32",3030 "src/_lofi/use-device-capabilities.ts": "f7c7b2321b400d8076a5347e0f1ff2924623535979d48a2d94a69f825b93841e",3131 "src/app.ts": "c03faa5219c79940e86f19beaaa94e6b917ec30311a51566b8f16d15886219cb",32- "src/env.d.ts": "01e5f288625c699524d6b6385a3a43907307fabcdbff802a32b82b254ef0876f",32+ "src/env.d.ts": "b44daed05ec5cdfacfd8d8acf7866974b5f6b8db923ab53bd244419093c719da",3333 "src/islands/TaskList.tsx": "2d6f4c7ed2475f1ce561e4b2c3a4e21210f4b55f0ec3eee6c4a6047f8622e189",3434 "src/islands/use-tasks.ts": "d2a9afa80590d4f38db7cfe0da37e6b7b17c00c1a73d82e06b800f97b5d609af",3535 "src/pages/index.astro": "3746bbd23cca65f5561c23fd4690368ee3f1cebb38d16f8bc7552ddff1f3f7fa",