Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .changeset/fix-generated-client-types-import.md

This file was deleted.

31 changes: 31 additions & 0 deletions .changeset/fix-native-sqlite-esm-database-build.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
"@tinacms/cli": minor
"@tinacms/schema-tools": minor
---

Fix native SQLite (and other native CJS adapters) crashing the ESM database build, plus surrounding cleanup work.

**The bug.** Since Tina v3's December 2025 ESM migration, bundling `tina/database.ts` with esbuild — and writing the output to `os.tmpdir()` — left users wedged between two failure modes: bundling native modules like `better-sqlite3` crashed with `__filename is not defined`, and externalizing them couldn't resolve `node_modules` from `/tmp/`. See #6675.

**What changed:**

- `loadDatabaseFile` and `loadConfigFile` now write esbuild output to `<project>/tina/__generated__/.cache/<timestamp>/` instead of `os.tmpdir()`, so Node's resolver can walk up to the project's `node_modules` at runtime.
- `better-sqlite3` is externalized so Node loads it as CJS where `__filename` exists.
- The build cache is swept on startup (clears residue from crashed prior runs), and each per-build subdir + its now-empty timestamp parent are removed after the dynamic-import resolves.
- Read-only project mounts (Docker `:ro` volumes, AWS Lambda's `/var/task`, sandboxed CI runners) now fail with an actionable error explaining the cause and resolution, instead of a cryptic mid-build `EACCES`.
- New `defineConfig` field: `build.externalDependencies?: string[]`. Users with custom native adapters outside the baseline can extend the externalize list from their config:

```ts
// tina/config.ts
export default defineConfig({
build: {
publicFolder: 'public',
outputFolder: 'admin',
externalDependencies: ['my-custom-native-adapter'],
},
// ...
});
```

Externalized packages must be installed in the project's `node_modules` so Node can resolve them at runtime.
- `tina init` now adds `tina/__generated__` to `.gitignore` for new projects (and existing projects without it).
5 changes: 0 additions & 5 deletions .changeset/fresh-tomatoes-look.md

This file was deleted.

5 changes: 5 additions & 0 deletions .changeset/search-sqlite-level-esm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tinacms/search": patch
---

Bump `sqlite-level` to `^2.0.0` and switch back to a named `import { SqliteLevel } from 'sqlite-level'`. The previous namespace-import workaround was needed because `sqlite-level` shipped as CJS and esbuild's default-import rewrite broke ESM named-export resolution; with the upstream CJS-to-ESM migration ([tinacms/sqlite-level#24](https://github.com/tinacms/sqlite-level/pull/24)) released as `sqlite-level@2.0.0`, that workaround is no longer required.
7 changes: 7 additions & 0 deletions packages/@tinacms/app/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# @tinacms/app

## 2.4.8

### Patch Changes

- Updated dependencies []:
- tinacms@3.8.1

## 2.4.7

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/@tinacms/app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tinacms/app",
"version": "2.4.7",
"version": "2.4.8",
"main": "src/main.tsx",
"license": "Apache-2.0",
"devDependencies": {
Expand Down
12 changes: 12 additions & 0 deletions packages/@tinacms/cli/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# tinacms-cli

## 2.3.1

### Patch Changes

- [#6850](https://github.com/tinacms/tinacms/pull/6850) [`629af08`](https://github.com/tinacms/tinacms/commit/629af08dc4b6dbe7ed652cbc5dfd55699b0fffa9) Thanks [@18-th](https://github.com/18-th)! - Fix the generated `client.ts` / `databaseClient.ts` `./types` import so it satisfies both TypeScript strict mode and Node native ESM. The generated import is now `import { queries } from "./types.js"` unconditionally, and the CLI emits a co-resident `types.js` alongside `types.ts` for TypeScript projects. Modern TS module resolution (`bundler` / `node16` / `nodenext`) rewrites the `.js` import back to `types.ts` at compile time, so type checking still sees the `.ts` source and `allowImportingTsExtensions` is not required, while Node ESM consumers resolve the on-disk `.js` file at runtime.

- Updated dependencies [[`890108d`](https://github.com/tinacms/tinacms/commit/890108dd6c1a88a1c5531cf397514c34712d13bd)]:
- @tinacms/graphql@2.4.1
- @tinacms/search@1.2.15
- tinacms@3.8.1
- @tinacms/app@2.4.8

## 2.3.0

### Minor Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/@tinacms/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@tinacms/cli",
"type": "module",
"version": "2.3.0",
"version": "2.3.1",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"files": [
Expand Down
11 changes: 10 additions & 1 deletion packages/@tinacms/cli/src/cmds/init/apply.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ async function apply({
if (!env.gitIgnoreEnvExists) {
itemsToAdd.push('.env');
}
if (!env.gitIgnoreTinaGeneratedExists) {
// Tina writes generated artifacts (including the build cache used to
// bundle tina/database.ts and tina/config.ts) under tina/__generated__/.
// None of it should be committed.
itemsToAdd.push('tina/__generated__');
}
if (itemsToAdd.length > 0) {
await updateGitIgnore({ baseDir, items: itemsToAdd });
}
Expand Down Expand Up @@ -272,7 +278,10 @@ const createPackageJSON = async () => {
};
const createGitignore = async ({ baseDir }: { baseDir: string }) => {
logger.info(logText('No .gitignore found, creating one'));
fs.outputFileSync(path.join(baseDir, '.gitignore'), 'node_modules');
fs.outputFileSync(
path.join(baseDir, '.gitignore'),
'node_modules\ntina/__generated__\n'
);
};

const updateGitIgnore = async ({
Expand Down
10 changes: 10 additions & 0 deletions packages/@tinacms/cli/src/cmds/init/detectEnvironment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,15 @@ const detectEnvironment = async ({
(await checkGitignoreForItem({ baseDir, line: '.env.tina' }));
const hasGitIgnoreEnv =
hasGitIgnore && (await checkGitignoreForItem({ baseDir, line: '.env' }));
// Tina writes generated artifacts (including the build cache used by the CLI
// to bundle tina/database.ts and tina/config.ts) under tina/__generated__/.
// Anything under that path is build output and should not be committed.
const hasGitIgnoreTinaGenerated =
hasGitIgnore &&
(await checkGitignoreForItem({
baseDir,
line: 'tina/__generated__',
}));
let frontMatterFormat: ContentFrontmatterFormat;
if (hasForestryConfig) {
const hugoConfigPath = path.join(rootPath, 'config.toml');
Expand All @@ -194,6 +203,7 @@ const detectEnvironment = async ({
gitIgnoreNodeModulesExists: hasGitIgnoreNodeModules,
gitIgnoreEnvExists: hasGitIgnoreEnv,
gitIgnoreTinaEnvExists: hasEnvTina,
gitIgnoreTinaGeneratedExists: hasGitIgnoreTinaGenerated,
packageJSONExists: hasPackageJSON,
sampleContentExists: hasSampleContent,
sampleContentPath,
Expand Down
1 change: 1 addition & 0 deletions packages/@tinacms/cli/src/cmds/init/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export type InitEnvironment = {
gitIgnoreNodeModulesExists: boolean;
gitIgnoreTinaEnvExists: boolean;
gitIgnoreEnvExists: boolean;
gitIgnoreTinaGeneratedExists: boolean;
packageJSONExists: boolean;
sampleContentExists: boolean;
sampleContentPath: string;
Expand Down
Loading
Loading