@cleverbrush/knex-schema 3.1.0 → 4.0.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.
@@ -0,0 +1,160 @@
1
+ import type { ObjectSchemaBuilder } from '@cleverbrush/schema';
2
+ import type { Knex } from 'knex';
3
+ import type { Entity } from './entity.js';
4
+ import type { DatabaseTableState, MigrationDiff, SchemaSnapshot } from './types.js';
5
+ /**
6
+ * Introspect a PostgreSQL table and return its current state.
7
+ *
8
+ * Queries `information_schema.columns`, `pg_indexes`, `pg_constraint`, and
9
+ * referential constraint metadata to build a complete picture of the table's
10
+ * columns, indexes, foreign keys, and check constraints.
11
+ *
12
+ * @param knex - A configured Knex instance connected to a PostgreSQL database.
13
+ * @param tableName - The table name to introspect.
14
+ * @returns The current database state for the table.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * const dbState = await introspectDatabase(knex, 'users');
19
+ * console.log(dbState.columns); // { id: { type: 'integer', ... }, ... }
20
+ * ```
21
+ */
22
+ export declare function introspectDatabase(knex: Knex, tableName: string): Promise<DatabaseTableState>;
23
+ /**
24
+ * Derive a {@link DatabaseTableState} from a code-first `ObjectSchemaBuilder`
25
+ * without connecting to the database.
26
+ *
27
+ * The result mirrors what {@link introspectDatabase} would return after the
28
+ * schema has been fully applied, so it can be fed directly into
29
+ * {@link diffSchema} as the `dbState` argument. This is the foundation of
30
+ * snapshot-based migration generation.
31
+ *
32
+ * @param schema - An `ObjectSchemaBuilder` with DDL extensions.
33
+ * @returns A {@link DatabaseTableState} representing the schema's ideal DB shape.
34
+ *
35
+ * @example
36
+ * ```ts
37
+ * const state = entitySchemaToTableState(UserSchema);
38
+ * // state.columns, state.foreignKeys, state.indexes …
39
+ * ```
40
+ */
41
+ export declare function entitySchemaToTableState(schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>): DatabaseTableState;
42
+ /**
43
+ * Compare a code-first schema model against a live database table state and
44
+ * produce a diff describing the changes needed to bring the database in sync.
45
+ *
46
+ * @param schema - The code-first `ObjectSchemaBuilder`.
47
+ * @param dbState - The current database state from {@link introspectDatabase}.
48
+ * @returns A {@link MigrationDiff} describing columns, indexes, and foreign
49
+ * keys to add, drop, or alter.
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * const dbState = await introspectDatabase(knex, 'users');
54
+ * const diff = diffSchema(UserSchema, dbState);
55
+ * if (diff.addColumns.length > 0) {
56
+ * const migration = generateMigration(diff, 'users');
57
+ * console.log(migration.up);
58
+ * }
59
+ * ```
60
+ */
61
+ export declare function diffSchema(schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>, dbState: DatabaseTableState): MigrationDiff;
62
+ /**
63
+ * Generate migration `up` and `down` code strings from a {@link MigrationDiff}.
64
+ *
65
+ * The generated code is valid TypeScript that uses Knex's schema builder API.
66
+ * Write it to a migration file and run via Knex's migration system.
67
+ *
68
+ * @param diff - The schema diff from {@link diffSchema}.
69
+ * @param tableName - The table name to alter.
70
+ * @returns An object with `up` and `down` migration code strings.
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * const diff = diffSchema(UserSchema, dbState);
75
+ * const migration = generateMigration(diff, 'users');
76
+ * fs.writeFileSync('migration.ts', migration.full);
77
+ * ```
78
+ */
79
+ export declare function generateMigration(diff: MigrationDiff, tableName: string): {
80
+ up: string;
81
+ down: string;
82
+ full: string;
83
+ };
84
+ /**
85
+ * Check whether a table exists in the connected PostgreSQL database.
86
+ *
87
+ * @param knex - A configured Knex instance (or transaction).
88
+ * @param tableName - The table name to check.
89
+ * @returns `true` when the table exists.
90
+ *
91
+ * @example
92
+ * ```ts
93
+ * const exists = await tableExistsInDb(knex, 'users');
94
+ * if (!exists) await generateCreateTable(UserSchema)(knex);
95
+ * ```
96
+ */
97
+ export declare function tableExistsInDb(knex: Knex, tableName: string): Promise<boolean>;
98
+ /**
99
+ * Return `true` when a {@link MigrationDiff} has no operations — i.e. the
100
+ * database table is already in sync with the schema.
101
+ */
102
+ export declare function isDiffEmpty(diff: MigrationDiff): boolean;
103
+ /**
104
+ * Execute a {@link MigrationDiff} directly against a live database without
105
+ * writing a migration file. Intended for `db push` (dev-only schema sync).
106
+ *
107
+ * Foreign-key constraint drops are executed as raw `ALTER TABLE … DROP
108
+ * CONSTRAINT` statements before the main `alterTable` call.
109
+ *
110
+ * @param knex - A configured Knex instance or transaction.
111
+ * @param diff - The diff from {@link diffSchema}.
112
+ * @param tableName - The table to alter.
113
+ *
114
+ * @example
115
+ * ```ts
116
+ * const dbState = await introspectDatabase(knex, 'users');
117
+ * const diff = diffSchema(UserSchema, dbState);
118
+ * if (!isDiffEmpty(diff)) await applyDiff(knex, diff, 'users');
119
+ * ```
120
+ */
121
+ export declare function applyDiff(knex: Knex, diff: MigrationDiff, tableName: string): Promise<void>;
122
+ /**
123
+ * Generate a single combined migration (up + down) for a set of entities by
124
+ * diffing the current code-first schemas against a **serialized snapshot**
125
+ * stored in the repository — no live database connection required.
126
+ *
127
+ * For each entity's table the function:
128
+ * - **New tables** (in entities but not in `prevSnapshot`): emits `CREATE TABLE`.
129
+ * - **Existing tables** (in both): diffs entity schema against the snapshot
130
+ * state via {@link diffSchema} and emits `ALTER TABLE` when changes exist.
131
+ * - **Dropped tables** (in `prevSnapshot` but not in entities): emits
132
+ * `DROP TABLE` with a best-effort `CREATE TABLE` in the `down` direction.
133
+ * - Orders tables topologically by FK dependencies so parent tables are
134
+ * created before child tables in `up` (and dropped after in `down`).
135
+ *
136
+ * @param entities - The entities from your {@link EntityMap}.
137
+ * @param prevSnapshot - The last committed {@link SchemaSnapshot} (empty on first run).
138
+ * @returns `{ up, down, full, isEmpty, nextSnapshot }` where `nextSnapshot`
139
+ * should be written to disk after the migration file is created.
140
+ *
141
+ * @example
142
+ * ```ts
143
+ * const prev = loadSnapshot('./migrations/snapshot.json');
144
+ * const result = generateMigrationsForContext(
145
+ * Object.values({ todos: TodoEntity, users: UserEntity }),
146
+ * prev
147
+ * );
148
+ * if (!result.isEmpty) {
149
+ * fs.writeFileSync('migrations/20260423000000_init.ts', result.full);
150
+ * writeSnapshot('./migrations/snapshot.json', result.nextSnapshot);
151
+ * }
152
+ * ```
153
+ */
154
+ export declare function generateMigrationsForContext(entities: Entity<any, any>[], prevSnapshot: SchemaSnapshot): {
155
+ up: string;
156
+ down: string;
157
+ full: string;
158
+ isEmpty: boolean;
159
+ nextSnapshot: SchemaSnapshot;
160
+ };
package/dist/raw.d.ts ADDED
@@ -0,0 +1,35 @@
1
+ import type { InferType, ObjectSchemaBuilder } from '@cleverbrush/schema';
2
+ import type { Knex } from 'knex';
3
+ /**
4
+ * Execute a raw SQL query or Knex query builder and map the result rows
5
+ * through the schema's column→property name mapping.
6
+ *
7
+ * This is the escape hatch for complex queries that can't be expressed with
8
+ * the typed `SchemaQueryBuilder` API. The schema is used only for result
9
+ * mapping — column names in the result are converted back to property names.
10
+ * Extra columns (not in the schema) are passed through unchanged.
11
+ *
12
+ * @param knex - A configured Knex instance.
13
+ * @param schema - The `ObjectSchemaBuilder` for result mapping.
14
+ * @param queryOrSql - A raw SQL string or a `Knex.QueryBuilder`.
15
+ * @param bindings - Optional bindings for parameterised SQL queries.
16
+ * @returns Mapped result rows.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * // Raw SQL with schema result mapping
21
+ * const results = await rawQuery(knex, PostSchema, `
22
+ * SELECT p.*, COUNT(c.id) AS comment_count
23
+ * FROM posts p
24
+ * LEFT JOIN comments c ON c.post_id = p.id
25
+ * GROUP BY p.id
26
+ * ORDER BY comment_count DESC
27
+ * LIMIT ?
28
+ * `, [10]);
29
+ *
30
+ * // Knex query builder as the source
31
+ * const subQuery = knex('posts').select('author_id', knex.raw('COUNT(*) as post_count')).groupBy('author_id');
32
+ * const results = await rawQuery(knex, UserSchema, subQuery);
33
+ * ```
34
+ */
35
+ export declare function rawQuery<TSchema extends ObjectSchemaBuilder<any, any, any, any, any, any, any>>(knex: Knex, schema: TSchema, queryOrSql: string | Knex.QueryBuilder, bindings?: any[]): Promise<(InferType<TSchema> & Record<string, any>)[]>;
@@ -0,0 +1,39 @@
1
+ import type { Entity } from './entity.js';
2
+ import type { SchemaSnapshot } from './types.js';
3
+ /**
4
+ * Build a {@link SchemaSnapshot} from a set of entities without a live DB.
5
+ *
6
+ * Handles polymorphic (CTI) entities by including each variant table.
7
+ * Deduplicates tables so STI variants sharing a base table are only included
8
+ * once.
9
+ *
10
+ * @param entities - The entities from your `EntityMap`.
11
+ * @returns A snapshot reflecting the current code-first schema state.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * const snapshot = entitiesToSnapshot(Object.values(entityMap));
16
+ * writeSnapshot('./migrations/snapshot.json', snapshot);
17
+ * ```
18
+ */
19
+ export declare function entitiesToSnapshot(entities: Entity<any, any>[]): SchemaSnapshot;
20
+ /**
21
+ * Load a {@link SchemaSnapshot} from disk.
22
+ *
23
+ * Returns an empty snapshot (no tables) when the file does not exist — this
24
+ * is the "first run" case, which causes `migrate generate` to emit a single
25
+ * migration containing `CREATE TABLE` for every entity.
26
+ *
27
+ * @param snapshotPath - Absolute or cwd-relative path to `snapshot.json`.
28
+ * @returns The parsed snapshot, or `{ version: 1, tables: {} }` if missing or
29
+ * unreadable.
30
+ */
31
+ export declare function loadSnapshot(snapshotPath: string): SchemaSnapshot;
32
+ /**
33
+ * Write a {@link SchemaSnapshot} to disk atomically (temp-file + rename) with
34
+ * deterministic key ordering so diffs in version control are minimal.
35
+ *
36
+ * @param snapshotPath - Absolute or cwd-relative path to write `snapshot.json`.
37
+ * @param snapshot - The snapshot to serialize.
38
+ */
39
+ export declare function writeSnapshot(snapshotPath: string, snapshot: SchemaSnapshot): void;
package/dist/types.d.ts CHANGED
@@ -89,4 +89,273 @@ export type ValidatedSpec = ({
89
89
  type: 'many';
90
90
  } & ValidatedJoinManySpec);
