uql-codemod 0.48.2 → 0.50.0
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.
- package/README.md +23 -12
- package/dist/builders.d.ts +28 -0
- package/dist/builders.js +783 -0
- package/dist/classOptions.d.ts +9 -0
- package/dist/classOptions.js +240 -0
- package/dist/columnMethods.d.ts +11 -0
- package/dist/columnMethods.js +6 -0
- package/dist/columnRefs.js +1 -8
- package/dist/context.d.ts +18 -5
- package/dist/context.js +22 -4
- package/dist/definers.d.ts +24 -0
- package/dist/definers.js +34 -0
- package/dist/edits.d.ts +26 -5
- package/dist/edits.js +54 -12
- package/dist/entitySql.js +2 -4
- package/dist/imports.d.ts +21 -5
- package/dist/imports.js +103 -31
- package/dist/index.d.ts +3 -3
- package/dist/index.js +9 -12
- package/dist/jsonIndex.d.ts +11 -0
- package/dist/jsonIndex.js +78 -0
- package/dist/keyMaps.d.ts +3 -1
- package/dist/keyMaps.js +5 -1
- package/dist/migrationBuilders.d.ts +13 -0
- package/dist/migrationBuilders.js +182 -0
- package/dist/relationTarget.d.ts +6 -0
- package/dist/relationTarget.js +21 -0
- package/dist/schemaEntity.d.ts +15 -0
- package/dist/schemaEntity.js +578 -0
- package/dist/schemaMessages.d.ts +8 -0
- package/dist/schemaMessages.js +8 -0
- package/dist/schemaOptions.d.ts +6 -0
- package/dist/schemaOptions.js +6 -0
- package/dist/syntax.d.ts +54 -0
- package/dist/syntax.js +131 -1
- package/dist/transform.d.ts +11 -2
- package/dist/transform.js +142 -131
- package/dist/tsconfig.d.ts +3 -9
- package/dist/tsconfig.js +18 -21
- package/package.json +1 -1
- package/dist/fieldType.d.ts +0 -13
- package/dist/fieldType.js +0 -56
package/README.md
CHANGED
|
@@ -24,35 +24,46 @@ Only `--flag=value` is read, and anything unrecognised is an error. It exits `0`
|
|
|
24
24
|
|
|
25
25
|
## What it rewrites
|
|
26
26
|
|
|
27
|
-
- `
|
|
28
|
-
- `
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
- `
|
|
27
|
+
- `virtual` to `computed` (on `@Field` and in `defineEntity`'s `fields`), a check's `expression` and a filter's `condition` to `where` (`@Entity`, `defineEntity`, `@Filter`), `raw('...')` to the `sql` tagged template, and a second argument onto `.as()`.
|
|
28
|
+
- A column's options to its builder, last, after the rewrites above: `@Id()` and `@Field({ type: String, nullable: true, length: 80 })` to `@Field(f.number().id())` and `@Field(f.string().nullable().length(80))`, a NOT NULL column losing its `nullable: false`, `computed` to `@Computed((row) => f.string().as(...))` or `@Computed((row) => row.books.count())`, and a schema's `fields` likewise; a schema's other options to the sections chained after it, and its `aggregates` to `.relations()`' second callback. A schema column's foreign key becomes a relation: its `references` is dropped where a relation joins on the column (by `(order) => order.customerId`, by `[{ local, foreign }]` pairs, or as the ORM infers the one column naming its target, written into it), its `onDelete` moved into that relation, and where none joins, a `manyToOne` named as the column less its `Id` is written for it: `customer: () => rel.manyToOne(Customer, { references: (order) => order.customerId })`. Then each index, check and trigger entry, in `@Entity` and a schema, goes to the helper its callback is handed: `(post, index) => [index([post.title], 'by_title')]`.
|
|
29
|
+
- A migration's columns to the same methods: `table.string('email', { length: 80, nullable: true })` to `table.string('email').length(80).nullable()`, `.defaultValue()` to `.default()`, `.primaryKey()` to `.id()`, `.computed()` to `.as()`, and `.notNullable()` dropped.
|
|
30
|
+
- `@Index`, `@Trigger` and `@Filter` into `@Entity`'s `indexes`, `triggers` and `filters`, each decorator's comments kept above its entry; a class with no `@Entity` becomes `@Entity({ abstract: true, ... })`, a base that is never a table.
|
|
31
|
+
- Members named by string to callbacks: `mappedBy: 'author'` to `(post) => post.author`, and `include`, `references` and `@Entity`/`defineEntity`'s `indexes` and `hooks` likewise: `{ columns: (post) => [post.title] }`.
|
|
32
|
+
- `references: (post) => post.authorId` on a to-one (`@ManyToOne`, `@OneToOne`, or in `defineEntity`) that names no foreign key, declaring `@Field({ references: () => User }) authorId` first on a decorated class that has no such column, typed as the key it points at.
|
|
32
33
|
- A partial-index `where` string to `sql`, importing it, on entities and in the migration builder.
|
|
34
|
+
- A class registered with `defineEntity(Post, { ... })` to the schema it declares, whole or not at all: `export const Post = defineEntity({ name: 'Post', fields })` with its sections chained, as a schema's options are above, and `export type Post = InstanceType<typeof Post>`. The class is removed and a table it named kept as `table`; a field stating no `type` takes the one its property declares (`authorId?: number | null` is `f.number().nullable()`), each relation becomes `author: () => rel.manyToOne(User, { ... })`, a relation aggregate a derived field (`(post) => ({ total: () => post.comments.count() })`), a hook's method a function of the row (`this` read as the row), and the same class's `defineField`, `defineId`, `defineRelation`, `defineHook`, `defineIndex`, `defineTrigger` and `defineFilter` are folded in.
|
|
35
|
+
- A JSON index entry to the path read off the column's ref: `{ column: post.kind, jsonPath: { path: 'theme', type: Number } }` to `{ column: post.kind.theme, type: Number }`, and a `jsonArray`'s element type to `type: [String]`.
|
|
33
36
|
- `col('cost')` to the ref it names, ``(product) => sql`${product.cost}` `` in a `computed` and `refs(Item).cost` in a statement, and `$lock: { wait: 'skip' }` to `{ $wait: 'skip' }`, or to `true` for `{}` and a `'block'` wait.
|
|
37
|
+
- `$exclude` to a `$select` leaving its fields out: `$exclude: { password: true }` to `$select: { password: false }`, at every depth of `$populate`.
|
|
34
38
|
- An aggregate's `$agg` to `$select`, and each field it or `$text`'s `$fields` names to a key: `{ $sum: { amount: true } }`.
|
|
35
|
-
- Renamed exports, at the import and every use: `raw` to `sql`, `QueryWhereMap` to `QueryWhere`, `RelationKeyMap` to `KeyMap`, `FilterCondition` to `FilterWhere`, `SqlMigrationModuleOptions` to `MigrationModuleOptions`, `buildSqlQuerierMigrationModule` to `buildMigrationModule`, `QueryDialect` to `SqlQueryDialect`, `EngineFeatures` to `DialectFeatures`, `KnownMigratorDialect` to `DialectName`, `D1Preparer`/`D1Database` to `D1Queryable`, and the removed driver classes to the one each extended: `PgDialect`/`NeonDialect`/`PgliteDialect` to `PostgresDialect`, `CrdbQuerier`/`NeonQuerier` to `PgQuerier`, `LibsqlQuerier`/`TursoQuerier` to `HranaQuerier`, `TursoLocalQuerier` to `SqliteQuerier` and `TursoDatabase` to `SqliteDatabase`, `MySql2Dialect` to `MySqlDialect`, `MongodbNativeDialect` to `MongoDialect`, `Sqlite3QuerierPool` to `SqliteQuerierPool`, the migration builder's `I`-prefixed types to the unprefixed name, moving the import to the entry that exports it; and `MongoQuerier`, `isMongoQuerier` and `MongoSchemaIntrospector` to `uql-orm/mongodb`.
|
|
39
|
+
- Renamed exports, at the import and every use: `raw` to `sql`, `QueryWhereMap` to `QueryWhere`, `IndexColumnSchema` to `IndexEntry`, `IndexColumnModifiers` to `IndexEntryModifiers`, `RelationKeyMap` to `KeyMap`, `FilterCondition` to `FilterWhere`, `SqlMigrationModuleOptions` to `MigrationModuleOptions`, `buildSqlQuerierMigrationModule` to `buildMigrationModule`, `QueryDialect` to `SqlQueryDialect`, `EngineFeatures` to `DialectFeatures`, `KnownMigratorDialect` to `DialectName`, `D1Preparer`/`D1Database` to `D1Queryable`, and the removed driver classes to the one each extended: `PgDialect`/`NeonDialect`/`PgliteDialect` to `PostgresDialect`, `CrdbQuerier`/`NeonQuerier` to `PgQuerier`, `LibsqlQuerier`/`TursoQuerier` to `HranaQuerier`, `TursoLocalQuerier` to `SqliteQuerier` and `TursoDatabase` to `SqliteDatabase`, `MySql2Dialect` to `MySqlDialect`, `MongodbNativeDialect` to `MongoDialect`, `Sqlite3QuerierPool` to `SqliteQuerierPool`, the migration builder's `I`-prefixed types to the unprefixed name (`IColumnBuilder`/`IColumnFactory`, and `uql-orm/migrate`'s `ColumnBuilder`/`ColumnFactory`, to `TableColumnBuilder`/`TableColumnFactory`), moving the import to the entry that exports it; and `MongoQuerier`, `isMongoQuerier` and `MongoSchemaIntrospector` to `uql-orm/mongodb`.
|
|
36
40
|
- Imports off `uql-orm/maria`, `uql-orm/mongo` and `uql-orm/bunSql` to `uql-orm/mariadb`, `uql-orm/mongodb` and `uql-orm/bun-sql`, and off `uql-orm/type`, `uql-orm/dialect`, `uql-orm/entity`, `uql-orm/querier` and `uql-orm/namingStrategy` to `uql-orm`.
|
|
37
41
|
- The `[idKey]?: '...'` brand, and its import, on a key not called `id`, `_id` or `uuid` and on every composite.
|
|
38
|
-
- `import 'reflect-metadata'`, and `experimentalDecorators`/`emitDecoratorMetadata` in `tsconfig.json`, comments and formatting kept.
|
|
39
42
|
|
|
40
43
|
## What it leaves to you
|
|
41
44
|
|
|
42
45
|
Reported with what to do, never guessed:
|
|
43
46
|
|
|
44
|
-
- `target: esnext`, the one target that leaves decorators untransformed,
|
|
47
|
+
- `target: esnext`, the one target that leaves decorators untransformed, a value inherited through `extends`, and `experimentalDecorators`/`emitDecoratorMetadata` in `tsconfig.json`, which the standard spec replaces: remove those by hand.
|
|
45
48
|
- `@Log()`, `@Serialized()`, `@Transactional()` and `@InjectQuerier()`: a `@Transactional()` method becomes a `pool.transaction()` around its body, and only you know which pool.
|
|
46
49
|
- An export removed with no one-to-one replacement (`setQuerierPool`, `getQuerier`, `augmentWhere`, `AbstractPgQuerier`, ...), an internal the root no longer exports (`AbstractSqlQuerier`, `fieldOf`, ...), the migration storages, and any import from `uql-orm/util` the root does not export (`refs`, ... move to `uql-orm`).
|
|
47
50
|
- A value it cannot read: options passed as a variable or a spread, a list that is not a literal, a key under a computed name.
|
|
51
|
+
- An `$exclude` it cannot read, or one beside a `$select`: merge it in, each field as `field: false`.
|
|
48
52
|
- A to-one onto a composite key: declare a column per key and pair each with it in `references`.
|
|
49
|
-
- A to-one whose `<relation>Id` is not a declared column: an undecorated property, a `defineEntity` whose `fields` leave it out
|
|
53
|
+
- A to-one whose `<relation>Id` is not a declared column: an undecorated property, or a `defineEntity` whose `fields` leave it out.
|
|
54
|
+
- A class `defineEntity` registers that a schema cannot declare as it is: one that extends another class, has a method no hook runs or is decorated as well; options it cannot read, or a column or section its chain cannot write; a class registered in another file, or an entity that is no class declared in the file. It is left as written, each reason reported.
|
|
55
|
+
- A schema column's foreign key no relation can take: one whose relation name (the column less its `Id`) is taken or cannot be read off it, a key with no type of its own (`f.references(() => Order)`), or an `onDelete` its relation contradicts.
|
|
56
|
+
- A definer on a decorated class (`defineIndex(Post, ...)`), and `@Entity`'s `fields`, `relations`, `hooks` and `extends`: each is a decorator, or the class's own `extends`, now.
|
|
57
|
+
- A property typed more narrowly than its schema derives, as a note: a `Json<T>` column wants a Standard Schema, a string-literal union `enum`.
|
|
50
58
|
- A partial-index `where` string that interpolates, since `sql` would bind what the template spliced in.
|
|
59
|
+
- A JSON index entry whose `path` is not a string literal, or that takes an option besides `path`, `type` and `length`.
|
|
51
60
|
- A `col()` whose entity it cannot tell: a raw built apart from its query, one under a relation filter, or a column no field maps.
|
|
52
61
|
- SQL in a definition that names a column by hand, as a note: a rename reaches a callback's refs, ``(user) => sql`lower(${user.email})` ``, and never the text.
|
|
53
|
-
- A file that already names something the codemod would write (`sql`, `refs`, `idKey`, a renamed export): left unchanged and reported, since the new import would shadow it or be shadowed.
|
|
62
|
+
- A file that already names something the codemod would write (`sql`, `refs`, `idKey`, `f`, a renamed export): left unchanged and reported, since the new import would shadow it or be shadowed.
|
|
54
63
|
- A property whose type maps to no column (`Json<T>`, a vector, a mixed union).
|
|
55
|
-
- A
|
|
64
|
+
- A column option it cannot write as a method: a `shape` a JSON column no longer takes, a migration column's options passed as a variable, or a flag such as `unique: isUnique` that no literal states.
|
|
65
|
+
- A `@Field`/`@Id` with no `type`, and a relation with no `entity`: declare the column as a builder (`f.string()`) and name the target (`entity: () => Target`). A branded string id's column, `f.uuid()` or `f.string()`, is yours to pick.
|
|
66
|
+
- `Relation<T>` imported from `uql-orm`, which no longer exports it: write the property's type without it, and drop the import.
|
|
56
67
|
|
|
57
68
|
## After it runs
|
|
58
69
|
|
|
@@ -60,7 +71,7 @@ Reported with what to do, never guessed:
|
|
|
60
71
|
|
|
61
72
|
## Why TypeScript 6
|
|
62
73
|
|
|
63
|
-
Reading each property's type needs the checker, so TypeScript is a runtime dependency. 7's entry point exports no compiler API yet and has no standalone parser, which the `tsconfig.json`
|
|
74
|
+
Reading each property's type needs the checker, so TypeScript is a runtime dependency. 7's entry point exports no compiler API yet and has no standalone parser, which the `tsconfig.json` check needs to read its comments; revisit once that API is stable.
|
|
64
75
|
|
|
65
76
|
## License
|
|
66
77
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import { type Pass } from './edits.js';
|
|
3
|
+
export type BuildersResult = Pass & {
|
|
4
|
+
readonly unresolved: string[];
|
|
5
|
+
};
|
|
6
|
+
/** Whether `node` is already a builder, `f.string()...`. */
|
|
7
|
+
export declare function isBuilder(node: ts.Expression): boolean;
|
|
8
|
+
/** The names a builder writes, which the file must not bind otherwise. */
|
|
9
|
+
export declare const BUILDER_NAMES: ReadonlySet<string>;
|
|
10
|
+
/**
|
|
11
|
+
* Writes entity definitions as column builders, `@Field(f.string().nullable())`, and a schema as its columns and a
|
|
12
|
+
* chain of sections. Read off the text the other rewrites produced, so it only moves what is written; whatever it
|
|
13
|
+
* cannot write faithfully is left as it is and reported.
|
|
14
|
+
*/
|
|
15
|
+
export declare function toBuilders(fileName: string, text: string, { locate, taken }: {
|
|
16
|
+
readonly locate?: (at: number) => string;
|
|
17
|
+
readonly taken: ReadonlySet<string>;
|
|
18
|
+
}): BuildersResult;
|
|
19
|
+
/**
|
|
20
|
+
* A schema's statement, `const X = defineEntity({...})`, its call written as a chain and the builders it writes, or why
|
|
21
|
+
* it cannot be.
|
|
22
|
+
*/
|
|
23
|
+
export declare function chainedSchema(text: string): {
|
|
24
|
+
readonly text: string;
|
|
25
|
+
readonly builders: ReadonlySet<string>;
|
|
26
|
+
} | {
|
|
27
|
+
readonly reasons: readonly string[];
|
|
28
|
+
};
|