turbine-orm 0.73.0 → 0.73.1-next.17e8f0c
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.
|
@@ -100,6 +100,12 @@ export declare function migrationTimestamp(name: string): string | null;
|
|
|
100
100
|
export declare function assertNoEmbeddedTransactions(files: MigrationFile[], section: 'up' | 'down'): void;
|
|
101
101
|
/** Scan a set of migration files' UP sections for data-destroying statements. */
|
|
102
102
|
export declare function collectUpDestructive(files: MigrationFile[]): DestructiveOffender[];
|
|
103
|
+
/**
|
|
104
|
+
* @internal exported for tests. The integration test that covers this races 12
|
|
105
|
+
* concurrent callers and reproduces the bug about 12% of the time, which is not
|
|
106
|
+
* a gate. This entry point lets the RULE be asserted directly, once per code.
|
|
107
|
+
*/
|
|
108
|
+
export declare function ensureTrackingTable(client: MigrationQueryClient, dialect?: Dialect): Promise<void>;
|
|
103
109
|
/**
|
|
104
110
|
* Parse a migration filename into its components.
|
|
105
111
|
* Expected format: YYYYMMDDHHMMSS_description.sql
|
package/dist/cjs/cli/migrate.js
CHANGED
|
@@ -20,6 +20,7 @@ exports.MIGRATION_RECIPES = exports.splitSqlStatements = void 0;
|
|
|
20
20
|
exports.migrationTimestamp = migrationTimestamp;
|
|
21
21
|
exports.assertNoEmbeddedTransactions = assertNoEmbeddedTransactions;
|
|
22
22
|
exports.collectUpDestructive = collectUpDestructive;
|
|
23
|
+
exports.ensureTrackingTable = ensureTrackingTable;
|
|
23
24
|
exports.parseMigrationFilename = parseMigrationFilename;
|
|
24
25
|
exports.headerSafeName = headerSafeName;
|
|
25
26
|
exports.sanitizeName = sanitizeName;
|
|
@@ -150,8 +151,21 @@ function quotedTrackingTable(dialect) {
|
|
|
150
151
|
* already exists` (42P07). `migrate up`/`down` hold the migration lock before
|
|
151
152
|
* they reach here, but `migrate status` and the deploy inspector deliberately do
|
|
152
153
|
* not, and read-only commands should not need a lock to survive each other.
|
|
154
|
+
*
|
|
155
|
+
* 42710 (`duplicate_object`, "type _turbine_migrations already exists") is the
|
|
156
|
+
* third and was missed for six releases, because this set was written from what
|
|
157
|
+
* ONE measured run happened to produce rather than from the rule. Creating a
|
|
158
|
+
* table also creates its composite row TYPE, so a loser can lose on the type
|
|
159
|
+
* instead of on the relation, and which of the three it reports depends on how
|
|
160
|
+
* far it got. The test that covers this threw its failure away as
|
|
161
|
+
* "[object Object]", so the release it eventually blocked named no code at all.
|
|
162
|
+
*/
|
|
163
|
+
const TABLE_ALREADY_EXISTS_CODES = new Set(['23505', '42P07', '42710']);
|
|
164
|
+
/**
|
|
165
|
+
* @internal exported for tests. The integration test that covers this races 12
|
|
166
|
+
* concurrent callers and reproduces the bug about 12% of the time, which is not
|
|
167
|
+
* a gate. This entry point lets the RULE be asserted directly, once per code.
|
|
153
168
|
*/
|
|
154
|
-
const TABLE_ALREADY_EXISTS_CODES = new Set(['23505', '42P07']);
|
|
155
169
|
async function ensureTrackingTable(client, dialect = dialect_js_1.postgresDialect) {
|
|
156
170
|
const sql = dialect.buildMigrationTrackingTable(quotedTrackingTable(dialect));
|
|
157
171
|
try {
|
package/dist/cli/migrate.d.ts
CHANGED
|
@@ -100,6 +100,12 @@ export declare function migrationTimestamp(name: string): string | null;
|
|
|
100
100
|
export declare function assertNoEmbeddedTransactions(files: MigrationFile[], section: 'up' | 'down'): void;
|
|
101
101
|
/** Scan a set of migration files' UP sections for data-destroying statements. */
|
|
102
102
|
export declare function collectUpDestructive(files: MigrationFile[]): DestructiveOffender[];
|
|
103
|
+
/**
|
|
104
|
+
* @internal exported for tests. The integration test that covers this races 12
|
|
105
|
+
* concurrent callers and reproduces the bug about 12% of the time, which is not
|
|
106
|
+
* a gate. This entry point lets the RULE be asserted directly, once per code.
|
|
107
|
+
*/
|
|
108
|
+
export declare function ensureTrackingTable(client: MigrationQueryClient, dialect?: Dialect): Promise<void>;
|
|
103
109
|
/**
|
|
104
110
|
* Parse a migration filename into its components.
|
|
105
111
|
* Expected format: YYYYMMDDHHMMSS_description.sql
|
package/dist/cli/migrate.js
CHANGED
|
@@ -121,9 +121,22 @@ function quotedTrackingTable(dialect) {
|
|
|
121
121
|
* already exists` (42P07). `migrate up`/`down` hold the migration lock before
|
|
122
122
|
* they reach here, but `migrate status` and the deploy inspector deliberately do
|
|
123
123
|
* not, and read-only commands should not need a lock to survive each other.
|
|
124
|
+
*
|
|
125
|
+
* 42710 (`duplicate_object`, "type _turbine_migrations already exists") is the
|
|
126
|
+
* third and was missed for six releases, because this set was written from what
|
|
127
|
+
* ONE measured run happened to produce rather than from the rule. Creating a
|
|
128
|
+
* table also creates its composite row TYPE, so a loser can lose on the type
|
|
129
|
+
* instead of on the relation, and which of the three it reports depends on how
|
|
130
|
+
* far it got. The test that covers this threw its failure away as
|
|
131
|
+
* "[object Object]", so the release it eventually blocked named no code at all.
|
|
132
|
+
*/
|
|
133
|
+
const TABLE_ALREADY_EXISTS_CODES = new Set(['23505', '42P07', '42710']);
|
|
134
|
+
/**
|
|
135
|
+
* @internal exported for tests. The integration test that covers this races 12
|
|
136
|
+
* concurrent callers and reproduces the bug about 12% of the time, which is not
|
|
137
|
+
* a gate. This entry point lets the RULE be asserted directly, once per code.
|
|
124
138
|
*/
|
|
125
|
-
|
|
126
|
-
async function ensureTrackingTable(client, dialect = postgresDialect) {
|
|
139
|
+
export async function ensureTrackingTable(client, dialect = postgresDialect) {
|
|
127
140
|
const sql = dialect.buildMigrationTrackingTable(quotedTrackingTable(dialect));
|
|
128
141
|
try {
|
|
129
142
|
await client.query(sql);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "turbine-orm",
|
|
3
|
-
"version": "0.73.
|
|
3
|
+
"version": "0.73.1-next.17e8f0c",
|
|
4
4
|
"description": "Postgres-native TypeScript ORM, runs on Neon, Vercel Postgres, Cloudflare, Supabase. Streaming cursors, typed errors, single-query nested relations. One dependency, no WASM engine",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"//exports": "Each subpath declares its types PER CONDITION. A single shared top-level \"types\" resolves to the ESM declarations for `require` too, which is TS1479 (\"is an ES module ... cannot be require()d\") for any CJS consumer on moduleResolution node16/nodenext. The require condition points at dist/cjs, which ships its own {\"type\":\"commonjs\"} package.json, so those declarations are CJS declarations. Gated in CI by publint + @arethetypeswrong/cli + a real .cts consumer typecheck (see the package-types job in ci.yml).",
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
"//coverage:cli": "The CLI coverage gate, split into ONE collection run plus a per-file threshold check for every file in it, and an aggregate. c8 enforces a single threshold set per invocation and its --per-file applies the SAME numbers to every file, neither of which can express 'destructive.ts holds 100 while migrate.ts holds 70'. An aggregate-only floor lets the least-covered file spend the whole slack the best-covered file earned: at the measured 3623/2951 lines, migrate.ts could fall from 70.3% to 66.6% with the aggregate still green. So each file gets its OWN floor, checked by re-reporting the coverage already on disk (c8 report re-reads ./coverage/tmp, so this costs no extra test run). The aggregate check is kept as well: it catches all three sagging together inside their individual margins. Per-file gates run FIRST because their failure names the file. DATABASE_URL is neutralized on the collection run: these test files include live migration tests that create and drop tables, and this script runs from prepublishOnly.",
|
|
129
129
|
"test:coverage:cli": "npm run coverage:cli:collect && npm run coverage:cli:gate:destructive && npm run coverage:cli:gate:sql-statements && npm run coverage:cli:gate:pii-guard && npm run coverage:cli:gate:error-catalog && npm run coverage:cli:gate:mcp && npm run coverage:cli:gate:compile-query && npm run coverage:cli:gate:studio && npm run coverage:cli:gate:migrate && npm run coverage:cli:gate:aggregate",
|
|
130
130
|
"//coverage:cli:collect": "--check-coverage=false is load-bearing, not tidying. c8 reads .c8rc.json for defaults, so this COLLECTION step was silently enforcing the MAIN gate's global thresholds against a src/cli-only file set. That is a gate nobody wrote and nobody wanted, and it went unnoticed only because the main floor was low enough (75) for the CLI aggregate (89.29) to clear it by accident. When the main floors were re-baselined to 93/89/78 (see //merge-bug in .c8rc.json) it started failing here, several steps before the per-file gates that are supposed to decide. Thresholds for these files belong to the coverage:cli:gate:* scripts, which pass their own explicitly.",
|
|
131
|
-
"coverage:cli:collect": "DATABASE_URL= c8 --all --check-coverage=false --reporter text --exclude 'src/test/**' --include src/cli/studio.ts --include src/cli/migrate.ts --include src/cli/destructive.ts --include src/cli/sql-statements.ts --include src/cli/pii-predicate-guard.ts --include src/cli/mcp.ts --include src/cli/compile-query.ts --include src/cli/error-catalog.ts tsx --test src/test/studio-write.test.ts src/test/studio-demo.test.ts src/test/studio.test.ts src/test/studio-security.test.ts src/test/migrate.test.ts src/test/migrate-deploy.test.ts src/test/migrate-smoke-fixes.test.ts src/test/destructive-migrations.test.ts src/test/backfill-recipe.test.ts src/test/cli.test.ts src/test/cli-diff-migration.test.ts src/test/cli-flags.test.ts src/test/cli-first-run.test.ts src/test/mcp.test.ts src/test/mcp-relations.test.ts src/test/mcp-pii.test.ts src/test/mcp-pii-round2.test.ts src/test/mcp-agent-tools.test.ts src/test/mcp-compile-query.test.ts",
|
|
131
|
+
"coverage:cli:collect": "DATABASE_URL= c8 --all --check-coverage=false --reporter text --exclude 'src/test/**' --include src/cli/studio.ts --include src/cli/migrate.ts --include src/cli/destructive.ts --include src/cli/sql-statements.ts --include src/cli/pii-predicate-guard.ts --include src/cli/mcp.ts --include src/cli/compile-query.ts --include src/cli/error-catalog.ts tsx --test src/test/studio-write.test.ts src/test/studio-demo.test.ts src/test/studio.test.ts src/test/studio-security.test.ts src/test/migrate.test.ts src/test/migrate-deploy.test.ts src/test/migrate-smoke-fixes.test.ts src/test/tracking-table-race.test.ts src/test/destructive-migrations.test.ts src/test/backfill-recipe.test.ts src/test/cli.test.ts src/test/cli-diff-migration.test.ts src/test/cli-flags.test.ts src/test/cli-first-run.test.ts src/test/mcp.test.ts src/test/mcp-relations.test.ts src/test/mcp-pii.test.ts src/test/mcp-pii-round2.test.ts src/test/mcp-agent-tools.test.ts src/test/mcp-compile-query.test.ts",
|
|
132
132
|
"coverage:cli:gate": "c8 report --all --exclude 'src/test/**' --reporter text --check-coverage",
|
|
133
133
|
"coverage:cli:gate:destructive": "npm run coverage:cli:gate -- --include src/cli/destructive.ts --lines 98 --statements 98 --branches 84 --functions 98",
|
|
134
134
|
"coverage:cli:gate:sql-statements": "npm run coverage:cli:gate -- --include src/cli/sql-statements.ts --lines 100 --statements 100 --branches 98 --functions 100",
|
|
@@ -22,10 +22,12 @@ const orders = await db.orders.findMany({
|
|
|
22
22
|
});
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
`include` is Prisma's word.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
`include` is Prisma's word. Written as a plain object literal TypeScript rejects
|
|
26
|
+
it, but that check does not apply to a spread (`findMany({ ...args })`) or to
|
|
27
|
+
JSON-shaped args, which is how generated and tool-driven code usually arrives.
|
|
28
|
+
On those paths it is ignored rather than refused: the query runs, returns rows,
|
|
29
|
+
and the relation is simply absent from every one of them. Since 0.73.0 it also
|
|
30
|
+
prints a dev-mode warning naming `with`; in production it is silent.
|
|
29
31
|
|
|
30
32
|
## 2. Relation names are derived, and not from the column
|
|
31
33
|
|