91
91
  export type InsertType<T extends ObjectSchemaBuilder<any, any, any, any, any, any, any>> = InferType<ReturnType<T['makeAllPropsOptional']>>;
92
+ import type { COMPOSITE_PRIMARY_KEY_BRAND, PRIMARY_KEY_BRAND } from './extension.js';
93
+ /**
94
+ * Detect whether a property schema is branded as a primary key (i.e. its
95
+ * schema was created with `.primaryKey()`).
96
+ *
97
+ * @internal
98
+ */
99
+ type IsPkBranded<TPropSchema> = TPropSchema extends {
100
+ readonly [PRIMARY_KEY_BRAND]?: true;
101
+ } ? true : false;
102
+ /**
103
+ * Extract the primary-key column descriptor for a schema.
104
+ *
105
+ * Returns:
106
+ * - the literal property-key string for a single-column primary key
107
+ * (e.g. `'id'`),
108
+ * - a tuple of property-key strings for a composite primary key
109
+ * (e.g. `['userId', 'roleId']`),
110
+ * - or `never` if no primary key is declared.
111
+ *
112
+ * Composite primary keys are detected via the `COMPOSITE_PRIMARY_KEY_BRAND`
113
+ * placed on the object schema by `.hasPrimaryKey([...] as const)`. Use
114
+ * `as const` on the column tuple to preserve ordering at the type level.
115
+ *
116
+ * @public
117
+ */
118
+ export type PrimaryKeyOf<S extends ObjectSchemaBuilder<any, any, any, any, any, any, any>> = S extends {
119
+ readonly [COMPOSITE_PRIMARY_KEY_BRAND]?: infer TCols;
120
+ } ? TCols extends readonly string[] ? TCols : never : {
121
+ [K in keyof SchemaPropsForPk<S> & string]: IsPkBranded<SchemaPropsForPk<S>[K]> extends true ? K : never;
122
+ }[keyof SchemaPropsForPk<S> & string];
123
+ /**
124
+ * Extract the schema's property record for primary-key inference. Mirrors
125
+ * `SchemaProps` from `entity.ts` but lives here to avoid a circular import.
126
+ *
127
+ * @internal
128
+ */
129
+ type SchemaPropsForPk<T> = T extends ObjectSchemaBuilder<infer P, any, any, any, any, any, any> ? P : never;
130
+ /**
131
+ * The runtime value type of a schema's primary key.
132
+ *
133
+ * - For a single-column PK, the inferred type of that property
134
+ * (e.g. `number`).
135
+ * - For a composite PK, a tuple of inferred property types in declared
136
+ * order (e.g. `[number, number]`).
137
+ * - `never` if no primary key is declared.
138
+ *
139
+ * @public
140
+ */
141
+ export type PrimaryKeyValueOf<S extends ObjectSchemaBuilder<any, any, any, any, any, any, any>> = PrimaryKeyOf<S> extends readonly (infer _Item extends string)[] ? PrimaryKeyOf<S> extends readonly string[] ? PkTupleValue<S, PrimaryKeyOf<S>> : never : PrimaryKeyOf<S> extends string ? InferType<S>[PrimaryKeyOf<S> & keyof InferType<S>] : never;
142
+ /**
143
+ * Map a tuple of PK property-key names to their inferred value types.
144
+ *
145
+ * @internal
146
+ */
147
+ type PkTupleValue<S extends ObjectSchemaBuilder<any, any, any, any, any, any, any>, TKeys extends readonly string[]> = {
148
+ [I in keyof TKeys]: TKeys[I] extends keyof InferType<S> ? InferType<S>[TKeys[I]] : unknown;
149
+ };
150
+ /**
151
+ * Extract the property schema captured inside a `PropertyDescriptor`.
152
+ *
153
+ * @internal
154
+ */
155
+ type DescriptorPropertySchema<T> = T extends PropertyDescriptor<any, infer S, any, any> ? S : never;
156
+ /**
157
+ * Result row type produced by a {@link SelectProjection} selector.
158
+ *
159
+ * Each entry's value is the {@link InferType} of the property schema the
160
+ * descriptor points at, so `.select(t => ({ id: t.id, n: t.title }))`
161
+ * yields `{ id: number; n: string }`.
162
+ *
163
+ * @public
164
+ */
165
+ export type SelectProjection<R extends Record<string, unknown>> = {
166
+ [K in keyof R]: InferType<DescriptorPropertySchema<R[K]>>;
167
+ };
168
+ /**
169
+ * Callback shape accepted by the projection overload of `select`. The
170
+ * callback receives the schema's property-descriptor tree and returns an
171
+ * `{ alias: descriptor }` record.
172
+ *
173
+ * @public
174
+ */
175
+ export type SelectSelector<T extends ObjectSchemaBuilder<any, any, any, any, any, any, any>> = (tree: PropertyDescriptorTree<SchemaBase<T>, SchemaBase<T>>) => Record<string, PropertyDescriptor<any, any, any>>;
176
+ /** Result of offset-based pagination via {@link SchemaQueryBuilder.paginate}. */
177
+ export interface PaginationResult<T> {
178
+ /** The rows for the current page. */
179
+ data: T[];
180
+ /** Total number of matching rows across all pages. */
181
+ total: number;
182
+ /** Current page number (1-based). */
183
+ page: number;
184
+ /** Number of rows per page. */
185
+ pageSize: number;
186
+ /** Total number of pages. */
187
+ totalPages: number;
188
+ /** Whether a next page exists. */
189
+ hasNextPage: boolean;
190
+ /** Whether a previous page exists. */
191
+ hasPreviousPage: boolean;
192
+ }
193
+ /** Result of cursor-based pagination via {@link SchemaQueryBuilder.paginateAfter}. */
194
+ export interface CursorPaginationResult<T> {
195
+ /** The rows for the current page. */
196
+ data: T[];
197
+ /** Cursor value for the next page, or `null` if no more rows. */
198
+ nextCursor: string | null;
199
+ /** Whether more rows exist after this page. */
200
+ hasMore: boolean;
201
+ }
202
+ /** Storage strategy for a polymorphic variant. */
203
+ export type VariantStorageType = 'cti' | 'sti';
204
+ /** @internal Resolved form of a variant relation stored on {@link ResolvedVariantSpec}. */
205
+ export interface ResolvedVariantRelationSpec {
206
+ name: string;
207
+ type: 'hasMany' | 'hasOne' | 'belongsTo' | 'belongsToMany';
208
+ schema: any;
209
+ /** Resolved FK *column* name on the variant or foreign table. */
210
+ foreignKey?: string;
211
+ through?: {
212
+ table: string;
213
+ localKey: string;
214
+ foreignKey: string;
215
+ };
216
+ }
217
+ /** @internal Resolved, normalised variant spec stored in schema extensions. */
218
+ export interface ResolvedVariantSpec {
219
+ storage: VariantStorageType;
220
+ schema: ObjectSchemaBuilder<any, any, any, any, any, any, any>;
221
+ /** CTI: FK column name on the variant table. */
222
+ foreignKey?: string;
223
+ /** CTI: variant table name (from `schema.hasTableName()`). */
224
+ tableName?: string;
225
+ allowOrphan: boolean;
226
+ enforceCheck: boolean;
227
+ /** Variant-scoped relations (resolved), populated by `.withVariants()`. */
228
+ relations: ResolvedVariantRelationSpec[];
229
+ }
230
+ /** @internal Full variant config stored in the schema extension `'variants'`. */
231
+ export interface ResolvedVariantConfig {
232
+ /** Property key on the base schema that is the discriminator. */
233
+ discriminatorKey: string;
234
+ /** SQL column name corresponding to `discriminatorKey`. Filled by query builder. */
235
+ discriminatorColumn: string;
236
+ /** Map from discriminator value → resolved variant spec. */
237
+ variants: Record<string, ResolvedVariantSpec>;
238
+ }
239
+ /** @internal Pending filter registered via `.whereVariant()`. */
240
+ export interface VariantWhereFilter {
241
+ /** The discriminator value this filter applies to (e.g. `'image'`). */
242
+ key: string;
243
+ /** SQL column expression on the variant alias (e.g. `__v_image.width`). */
244
+ qualifiedColumn: string;
245
+ /** SQL comparison operator (validated). */
246
+ op: string;
247
+ value: any;
248
+ }
249
+ /** @internal Relation metadata stored via `.hasMany()`, `.belongsTo()`, etc. */
250
+ export interface RelationSpec {
251
+ type: 'hasMany' | 'hasOne' | 'belongsTo' | 'belongsToMany';
252
+ name: string;
253
+ schema: any;
254
+ foreignKey?: any;
255
+ through?: {
256
+ table: string;
257
+ localKey: string;
258
+ foreignKey: string;
259
+ };
260
+ }
261
+ /** Column information read from the database. */
262
+ export interface DatabaseColumnInfo {
263
+ name: string;
264
+ type: string;
265
+ nullable: boolean;
266
+ defaultValue: string | null;
267
+ maxLength: number | null;
268
+ numericPrecision: number | null;
269
+ }
270
+ /** Index information read from the database. */
271
+ export interface DatabaseIndexInfo {
272
+ name: string;
273
+ columns: string[];
274
+ unique: boolean;
275
+ definition: string;
276
+ }
277
+ /** Foreign key information read from the database. */
278
+ export interface DatabaseForeignKeyInfo {
279
+ constraintName: string;
280
+ columnName: string;
281
+ foreignTable: string;
282
+ foreignColumn: string;
283
+ deleteRule: string;
284
+ updateRule: string;
285
+ }
286
+ /** Check constraint information read from the database. */
287
+ export interface DatabaseCheckInfo {
288
+ name: string;
289
+ definition: string;
290
+ }
291
+ /** Full database table state from introspection. */
292
+ export interface DatabaseTableState {
293
+ columns: Record<string, DatabaseColumnInfo>;
294
+ indexes: DatabaseIndexInfo[];
295
+ foreignKeys: DatabaseForeignKeyInfo[];
296
+ checks: DatabaseCheckInfo[];
297
+ }
298
+ /**
299
+ * Serialized snapshot of all entity schemas at a given point in time.
300
+ *
301
+ * Stored in `<migrations.directory>/snapshot.json` and committed to version
302
+ * control. `migrate generate` diffs the current code against this snapshot
303
+ * (instead of a live database) to produce migration files, so no DB
304
+ * connection is required.
305
+ *
306
+ * Each entry in `tables` mirrors the shape that `introspectDatabase` would
307
+ * return — allowing `diffSchema` to be reused unchanged.
308
+ *
309
+ * @public
310
+ */
311
+ export interface SchemaSnapshot {
312
+ version: 1;
313
+ /** Map of table name → database state derived from entity schemas. */
314
+ tables: Record<string, DatabaseTableState>;
315
+ }
316
+ /** A column to add in a migration. */
317
+ export interface AddColumnDiff {
318
+ name: string;
319
+ type: string;
320
+ nullable: boolean;
321
+ defaultValue?: any;
322
+ references?: {
323
+ table: string;
324
+ column: string;
325
+ };
326
+ onDelete?: string;
327
+ onUpdate?: string;
328
+ }
329
+ /** Changes to apply to an existing column. */
330
+ export interface AlterColumnDiff {
331
+ name: string;
332
+ changes: Record<string, {
333
+ from: any;
334
+ to: any;
335
+ }>;
336
+ }
337
+ /** An index to add in a migration. */
338
+ export interface AddIndexDiff {
339
+ columns: string[];
340
+ name?: string;
341
+ unique?: boolean;
342
+ }
343
+ /** A foreign key to add in a migration. */
344
+ export interface AddForeignKeyDiff {
345
+ column: string;
346
+ foreignTable: string;
347
+ foreignColumn: string;
348
+ onDelete?: string;
349
+ onUpdate?: string;
350
+ }
351
+ /** Schema diff result between the code-first model and the live database. */
352
+ export interface MigrationDiff {
353
+ addColumns: AddColumnDiff[];
354
+ dropColumns: string[];
355
+ alterColumns: AlterColumnDiff[];
356
+ addIndexes: AddIndexDiff[];
357
+ dropIndexes: string[];
358
+ addForeignKeys: AddForeignKeyDiff[];
359
+ dropForeignKeys: string[];
360
+ }
92
361
  export {};
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "email": "andrew_zol@cleverbrush.com"
6
6
  },
7
7
  "dependencies": {
8
- "@cleverbrush/schema": "^3.1.0"
8
+ "@cleverbrush/schema": "^4.0.0"
9
9
  },
10
10
  "peerDependencies": {
11
11
  "knex": ">=3.1.0"
@@ -32,6 +32,10 @@
32
32
  ".": {
33
33
  "types": "./dist/index.d.ts",
34
34
  "import": "./dist/index.js"
35
+ },
36
+ "./extension": {
37
+ "types": "./dist/extension.d.ts",
38
+ "import": "./dist/extension.js"
35
39
  }
36
40
  },
37
41
  "sideEffects": false,
@@ -48,5 +52,5 @@
48
52
  },
49
53
  "type": "module",
50
54
  "types": "./dist/index.d.ts",
51
- "version": "3.1.0"
55
+ "version": "4.0.0"
52
56
  }