Merge branch 'staging' into big-nate-bus-1891-tables-on-reports-should-hug-rows-have-a-max-height

This commit is contained in:
Nate Kelley 2025-09-24 08:07:52 -06:00
commit 2922660f75
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
38 changed files with 430 additions and 475 deletions

View File

@ -5,12 +5,7 @@
"build": {
"dependsOn": ["@buster/database#build"],
"outputs": ["target/release/**"],
"inputs": [
"server/**/*",
"libs/**/*",
"Cargo.toml",
"Cargo.lock"
]
"inputs": ["server/**/*", "libs/**/*", "Cargo.toml", "Cargo.lock"]
},
"start": {
"dependsOn": ["@buster/database#start", "build"],

View File

@ -1,7 +1,7 @@
{
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
"extends": ["../../biome.json"],
"$schema": "https://biomejs.dev/schemas/2.2.4/schema.json",
"extends": ["../../biome2.json"],
"files": {
"include": ["src/**/*", "scripts/**/*"]
"includes": ["src/**/*", "scripts/**/*"]
}
}

View File

@ -26,7 +26,7 @@
"zod": "catalog:"
},
"devDependencies": {
"momentic": "^2.16.0",
"momentic": "^2.17.3",
"tsx": "catalog:"
}
}
}

10
apps/momentic/turbo.json Normal file
View File

@ -0,0 +1,10 @@
{
"$schema": "https://turbo.build/schema.json",
"extends": ["//"],
"tasks": {
"momentic": {
"cache": false,
"persistent": true
}
}
}

View File

