cli improvements and typescript config changes

This commit is contained in:
2025-08-04 01:50:51 +02:00
parent 15169f7555
commit 12e516eb06
33 changed files with 4102 additions and 188 deletions

12
.gitignore vendored
View File

@@ -31,7 +31,11 @@ yarn-error.log*
*.pem *.pem
# NX # NX
.nx/cache .nx
.nx/workspace-data
.cursor/rules/nx-rules.mdc # SvelteKit
.github/instructions/nx.instructions.md .svelte-kit
.wrangler
# Sanity
.sanity

View File

@@ -72,6 +72,24 @@ async function main() {
], ],
initialValue: 'bun', initialValue: 'bun',
}), }),
lowerCaseName: ({ results }) => {
const defaultLowercase = String(results.dirName || results.projectName)
.trim()
.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.replace(/^-+|-+$/g, '');
return p.text({
message: `${color.cyan('📓 Enter a lowercase name for your project (e.g., used as')} ${color.yellow('<input>.sanity.studio')}${color.cyan('):')}`,
placeholder: `${defaultLowercase}`,
initialValue: defaultLowercase,
validate: (v) => {
if (v.length < 2) return `${color.red('❌ Too short!')}`;
if (!/^[a-z0-9-]+$/.test(v)) return `${color.red('❌ Only lowercase letters, numbers, and hyphens allowed!')}`;
if (v.startsWith('-') || v.endsWith('-')) return `${color.red('❌ Cannot start or end with hyphen!')}`;
if (v.includes('.sanity.studio')) return `${color.red('❌ Do not include .sanity.studio - it will be added automatically!')}`;
},
});
},
faviconPath: () => faviconPath: () =>
p.text({ p.text({
message: `${color.cyan('🖼️ Path to favicon SVG (leave empty to skip):')}`, message: `${color.cyan('🖼️ Path to favicon SVG (leave empty to skip):')}`,
@@ -107,8 +125,41 @@ async function main() {
task: async () => { task: async () => {
const __dirname = path.dirname(new URL(import.meta.url).pathname); const __dirname = path.dirname(new URL(import.meta.url).pathname);
const templateDir = path.resolve(__dirname, 'template'); const templateDir = path.resolve(__dirname, 'template');
// Ensure root directory exists with proper permissions
await fs.ensureDir(rootDir); await fs.ensureDir(rootDir);
await fs.copy(templateDir, rootDir, { overwrite: true });
try {
await fs.copy(templateDir, rootDir, {
overwrite: true,
errorOnExist: false,
preserveTimestamps: false
});
} catch (error) {
throw new Error(`Failed to copy template files: ${error.message}`);
}
// Rename gitignore files to .gitignore (dotfiles get lost in npm packages)
async function renameGitignoreFiles(dir) {
try {
const items = await fs.readdir(dir);
for (const item of items) {
const itemPath = path.join(dir, item);
const stat = await fs.stat(itemPath);
if (stat.isDirectory()) {
await renameGitignoreFiles(itemPath);
} else if (item === 'gitignore') {
const gitignorePath = path.join(dir, '.gitignore');
await fs.move(itemPath, gitignorePath);
}
}
} catch (error) {
throw new Error(`Failed to rename gitignore files: ${error.message}`);
}
}
await renameGitignoreFiles(rootDir);
return 'Template copied!'; return 'Template copied!';
}, },
}, },
@@ -205,13 +256,30 @@ async function main() {
const wranglerPath = path.join(rootDir, "apps/client/wrangler.jsonc"); const wranglerPath = path.join(rootDir, "apps/client/wrangler.jsonc");
if (await fs.pathExists(wranglerPath)) { if (await fs.pathExists(wranglerPath)) {
let wranglerFile = await fs.readFile(wranglerPath, "utf8"); let wranglerFile = await fs.readFile(wranglerPath, "utf8");
wranglerFile = wranglerFile.replace(/"name": "[^"]+"/, `"name": "${kebabName}"`); wranglerFile = wranglerFile.replace(/"name": "[^"]+"/, `"name": "${project.lowerCaseName}"`);
await fs.writeFile(wranglerPath, wranglerFile); await fs.writeFile(wranglerPath, wranglerFile);
} }
return `Sanity project created with ID: ${sanityJson.projectId}`; return `Sanity project created with ID: ${sanityJson.projectId}`;
}, },
}, },
{
title: `${color.blue('🗄️ Setting up production dataset for Sanity CMS')}`,
task: async () => {
if (!(await fs.pathExists(studioDir))) throw new Error(`Studio directory not found at ${studioDir}`);
try {
await runCommand(pmx, ['sanity', 'dataset', 'create', 'production'], studioDir);
return 'Production dataset created successfully';
} catch (error) {
// Check if dataset already exists
if (error.message && error.message.includes('already exists')) {
return 'Production dataset already exists';
}
throw new Error(`Failed to create production dataset: ${error.message}`);
}
},
},
{ {
title: `${color.green('🔐 Creating Sanity viewer token')}`, title: `${color.green('🔐 Creating Sanity viewer token')}`,
task: async () => { task: async () => {
@@ -231,8 +299,8 @@ async function main() {
let content = await fs.readFile(connPath, 'utf8'); let content = await fs.readFile(connPath, 'utf8');
content = content content = content
.replace(/publicViewerToken: "[^"]+"/, `publicViewerToken: "${token.key}"`) .replace(/publicViewerToken: "[^"]+"/, `publicViewerToken: "${token.key}"`)
.replace(/studioHost: "[^"]+"/, `studioHost: "${kebabName}"`) .replace(/studioHost: "[^"]+"/, `studioHost: "${project.lowerCaseName}"`)
.replace(/studioUrl: "[^"]+"/, `studioUrl: "https://${kebabName}.sanity.studio"`); .replace(/studioUrl: "[^"]+"/, `studioUrl: "https://${project.lowerCaseName}.sanity.studio"`);
await fs.writeFile(connPath, content); await fs.writeFile(connPath, content);
return 'Viewer token created and configured!'; return 'Viewer token created and configured!';
}, },
@@ -257,7 +325,7 @@ async function main() {
'http://localhost:5173', 'http://localhost:5173',
'https://*.api.sanity.io', 'https://*.api.sanity.io',
'wss://*.api.sanity.io', 'wss://*.api.sanity.io',
`https://${kebabName}.sanity.studio`, `https://${project.lowerCaseName}.sanity.studio`,
]; ];
if (project.extraDomain && project.extraDomain.trim()) { if (project.extraDomain && project.extraDomain.trim()) {
corsOrigins.push(`https://${project.extraDomain.trim()}`); corsOrigins.push(`https://${project.extraDomain.trim()}`);
@@ -267,7 +335,7 @@ async function main() {
title: `${color.cyan('🌐 Adding Sanity CORS origin:')} ${color.yellow(origin)}`, title: `${color.cyan('🌐 Adding Sanity CORS origin:')} ${color.yellow(origin)}`,
task: async () => { task: async () => {
const args = ['sanity', 'cors', 'add', origin, '--yes']; const args = ['sanity', 'cors', 'add', origin, '--yes'];
if (origin === `https://${kebabName}.sanity.studio`) args.push('--credentials'); if (origin === `https://${project.lowerCaseName}.sanity.studio`) args.push('--credentials');
await runCommand(pmx, args, studioDir); await runCommand(pmx, args, studioDir);
return `CORS added: ${origin}` + (args.includes('--credentials') ? ' (credentials allowed)' : ''); return `CORS added: ${origin}` + (args.includes('--credentials') ? ' (credentials allowed)' : '');
}, },
@@ -290,7 +358,7 @@ async function main() {
]); ]);
const org = typeof project.gitOrg === 'string' ? project.gitOrg.trim() : ''; const org = typeof project.gitOrg === 'string' ? project.gitOrg.trim() : '';
if (org) { if (org) {
const githubUrl = `https://github.com/new?name=${kebabName}&owner=${org}`; const githubUrl = `https://github.com/new?name=${kebabName}&owner=${org}&visibility=private&description=${encodeURIComponent('This website was built using the official Lumify starter template for building with Sveltekit, Sanity, Bun, and Shadcn UI — bundled into a NX monorepo.')}`;
p.note( p.note(
`Please create a new GitHub repository named\n\`${kebabName}\` under \`${org}\` at:\n\n${color.cyan(githubUrl)}\n\nThe browser will open for you.`, `Please create a new GitHub repository named\n\`${kebabName}\` under \`${org}\` at:\n\n${color.cyan(githubUrl)}\n\nThe browser will open for you.`,
'GitHub Setup Required' 'GitHub Setup Required'
@@ -332,7 +400,7 @@ async function main() {
` • App: ${color.cyan('http://localhost:5173')} ${color.yellow('🌐')}\n` + ` • App: ${color.cyan('http://localhost:5173')} ${color.yellow('🌐')}\n` +
` • Studio: ${color.cyan('http://localhost:3333')} ${color.yellow('🛠️')}\n\n` + ` • Studio: ${color.cyan('http://localhost:3333')} ${color.yellow('🛠️')}\n\n` +
color.dim('After deploying:\n') + color.dim('After deploying:\n') +
` • Studio: ${color.cyan(`https://${kebabName}.sanity.studio`)} ${color.yellow('✨')}` ` • Studio: ${color.cyan(`https://${project.lowerCaseName}.sanity.studio`)} ${color.yellow('✨')}`
); );
process.exit(0); process.exit(0);
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@lumify-systems/template-sanity", "name": "@lumify-systems/template-sanity",
"version": "2.0.0", "version": "2.1.0",
"publishConfig": { "publishConfig": {
"access": "restricted", "access": "restricted",
"registry": "https://npm.pkg.github.com" "registry": "https://npm.pkg.github.com"

View File

@@ -1,51 +0,0 @@
import { getImageDimensions, type SanityImageDimensions } from '@sanity/asset-utils';
import type { ImageWithAlt } from './sanity.types';
import { generateImageUrl } from './image-url';
import { client } from './sanity';
export type SimpleImage = {
url: string;
alt: string;
dimensions: SanityImageDimensions;
};
// Internal helper to fetch image data from Sanity (client-side)
async function fetchImage(assetRef: string | undefined): Promise<ImageWithAlt | null> {
if (!assetRef) return null;
const image = await client.fetch(`*[_id == $id][0]`, { id: assetRef });
return image;
}
// Internal helper to get dimensions safely
function getDimensions(image: ImageWithAlt | any): SanityImageDimensions {
try {
if (image._type === 'imageWithAlt') {
const compatibleImage = { ...image, asset: image.asset };
return getImageDimensions(compatibleImage as any);
}
return getImageDimensions(image);
} catch {
return { width: 1200, height: 800, aspectRatio: 1.5 };
}
}
// Convert a single asset reference to SimpleImage (client-side)
export async function getImageClient(assetRef: string | undefined): Promise<SimpleImage> {
const image = await fetchImage(assetRef);
if (!image)
return { url: '', alt: '', dimensions: { width: 0, height: 0, aspectRatio: 1 } };
const dimensions = getDimensions(image);
return {
url: generateImageUrl(image),
alt: image.alt || '',
dimensions
};
}
// Convert multiple asset references to SimpleImage array (client-side)
export async function getImagesClient(assetRefs: (string | undefined)[]): Promise<SimpleImage[]> {
return Promise.all(assetRefs.map((ref) => getImageClient(ref)));
}

View File

@@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import { deconstructLink } from '$lib/link-helper'; import { deconstructLink } from '$lib/helper/link';
import LinkButton from '../link-button.svelte'; import LinkButton from '../link-button.svelte';
import { onMount } from 'svelte'; import { onMount } from 'svelte';

View File

@@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import { getImageDimensions } from '@sanity/asset-utils'; import { getImageDimensions } from '@sanity/asset-utils';
import { generateImageUrl, dynamicHeight } from '$lib/image-url'; import { generateImageUrl, dynamicHeight } from '$lib/helper/image-url';
let { portableText } = $props(); let { portableText } = $props();
const { value, isInline } = portableText; const { value, isInline } = portableText;

View File

@@ -1,10 +1,9 @@
<script lang="ts"> <script lang="ts">
import LinkButton from '../link-button.svelte'; import LinkButton from '../link-button.svelte';
import type { CtaSection } from '$lib/sanity.types'; import type { CtaSection } from '$lib/sanity.types';
import { deconstructLink } from '$lib/link-helper'; import { deconstructLink } from '$lib/helper/link';
import type { SimpleImage } from '$lib/asset-to-url'; import type { SimpleImage } from '$lib/helper/asset-to-url';
import { cn } from '$lib/utils'; import { cn } from '$lib/utils';
import { generateImageUrl } from '$lib/image-url';
import SanityBlock from '../sanity-block.svelte'; import SanityBlock from '../sanity-block.svelte';
import { onMount } from 'svelte'; import { onMount } from 'svelte';

View File

@@ -1,7 +1,7 @@
import { getImageDimensions, type SanityImageDimensions } from '@sanity/asset-utils'; import { getImageDimensions, type SanityImageDimensions } from '@sanity/asset-utils';
import type { ImageWithAlt } from './sanity.types'; import type { ImageWithAlt } from '../sanity.types';
import { generateImageUrl } from './image-url'; import { generateImageUrl } from './image-url';
import { serverClient } from './server/sanity'; import { serverClient } from '../server/sanity';
export type SimpleImage = { export type SimpleImage = {
url: string; url: string;
@@ -9,7 +9,6 @@ export type SimpleImage = {
dimensions: SanityImageDimensions; dimensions: SanityImageDimensions;
}; };
// Internal helper to fetch image data from Sanity
async function fetchImage(assetRef: string | undefined): Promise<ImageWithAlt | null> { async function fetchImage(assetRef: string | undefined): Promise<ImageWithAlt | null> {
if (!assetRef) return null; if (!assetRef) return null;
@@ -17,7 +16,6 @@ async function fetchImage(assetRef: string | undefined): Promise<ImageWithAlt |
return image; return image;
} }
// Internal helper to get dimensions safely
function getDimensions(image: ImageWithAlt | any): SanityImageDimensions { function getDimensions(image: ImageWithAlt | any): SanityImageDimensions {
try { try {
if (image._type === 'imageWithAlt') { if (image._type === 'imageWithAlt') {
@@ -30,7 +28,6 @@ function getDimensions(image: ImageWithAlt | any): SanityImageDimensions {
} }
} }
// Convert a single asset reference to SimpleImage
export async function getImage(assetRef: string | undefined): Promise<SimpleImage> { export async function getImage(assetRef: string | undefined): Promise<SimpleImage> {
const image = await fetchImage(assetRef); const image = await fetchImage(assetRef);
if (!image) if (!image)
@@ -45,7 +42,6 @@ export async function getImage(assetRef: string | undefined): Promise<SimpleImag
}; };
} }
// Convert multiple asset references to SimpleImage array
export async function getImages(assetRefs: (string | undefined)[]): Promise<SimpleImage[]> { export async function getImages(assetRefs: (string | undefined)[]): Promise<SimpleImage[]> {
return Promise.all(assetRefs.map((ref) => getImage(ref))); return Promise.all(assetRefs.map((ref) => getImage(ref)));
} }

View File

@@ -1,28 +1,26 @@
import { client } from './sanity'; import { client } from '../sanity';
import type { ImageWithAlt, SanityImageAsset } from './sanity.types'; import type { ImageWithAlt, SanityImageAsset } from '../sanity.types';
import imageUrlBuilder from '@sanity/image-url'; import imageUrlBuilder from '@sanity/image-url';
const { projectId, dataset } = client.config(); const { projectId, dataset } = client.config();
const builder = imageUrlBuilder({ projectId: projectId ?? '', dataset: dataset ?? '' }); const builder = imageUrlBuilder({ projectId: projectId ?? '', dataset: dataset ?? '' });
console.log('Image URL Builder initialized with:', { projectId, dataset }); export function generateImageUrl(
image: ImageWithAlt | any,
export function generateImageUrl(image: ImageWithAlt | any, width?: number, height?: number): string { width?: number,
height?: number
): string {
if (!image || !projectId || !dataset) { if (!image || !projectId || !dataset) {
console.log('No image, projectId, or dataset:', { image, projectId, dataset });
return ''; return '';
} }
// Handle direct URL
if (image.url && !image.asset) { if (image.url && !image.asset) {
return image.url; return image.url;
} }
// Handle Sanity image object
const imageRef = image.asset?._ref || image.asset?._id || image.asset; const imageRef = image.asset?._ref || image.asset?._id || image.asset;
if (!imageRef) { if (!imageRef) {
console.log('No imageRef found:', image);
return ''; return '';
} }
@@ -33,8 +31,7 @@ export function generateImageUrl(image: ImageWithAlt | any, width?: number, heig
.width(width || 1920) .width(width || 1920)
.format('webp') .format('webp')
.auto('format'); .auto('format');
// Cropping doesnt really work. But it is here for future reference i guess. Fucking Sanity is so retarded.
// Apply cropping if available
if (image.crop && width && height) { if (image.crop && width && height) {
const crop = image.crop; const crop = image.crop;
if (crop.top || crop.bottom || crop.left || crop.right) { if (crop.top || crop.bottom || crop.left || crop.right) {
@@ -47,19 +44,13 @@ export function generateImageUrl(image: ImageWithAlt | any, width?: number, heig
} }
const url = imageBuilder.url(); const url = imageBuilder.url();
console.log('Generated URL:', url);
return url; return url;
} catch (error) { } catch (error) {
console.error('Error generating image URL:', error);
return ''; return '';
} }
} }
export function dynamicHeight( export function dynamicHeight(originalHeight: number, originalWidth: number, isInline: boolean) {
originalHeight: number,
originalWidth: number,
isInline: boolean
) {
const targetWidth = isInline ? 100 : Math.min(originalWidth, 1200); const targetWidth = isInline ? 100 : Math.min(originalWidth, 1200);
return (targetWidth * originalHeight) / originalWidth; return (targetWidth * originalHeight) / originalWidth;
} }

View File

@@ -1,5 +1,5 @@
import type { Link } from './sanity.types'; import type { Link } from '../sanity.types';
import { client } from './sanity'; import { client } from '../sanity';
interface InternalLink { interface InternalLink {
_ref: string; _ref: string;

View File

@@ -1,6 +1,6 @@
import type {LayoutServerLoad} from './$types' import type {LayoutServerLoad} from './$types'
import { fetchSettings } from '$lib/settings' import { fetchSettings } from '$lib/settings'
import { getImage } from '$lib/asset-to-url' import { getImage } from '$lib/helper/asset-to-url'
export const load: LayoutServerLoad = async ({locals: {preview}}) => { export const load: LayoutServerLoad = async ({locals: {preview}}) => {
const settings = await fetchSettings() const settings = await fetchSettings()

View File

@@ -3,7 +3,7 @@
import {useQuery} from '@sanity/svelte-loader' import {useQuery} from '@sanity/svelte-loader'
import type { PageData } from './$types'; import type { PageData } from './$types';
import CTA from '$lib/components/section/cta.svelte'; import CTA from '$lib/components/section/cta.svelte';
import { getImageFromAsset } from '$lib/image-helper'; import { getImageFromAsset } from '$lib/helper/image';
export let data: PageData export let data: PageData
const query = useQuery(data) const query = useQuery(data)

View File

@@ -1,19 +1,11 @@
{ {
"extends": "./.svelte-kit/tsconfig.json", "extends": [
"compilerOptions": { "./.svelte-kit/tsconfig.json",
"allowJs": true, "@repo/typescript-config/sveltekit.json"
"checkJs": true, ]
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"moduleResolution": "bundler"
}
// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
// except $lib which is handled by https://svelte.dev/docs/kit/configuration#files // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
// //
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
// from the referenced tsconfig.json - TypeScript does not merge them in // from the referenced tsconfig.json - TypeScript does not merge them in
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "template-sanity", "name": "template-sanity",
"account_id": "7709703dd5c5923bd03a32fefb04f32d", // vaporvee "account_id": "<ACCOUNT_ID>", // replace it with your Cloudflare account ID. Usually found at https://dash.cloudflare.com/<ACCOUNT_ID>
"main": "./.cloudflare/worker.js", "main": "./.cloudflare/worker.js",
"site": { "site": {
"bucket": "./.cloudflare/public" "bucket": "./.cloudflare/public"

View File

@@ -20,8 +20,8 @@
"@repo/ui": "*", "@repo/ui": "*",
"@sanity/document-internationalization": "^3.3.3", "@sanity/document-internationalization": "^3.3.3",
"@sanity/vision": "^4.2.0", "@sanity/vision": "^4.2.0",
"react": "^19.1.0", "react": "^19.1.1",
"react-dom": "^19.1.0", "react-dom": "^19.1.1",
"sanity": "^4.2.0", "sanity": "^4.2.0",
"sanity-plugin-link-field": "^1.4.0", "sanity-plugin-link-field": "^1.4.0",
"sanity-plugin-media": "^3.0.4", "sanity-plugin-media": "^3.0.4",
@@ -31,8 +31,9 @@
}, },
"devDependencies": { "devDependencies": {
"@sanity/eslint-config-studio": "^5.0.2", "@sanity/eslint-config-studio": "^5.0.2",
"@types/react": "^19.1.8", "@types/react": "^19.1.9",
"eslint": "^9.31.0", "@repo/typescript-config": "*",
"eslint": "^9.32.0",
"prettier": "^3.6.2", "prettier": "^3.6.2",
"typescript": "^5.8.3" "typescript": "^5.8.3"
}, },

View File

@@ -1,17 +1,5 @@
{ {
"compilerOptions": { "extends": "@repo/typescript-config/sanity.json",
"target": "ES2017",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "Preserve",
"moduleDetection": "force",
"isolatedModules": true,
"jsx": "preserve",
"incremental": true
},
"include": ["**/*.ts", "**/*.tsx"], "include": ["**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"] "exclude": ["node_modules"]
} }

3918
template/bun.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -2,29 +2,13 @@
"$schema": "./node_modules/nx/schemas/nx-schema.json", "$schema": "./node_modules/nx/schemas/nx-schema.json",
"targetDefaults": { "targetDefaults": {
"build": { "build": {
"dependsOn": [ "dependsOn": ["^build", "^generate"],
"^build", "inputs": ["{projectRoot}/**/*", "{projectRoot}/.env*"],
"^generate" "outputs": ["{projectRoot}/dist/**"],
],
"inputs": [
"{projectRoot}/**/*",
"{projectRoot}/.env*"
],
"outputs": [
"{projectRoot}/dist/**"
],
"cache": true "cache": true
}, },
"lint": { "check": {
"dependsOn": [ "dependsOn": ["^check"],
"^lint"
],
"cache": true
},
"check-types": {
"dependsOn": [
"^check-types"
],
"cache": true "cache": true
}, },
"deploy": { "deploy": {
@@ -37,4 +21,4 @@
"cache": true "cache": true
} }
} }
} }

View File

@@ -8,7 +8,7 @@
"deploy": "nx run-many -t deploy", "deploy": "nx run-many -t deploy",
"generate": "nx run-many -t generate", "generate": "nx run-many -t generate",
"format": "prettier --write \"**/*.{ts,tsx,md}\"", "format": "prettier --write \"**/*.{ts,tsx,md}\"",
"check-types": "nx run-many -t check-types" "check": "nx run-many -t check"
}, },
"devDependencies": { "devDependencies": {
"prettier": "^3.6.2", "prettier": "^3.6.2",

View File

@@ -3,9 +3,10 @@
"module": "index.ts", "module": "index.ts",
"type": "module", "type": "module",
"devDependencies": { "devDependencies": {
"@repo/typescript-config": "*",
"@types/bun": "latest" "@types/bun": "latest"
}, },
"peerDependencies": { "peerDependencies": {
"typescript": "^5.8.3" "typescript": "^5.8.3"
} }
} }

View File

@@ -1,27 +1,3 @@
{ {
"compilerOptions": { "extends": "@repo/typescript-config/react-package.json"
// Enable latest features
"lib": ["ESNext", "DOM"],
"target": "ESNext",
"module": "ESNext",
"moduleDetection": "force",
"jsx": "react-jsx",
"allowJs": true,
// Bundler mode
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"noEmit": true,
// Best practices
"strict": true,
"skipLibCheck": true,
"noFallthroughCasesInSwitch": true,
// Some stricter flags (disabled by default)
"noUnusedLocals": false,
"noUnusedParameters": false,
"noPropertyAccessFromIndexSignature": false
}
} }

View File

@@ -1,5 +1,6 @@
{ {
"$schema": "https://json.schemastore.org/tsconfig", "$schema": "https://json.schemastore.org/tsconfig",
"extends": "../../tsconfig.base.json",
"compilerOptions": { "compilerOptions": {
"declaration": true, "declaration": true,
"declarationMap": true, "declarationMap": true,

View File

@@ -0,0 +1,6 @@
{
"extends": "@repo/typescript-config/base.json",
"compilerOptions": {
"jsx": "react-jsx"
}
}

View File

@@ -0,0 +1,12 @@
{
"extends": "@repo/typescript-config/base.json",
"compilerOptions": {
"jsx": "react-jsx",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"noFallthroughCasesInSwitch": true,
"noUnusedLocals": false,
"noUnusedParameters": false,
"noPropertyAccessFromIndexSignature": false
}
}

View File

@@ -0,0 +1,8 @@
{
"extends": "@repo/typescript-config/base.json",
"compilerOptions": {
"target": "ES2017",
"module": "Preserve",
"incremental": true
}
}

View File

@@ -0,0 +1,13 @@
{
"compilerOptions": {
"checkJs": true,
"sourceMap": true,
"declaration": true,
"declarationMap": true,
"esModuleInterop": true,
"noUncheckedIndexedAccess": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"strict": true
}
}

View File

@@ -9,18 +9,18 @@
}, },
"scripts": { "scripts": {
"lint": "eslint . --max-warnings 0", "lint": "eslint . --max-warnings 0",
"check-types": "tsc --noEmit" "check": "tsc --noEmit"
}, },
"devDependencies": { "devDependencies": {
"@repo/typescript-config": "*", "@repo/typescript-config": "*",
"@types/node": "^22.15.3", "@types/node": "^22.15.3",
"@types/react": "19.1.0", "@types/react": "19.1.9",
"@types/react-dom": "19.1.1", "@types/react-dom": "19.1.1",
"eslint": "^9.30.0", "eslint": "^9.32.0",
"typescript": "5.8.2" "typescript": "5.8.3"
}, },
"dependencies": { "dependencies": {
"react": "^19.1.0", "react": "^19.1.1",
"react-dom": "^19.1.0" "react-dom": "^19.1.1"
} }
} }

View File

@@ -2,10 +2,7 @@
"extends": "@repo/typescript-config/react-library.json", "extends": "@repo/typescript-config/react-library.json",
"compilerOptions": { "compilerOptions": {
"outDir": "dist", "outDir": "dist",
"allowJs": true, "noEmit": true
"noEmit": true,
"module": "ESNext",
"moduleResolution": "bundler"
}, },
"include": ["src"], "include": ["src"],
"exclude": ["node_modules", "dist"] "exclude": ["node_modules", "dist"]

View File

@@ -0,0 +1,10 @@
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@repo/typescript-config/*": ["packages/typescript-config/*"],
"@repo/sanity-connection": ["packages/sanity-connection"],
"@repo/ui": ["packages/ui"]
}
}
}