@ -357,7 +357,7 @@ export const analystAgentTask: ReturnType<
dataSourceId: dataSource.dataSourceId,
dataSourceSyntax: dataSource.dataSourceSyntax,
datasetsCount: datasets.length,
datasets: datasets.map((d) => ({
datasets: datasets.map((d: PermissionedDataset) => ({
id: d.id,
name: d.name,
})),

View File

@ -9,7 +9,7 @@
"start": {
"cache": false,
"persistent": true,
"dependsOn": ["^build"],
"dependsOn": ["^build", "@buster-app/supabase#start"],
"with": ["@buster-app/supabase#start"]
},
"dev": {

View File

@ -1,28 +1,25 @@
import type { StorybookConfig } from '@storybook/react-vite';
import { join, dirname } from "path"
import { dirname, join } from 'path';
/**
* This function is used to resolve the absolute path of a package.
* It is needed in projects that use Yarn PnP or are set up within a monorepo.
*/
* This function is used to resolve the absolute path of a package.
* It is needed in projects that use Yarn PnP or are set up within a monorepo.
*/
function getAbsolutePath(value: string): any {
return dirname(require.resolve(join(value, 'package.json')))
return dirname(require.resolve(join(value, 'package.json')));
}
const config: StorybookConfig = {
"stories": [
"../src/**/*.mdx",
"../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"
],
"addons": [
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [
getAbsolutePath('@chromatic-com/storybook'),
getAbsolutePath('@storybook/addon-docs'),
getAbsolutePath("@storybook/addon-a11y"),
getAbsolutePath("@storybook/addon-vitest")
getAbsolutePath('@storybook/addon-a11y'),
getAbsolutePath('@storybook/addon-vitest'),
],
"framework": {
"name": getAbsolutePath('@storybook/react-vite'),
"options": {}
}
framework: {
name: getAbsolutePath('@storybook/react-vite'),
options: {},
},
};
export default config;
export default config;

View File

@ -1,6 +1,6 @@
import type { Preview } from "@storybook/react-vite";
import "../src/styles/styles.css";
import { BusterStyleProvider } from "../src/context/BusterStyles";
import type { Preview } from '@storybook/react-vite';
import '../src/styles/styles.css';
import { BusterStyleProvider } from '../src/context/BusterStyles';
const preview: Preview = {
parameters: {

View File

@ -1,7 +1,7 @@
import * as a11yAddonAnnotations from "@storybook/addon-a11y/preview";
import * as a11yAddonAnnotations from '@storybook/addon-a11y/preview';
import { setProjectAnnotations } from '@storybook/react-vite';
import * as projectAnnotations from './preview';
// This is an important step to apply the right configuration when testing your stories.
// More info at: https://storybook.js.org/docs/api/portable-stories/portable-stories-vitest#setprojectannotations
setProjectAnnotations([a11yAddonAnnotations, projectAnnotations]);
setProjectAnnotations([a11yAddonAnnotations, projectAnnotations]);

View File

@ -1,118 +0,0 @@
# Browser Redirect Caching Issue - Fix Documentation
## ✅ The Real Problem: Browser Caching
Your issue wasn't with Cloudflare Workers or SSR - it was **browser caching of redirects**!
### Evidence:
- ✅ **Incognito mode works perfectly** (no cache)
- ❌ **Regular browser fails** (has cached redirects)
- ❌ **After deployment, old cached redirects persist**
## 🔍 Root Cause
1. **301 (Permanent) redirects are cached aggressively** by browsers
2. Browsers remember these redirects **even after deployments**
3. The cached redirects were causing the loading issues
## ✅ Solutions Applied
### 1. Changed All Status Codes from 301 to 307
**Why 307?**
- **301**: Permanent redirect (heavily cached)
- **302**: Temporary redirect (sometimes cached)
- **307**: Temporary redirect (NEVER cached)
**Files Updated:**
- `/src/routes/app/index.tsx` - Changed 301 → 307
- `/src/routes/app.tsx` - Changed 302 → 307
- `/src/routes/auth.logout.tsx` - Changed 301 → 307
- `/src/routes/app/_settings/settings.index.tsx` - Changed 301 → 307
- `/src/routes/app/_app/datasets.$datasetId.tsx` - Changed 301 → 307
- `/src/routes/app/_app/datasets.$datasetId.permissions.index.tsx` - Changed 301 → 307
- `/src/routes/app/_settings/_permissions/settings.dataset-groups.$datasetGroupId.index.tsx` - Changed 301 → 307
- `/src/routes/app/_settings/_restricted_layout/_admin_only.tsx` - Changed 301 → 307
- `/src/routes/app/_settings/_permissions.tsx` - Changed 301 → 307
### 2. Added Cache Control Headers
Modified `/src/middleware/global-security.ts` to add no-cache headers for redirect routes:
```typescript
if (isRedirectRoute) {
headers['Cache-Control'] = 'no-cache, no-store, must-revalidate';
headers['Pragma'] = 'no-cache';
headers['Expires'] = '0';
}
```
### 3. Meta Refresh with Cache Prevention
Updated `/src/routes/index.tsx` with cache prevention meta tags:
```typescript
meta: [
{ 'http-equiv': 'refresh', content: '0; url=/app/home' },
{ 'http-equiv': 'Cache-Control', content: 'no-cache, no-store, must-revalidate' },
{ 'http-equiv': 'Pragma', content: 'no-cache' },
{ 'http-equiv': 'Expires', content: '0' },
]
```
## 🧹 Clear Your Browser Cache
**For existing users who might have cached 301 redirects:**
### Chrome/Edge:
1. Open DevTools (F12)
2. Right-click the refresh button
3. Select "Empty Cache and Hard Reload"
### Or Clear Specific Site Data:
1. Open DevTools → Application tab
2. Storage → Clear storage
3. Click "Clear site data"
### Firefox:
1. Ctrl+Shift+Delete
2. Select "Cache" only
3. Clear for "Last hour"
## 📊 Status Code Reference
| Code | Type | Cached? | Use Case |
|------|------|---------|----------|
| 301 | Permanent | ✅ Aggressively | Never for app redirects! |
| 302 | Temporary | ⚠️ Sometimes | Legacy, avoid |
| 303 | See Other | ❌ No | POST → GET redirect |
| 307 | Temporary | ❌ No | ✅ Best for app redirects |
| 308 | Permanent | ✅ Yes | Like 301 but preserves method |
## 🚀 Testing
1. **Clear browser cache first** (important!)
2. **Build and deploy:**
```bash
npm run build
npx wrangler deploy --env staging
```
3. **Test scenarios:**
- Visit `/` → Should redirect to `/app/home`
- Visit `/app/` → Should redirect to `/app/home`
- Log out → Should redirect to `/auth/login`
- All should work on first visit (cold start)
## 🎯 Key Takeaways
1. **Never use 301 for application redirects** - they're meant for permanent URL changes
2. **Use 307 for temporary redirects** that shouldn't be cached
3. **Browser caching can persist across deployments** and cause mysterious issues
4. **Incognito mode is your friend** for testing caching issues
## 🔮 Future Recommendations
1. **Consider server-side redirects** in Cloudflare configuration for static redirects
2. **Monitor with Chrome DevTools Network tab** - check "Disable cache" when debugging
3. **Use `wrangler tail` to see if requests are even hitting your worker**
## Related Issues
- [MDN: HTTP redirect status codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages)
- [Chrome: Clear cache for specific site](https://support.google.com/chrome/answer/2392709)
- [Cloudflare: Page Rules for redirects](https://developers.cloudflare.com/rules/page-rules/)

View File

@ -1,21 +1,8 @@
{
"$schema": "https://biomejs.dev/schemas/2.2.4/schema.json",
"extends": ["../../biome2.json"],
"files": {
"ignoreUnknown": false,
"includes": [
"src/**/*",
".vscode/**/*",
"index.html",
"vite.config.ts",
"vitest.config.ts",
"vitest.setup.ts",
"!src/routeTree.gen.ts",
"!**/node_modules",
"!**/dist",
"!**/build",
"!**/coverage",
"!**/.next"
]
"includes": ["!**/routeTree.gen.ts", "!.vercel", "!.nitro", "!.storybook"]
},
"linter": {
"enabled": true,
@ -63,56 +50,11 @@
}
},
"overrides": [
{
"includes": ["**/*.test.ts", "**/*.test.tsx", "**/*.stories.tsx"],
"linter": {
"rules": {
"suspicious": {
"noExplicitAny": "off"
},
"style": {
"noNonNullAssertion": "off"
},
"correctness": {
"noUnusedFunctionParameters": "off",
"noUnusedVariables": "off"
}
}
}
},
{
"includes": ["**/*.stories.tsx"],
"linter": {
"enabled": false
}
},
{
"includes": ["**/*.css"],
"linter": {
"enabled": false
}
}
],
"formatter": {
"enabled": true,
"formatWithErrors": false,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100,
"lineEnding": "lf"
},
"javascript": {
"formatter": {
"quoteStyle": "single",
"jsxQuoteStyle": "double",
"trailingCommas": "es5",
"semicolons": "always",
"arrowParentheses": "always"
}
},
"css": {
"parser": {
"cssModules": true
}
}
]
}

View File

@ -1,30 +1,24 @@
// Configuration for warning suppressions - easily extensible
const WARNING_SUPPRESSIONS = {
MODULE_LEVEL_DIRECTIVE: {
patterns: ["node_modules/"],
patterns: ['node_modules/'],
reason: "Suppress 'use client' directive warnings from dependencies",
},
THIS_IS_UNDEFINED: {
patterns: ["node_modules/"],
patterns: ['node_modules/'],
reason: "Suppress 'this' keyword warnings in ES modules from dependencies",
},
CIRCULAR_DEPENDENCY: {
patterns: [
"nitropack/dist/runtime/internal/",
"@tanstack/store/dist",
"juice/lib/",
],
reason: "Suppress known third-party circular dependency warnings",
patterns: ['nitropack/dist/runtime/internal/', '@tanstack/store/dist', 'juice/lib/'],
reason: 'Suppress known third-party circular dependency warnings',
},
};
// Additional message-based suppressions
const MESSAGE_SUPPRESSIONS = [
"The 'this' keyword is equivalent to 'undefined'",
];
const MESSAGE_SUPPRESSIONS = ["The 'this' keyword is equivalent to 'undefined'"];
function shouldSuppressWarning(warning) {
const message = warning.message || "";
const message = warning.message || '';
// Check code-based suppressions
const suppression = WARNING_SUPPRESSIONS[warning.code];
@ -33,9 +27,7 @@ function shouldSuppressWarning(warning) {
}
// Check message-based suppressions
return MESSAGE_SUPPRESSIONS.some((suppressionMessage) =>
message.includes(suppressionMessage)
);
return MESSAGE_SUPPRESSIONS.some((suppressionMessage) => message.includes(suppressionMessage));
}
export default {

View File

@ -14,7 +14,12 @@ const requiredEnv = {
};
// Validate environment variables
const { hasErrors } = validateEnv(requiredEnv, { skipInProduction: false, skipInCI: false, skipInDocker: false, logPublicVars: true });
const { hasErrors } = validateEnv(requiredEnv, {
skipInProduction: false,
skipInCI: false,
skipInDocker: false,
logPublicVars: true,
});
if (hasErrors) {
process.exit(1);

View File

@ -306,6 +306,23 @@ const AlreadyHaveAccount: React.FC<{
setSignUpFlow: (value: boolean) => void;
signUpFlow: boolean;
}> = React.memo(({ setErrorMessages, setPassword2, setSignUpFlow, signUpFlow }) => {
const handleToggleClick = () => {
if (!signUpFlow) {
// User clicked "Sign up" - redirect to get-started page
window.location.href = 'https://www.buster.so/get-started';
} else {
// User clicked "Sign in" - use existing toggle logic
setErrorMessages([]);
setPassword2('');
setSignUpFlow(!signUpFlow);
}
// TODO: Original toggle logic preserved for future re-enablement
// setErrorMessages([]);
// setPassword2('');
// setSignUpFlow(!signUpFlow);
};
return (
<div className="flex flex-col items-center justify-center gap-1.5">
<div className="flex items-center justify-center gap-0.5">
@ -317,11 +334,7 @@ const AlreadyHaveAccount: React.FC<{
variant="primary"
size="xs"
className={cn('ml-1 cursor-pointer font-normal')}
onClick={() => {
setErrorMessages([]);
setPassword2('');
setSignUpFlow(!signUpFlow);
}}
onClick={handleToggleClick}
>
{!signUpFlow ? 'Sign up' : 'Sign in'}
</Text>

View File

@ -1,4 +1,3 @@
import { Link } from '@tanstack/react-router';
import type React from 'react';
import { BusterLogoWithText } from '@/assets/svg/BusterLogoWithText';
import { Text } from '@/components/ui/typography';
@ -10,9 +9,9 @@ export const WelcomeToBuster: React.FC<{
<div className="flex h-full w-full flex-col justify-between p-10">
<div>
<div className="w-[130px]">
<Link to={'/'}>
<a href="https://www.buster.so/" target="_blank" rel="noopener noreferrer">
<BusterLogoWithText />
</Link>
</a>
</div>
<div className="mt-24">
<h1

View File

@ -19,14 +19,23 @@ export const useOAuthMutation = (
setLastUsedMethod: (method: SignInTypes) => void
) => {
return useMutation({
mutationFn,
mutationFn: async () => {
const result = await mutationFn();
if (!result.success) {
throw new Error(result.error || `${type} authentication failed`);
}
return result;
},
onSuccess: (data) => {
if (data.success && data.url) {
setLastUsedMethod(type);
window.location.href = data.url;
}
},
throwOnError: true,
retry: false,
onError: (error) => {
console.error(error);
},
});
};
@ -85,34 +94,43 @@ export const useAuthMutations = (redirectTo?: string | null, onSignUpSuccess?: (
// Email/Password Mutations
const emailSignInMutation = useMutation({
mutationFn: ({ email, password }: { email: string; password: string }) =>
signInWithEmailAndPassword({ data: { email, password, redirectUrl: redirectTo } }),
onSuccess: async (data) => {
if (!data.error) {
setLastUsedMethod('email');
await navigate({ to: redirectTo || '/app/home' });
}
if (data.error) {
throw new Error(data.message);
mutationFn: async ({ email, password }: { email: string; password: string }) => {
const result = await signInWithEmailAndPassword({
data: { email, password, redirectUrl: redirectTo },
});
if (result.error) {
throw new Error(result.message);
}
return result;
},
onSuccess: async () => {
setLastUsedMethod('email');
await navigate({ to: redirectTo || '/app/home' });
},
retry: false,
onError: (error) => {
console.error(error);
},
throwOnError: true,
});
const emailSignUpMutation = useMutation({
mutationFn: ({ email, password }: { email: string; password: string }) =>
signUpWithEmailAndPassword({ data: { email, password, redirectTo } }),
onSuccess: (data) => {
if (data.error) {
throw new Error(data.error);
mutationFn: async ({ email, password }: { email: string; password: string }) => {
const result = await signUpWithEmailAndPassword({ data: { email, password, redirectTo } });
if (!result.success) {
throw new Error(result.error || 'Sign up failed');
}
if (data.success) {
setLastUsedMethod('email');
if (onSignUpSuccess) {
onSignUpSuccess();
}
return result;
},
onSuccess: () => {
setLastUsedMethod('email');
if (onSignUpSuccess) {
onSignUpSuccess();
}
},
retry: false,
onError: (error) => {
console.error(error);
},
});
// Combined state

View File

@ -25,8 +25,5 @@
"@/*": ["./src/*"]
}
},
"references": [
{ "path": "../../packages/server-shared" },
{ "path": "./tsconfig.node.json" }
]
"references": [{ "path": "../../packages/server-shared" }, { "path": "./tsconfig.node.json" }]
}

View File

@ -7,11 +7,5 @@
"types": ["node", "vite/client"],
"skipLibCheck": true
},
"include": [
"vite.config.ts",
"vitest.config.ts",
"vitest.setup.ts"
]
"include": ["vite.config.ts", "vitest.config.ts", "vitest.setup.ts"]
}

View File

@ -1,78 +1,79 @@
{
"$schema": "https://turbo.build/schema.json",
"extends": ["//"],
"tasks": {
"build": {
"dependsOn": ["^build", "@buster/server-shared#build"],
"inputs": [
"src/**/*",
"!src/**/*.test.{ts,tsx,js,jsx}",
"!src/**/*.spec.{ts,tsx,js,jsx}",
"public/**/*",
"next.config.mjs",
"tailwind.config.ts",
"tsconfig.json",
"package.json"
],
"outputs": [".output/**", ".vercel/**"]
},
"build:vercel": {
"dependsOn": ["^build:vercel", "@buster/server-shared#build"],
"inputs": [
"src/**/*",
"!src/**/*.test.{ts,tsx,js,jsx}",
"!src/**/*.spec.{ts,tsx,js,jsx}",
"public/**/*",
"next.config.mjs",
"tailwind.config.ts",
"tsconfig.json",
"package.json"
],
"outputs": [".output/**", ".vercel/**"]
},
"start": {
"dependsOn": ["build"],
"cache": true,
"persistent": true
},
"test": {
"inputs": [
"src/**/*",
"**/*.test.{ts,tsx,js,jsx}",
"**/*.spec.{ts,tsx,js,jsx}",
"playwright-tests/**/*",
"vitest.config.ts",
"package.json"
]
},
"dev": {
"dependsOn": ["@buster/server-shared#build"],
"cache": false,
"persistent": true,
"inputs": [
"src/**/*",
"!src/**/*.test.{ts,tsx,js,jsx}",
"!src/**/*.spec.{ts,tsx,js,jsx}",
"next.config.mjs",
"tailwind.config.ts",
"tsconfig.json",
"package.json"
]
},
"dev:fast": {
"dependsOn": ["@buster/server-shared#build"],
"cache": false,
"persistent": true,
"inputs": [
"src/**/*",
"!src/**/*.test.{ts,tsx,js,jsx}",
"!src/**/*.spec.{ts,tsx,js,jsx}",
"next.config.mjs",
"tailwind.config.ts",
"tsconfig.json",
"package.json"
]
}
"$schema": "https://turbo.build/schema.json",
"extends": ["//"],
"tasks": {
"build": {
"dependsOn": ["^build", "@buster/server-shared#build"],
"inputs": [
"src/**/*",
"public/**/*",
"tsconfig.json",
"package.json",
"vite.config.ts",
"nitro.config.ts",
"!src/**/*.test.{ts,tsx,js,jsx}",
"!src/**/*.spec.{ts,tsx,js,jsx}",
"!src/**/*.stories.{ts,tsx,js,jsx}"
],
"outputs": [".output/**", ".vercel/**"]
},
"build:vercel": {
"dependsOn": ["^build:vercel", "@buster/server-shared#build"],
"inputs": [
"src/**/*",
"!src/**/*.test.{ts,tsx,js,jsx}",
"!src/**/*.spec.{ts,tsx,js,jsx}",
"public/**/*",
"next.config.mjs",
"tailwind.config.ts",
"tsconfig.json",
"package.json"
],
"outputs": [".output/**", ".vercel/**"]
},
"start": {
"dependsOn": ["build", "@buster-app/supabase#start"],
"cache": true,
"persistent": true,
"with": ["@buster-app/server#start", "@buster-app/api-legacy#start"]
},
"test": {
"inputs": [
"src/**/*",
"**/*.test.{ts,tsx,js,jsx}",
"**/*.spec.{ts,tsx,js,jsx}",
"playwright-tests/**/*",
"vitest.config.ts",
"package.json"
]
},
"dev": {
"dependsOn": ["@buster/server-shared#build"],
"cache": false,
"persistent": true,
"inputs": [
"src/**/*",
"!src/**/*.test.{ts,tsx,js,jsx}",
"!src/**/*.spec.{ts,tsx,js,jsx}",
"next.config.mjs",
"tailwind.config.ts",
"tsconfig.json",
"package.json"
]
},
"dev:fast": {
"dependsOn": ["@buster/server-shared#build"],
"cache": false,
"persistent": true,
"inputs": [
"src/**/*",
"!src/**/*.test.{ts,tsx,js,jsx}",
"!src/**/*.spec.{ts,tsx,js,jsx}",
"next.config.mjs",
"tailwind.config.ts",
"tsconfig.json",
"package.json"
]
}
}
}

View File

@ -93,7 +93,8 @@
"vitest.config.ts",
"biome.json",
"./package.json",
"./turbo.json"
"./turbo.json",
"./biome2.json"
],
"ignore": [
"**/node_modules/**",

125
biome2.json Normal file
View File

@ -0,0 +1,125 @@
{
"$schema": "https://biomejs.dev/schemas/2.2.4/schema.json",
"files": {
"ignoreUnknown": false,
"includes": [
".vscode/**/*",
"**/.html",
"**/*.json",
"**/*.ts",
"**/*.tsx",
"**/*.js",
"**/*.jsx",
"**/*.css",
"**/*.mjs",
"**/*.cjs",
"!**/node_modules",
"!**/dist",
"!**/build",
"!**/coverage",
"!**/.output",
"!apps/api",
"!apps/supabase"
]
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"correctness": {
"noUnusedVariables": "error",
"noUnusedImports": "off",
"useExhaustiveDependencies": "off"
},
"style": {
"noNonNullAssertion": "error",
"useImportType": "warn",
"useNodejsImportProtocol": "error",
"useConsistentArrayType": "error",
"noUnusedTemplateLiteral": "off"
},
"suspicious": {
"noExplicitAny": "error",
"noConsole": "warn",
"noTemplateCurlyInString": "off"
},
"complexity": {
"noExcessiveCognitiveComplexity": "off",
"noForEach": "off"
},
"nursery": {
"useSortedClasses": "off"
},
"performance": {
"noDelete": "error"
}
}
},
"overrides": [
{
"includes": [
"**/*.test.ts",
"**/*.test.tsx",
"**/*.spec.ts",
"**/*.spec.tsx",
"**/*.stories.tsx",
"**/*.setup.*",
"**/*.js"
],
"linter": {
"rules": {
"suspicious": {
"noExplicitAny": "off",
"noConsole": "off"
},
"style": {
"noNonNullAssertion": "off"
},
"correctness": {
"noUnusedFunctionParameters": "off",
"noUnusedVariables": "off"
}
}
}
},
{
"includes": ["**/*.css"],
"linter": {
"enabled": false
}
}
],
"formatter": {
"enabled": true,
"formatWithErrors": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100,
"lineEnding": "lf"
},
"javascript": {
"formatter": {
"quoteStyle": "single",
"jsxQuoteStyle": "double",
"trailingCommas": "es5",
"semicolons": "always",
"arrowParentheses": "always"
}
},
"json": {
"formatter": {
"enabled": true
}
},
"css": {
"parser": {
"cssModules": true
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100
}
}
}

View File

@ -64,12 +64,10 @@
"packageManager": "pnpm@10.17.1",
"pnpm": {
"peerDependencyRules": {
"ignoreMissing": [
"shiki"
],
"ignoreMissing": ["shiki"],
"allowedVersions": {
"shiki": "3"
}
}
}
}
}

View File

@ -16,8 +16,6 @@
"prebuild": "[ \"$SKIP_ENV_CHECK\" = \"true\" ] || tsx scripts/validate-env.ts",
"build": "tsc",
"build:dry-run": "tsc",
"build:commonjs": "tsc --module commonjs --moduleResolution node",
"build:commonjs:watch": "npm run build:commonjs && tsc --module commonjs --moduleResolution node --watch",
"dev": "tsc --watch",
"dev:fast": "tsc --watch",
"lint": "biome check --write",

View File

@ -2,17 +2,10 @@
"$schema": "https://turborepo.com/schema.json",
"extends": ["//"],
"tasks": {
"build:commonjs": {
"cache": false,
"persistent": false,
"dependsOn": ["@buster/database#build:commonjs"],
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
},
"build:commonjs:watch": {
"cache": false,
"persistent": true,
"dependsOn": ["build:commonjs"]
},
"dev": {
"cache": false,
"persistent": true,

View File

@ -2,21 +2,9 @@
"$schema": "https://turbo.build/schema.json",
"extends": ["//"],
"tasks": {
"dev:mastra": {
"cache": false,
"persistent": true,
"dependsOn": [
"@buster/database#build:commonjs",
"@buster/access-controls#build:commonjs",
"@buster/data-source#build:commonjs",
"@buster/search#build:commonjs"
],
"with": [
"@buster/database#build:commonjs:watch",
"@buster/access-controls#build:commonjs:watch",
"@buster/data-source#build:commonjs:watch",
"@buster/search#build:commonjs:watch"
]
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
},
"dev": {
"cache": false,

View File

@ -16,8 +16,6 @@
"prebuild": "[ \"$SKIP_ENV_CHECK\" = \"true\" ] || tsx scripts/validate-env.ts",
"build": "tsc",
"build:dry-run": "tsc",
"build:commonjs": "tsc --module commonjs --moduleResolution node",
"build:commonjs:watch": "npm run build:commonjs && tsc --module commonjs --moduleResolution node --watch",
"lint": "biome check --write",
"lint:fix": "biome check --write",
"test": "vitest run",

View File

@ -2,15 +2,9 @@
"$schema": "https://turborepo.com/schema.json",
"extends": ["//"],
"tasks": {
"build:commonjs": {
"cache": false,
"persistent": false,
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
},
"build:commonjs:watch": {
"cache": false,
"persistent": true,
"dependsOn": ["build:commonjs"]
}
}
}

View File

@ -7,16 +7,19 @@ import { config } from 'dotenv';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Find the root of the monorepo (where turbo.json is)
// Find the root of the monorepo (where turbo.json and pnpm-workspace.yaml are)
function findMonorepoRoot(): string {
let currentDir = __dirname;
while (currentDir !== '/') {
if (existsSync(path.join(currentDir, 'turbo.json'))) {
const turboPath = path.join(currentDir, 'turbo.json');
const pnpmWorkspacePath = path.join(currentDir, 'pnpm-workspace.yaml');
// Look for both turbo.json AND pnpm-workspace.yaml to ensure we find the actual root
if (existsSync(turboPath) && existsSync(pnpmWorkspacePath)) {
return currentDir;
}
currentDir = path.dirname(currentDir);
}
throw new Error('Could not find monorepo root (turbo.json)');
throw new Error('Could not find monorepo root (turbo.json + pnpm-workspace.yaml)');
}
// Load environment variables from root .env file

View File

@ -0,0 +1,10 @@
{
"$schema": "https://turbo.build/schema.json",
"extends": ["//"],
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
}
}
}

View File

@ -0,0 +1,10 @@
{
"$schema": "https://turbo.build/schema.json",
"extends": ["//"],
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
}
}
}

View File

@ -0,0 +1,10 @@
{
"$schema": "https://turbo.build/schema.json",
"extends": ["//"],
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
}
}
}

10
packages/sdk/turbo.json Normal file
View File

@ -0,0 +1,10 @@
{
"$schema": "https://turbo.build/schema.json",
"extends": ["//"],
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
}
}
}

View File

@ -0,0 +1,10 @@
{
"$schema": "https://turbo.build/schema.json",
"extends": ["//"],
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
}
}
}

10
packages/slack/turbo.json Normal file
View File

@ -0,0 +1,10 @@
{
"$schema": "https://turbo.build/schema.json",
"extends": ["//"],
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
}
}
}

View File

@ -0,0 +1,10 @@
{
"$schema": "https://turbo.build/schema.json",
"extends": ["//"],
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
}
}
}

View File

@ -0,0 +1,10 @@
{
"$schema": "https://turbo.build/schema.json",
"extends": ["//"],
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
}
}
}

View File

@ -232,8 +232,8 @@ importers:
version: 3.25.76
devDependencies:
momentic:
specifier: ^2.16.0
version: 2.16.0(@types/node@24.3.1)
specifier: ^2.17.3
version: 2.17.3(@types/node@24.3.1)
tsx:
specifier: 'catalog:'
version: 4.20.5
@ -9969,8 +9969,8 @@ packages:
moment@2.30.1:
resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==}
momentic@2.16.0:
resolution: {integrity: sha512-HxaPDj5B7c5+BTE/gbun5SqCGjnPfAjcjbvrzi3LQP9qCnEntI/IKddN38D613+aPe8Rif1ZAq5pjtMRNWrGcQ==}
momentic@2.17.3:
resolution: {integrity: sha512-PiAcdojIpywPU0gOR9MApgRsqxY3VgmLMpimJubkVNslFI+re9DBFI/9avdAIKdezZBCRgtx1dgVGDmKmSBx+g==}
engines: {node: '>=20'}
hasBin: true
@ -23554,7 +23554,7 @@ snapshots:
moment@2.30.1: {}
momentic@2.16.0(@types/node@24.3.1):
momentic@2.17.3(@types/node@24.3.1):
dependencies:
'@actions/exec': 1.1.1
'@actions/io': 1.1.3

View File

@ -4,62 +4,34 @@
"concurrency": "20",
"tasks": {
"build": {
"dependsOn": [
"^build"
],
"outputs": [
"dist/**",
".next/**"
]
"dependsOn": ["^build"]
},
"build:dry-run": {
"dependsOn": [
"^build:dry-run"
],
"outputs": [
"dist/**",
".next/**"
],
"env": [
"SKIP_ENV_CHECK"
]
"dependsOn": ["^build:dry-run"],
"env": ["SKIP_ENV_CHECK"]
},
"dev": {
"cache": false,
"persistent": true
},
"momentic": {
"cache": false,
"persistent": true
},
"dev:fast": {
"cache": false,
"persistent": true
},
"lint": {
"dependsOn": [
"^lint"
]
"dependsOn": ["^lint"]
},
"typecheck": {
"dependsOn": [
"^build"
]
"dependsOn": ["^build"]
},
"test": {
"dependsOn": [
"^build"
]
"dependsOn": ["^build"]
},
"test:unit": {
"dependsOn": [
"^test:unit"
]
"dependsOn": ["^test:unit"]
},
"test:integration": {
"dependsOn": [
"^build"
]
"dependsOn": ["^build"]
},
"test:watch": {
"cache": false,
@ -74,53 +46,13 @@
"persistent": true
},
"test:coverage": {
"dependsOn": [
"^build"
],
"outputs": [
"coverage/**"
]
},
"build:commonjs": {
"cache": false,
"persistent": false,
"outputs": [
"dist/**"
]
},
"build:commonjs:watch": {
"cache": false,
"persistent": true,
"dependsOn": [
"build:commonjs"
]
},
"db:migrate": {
"cache": false,
"env": [
"NODE_TLS_REJECT_UNAUTHORIZED"
]
},
"db:seed": {
"cache": false,
"env": [
"DATABASE_URL",
"ENVIRONMENT",
"NODE_ENV"
]
},
"db:init": {
"cache": false,
"dependsOn": ["db:migrate"],
"env": [
"DATABASE_URL",
"ENVIRONMENT",
"NODE_ENV"
]
"dependsOn": ["^build"],
"outputs": ["coverage/**"]
}
},
"globalEnv": [
"NODE_ENV",
"NODE_TLS_REJECT_UNAUTHORIZED",
"CI",
"VERCEL",
"VERCEL_ENV",
@ -181,4 +113,4 @@
"NODE_TLS_REJECT_UNAUTHORIZED"
],
"envMode": "strict"
}
}