velocious 1.0.352 → 1.0.354

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.
@@ -1,6 +1,28 @@
1
1
  export default class VelociousDatabaseConnectionDriversSqliteSqlAlterTable extends AlterTableBase {
2
2
  logger: Logger;
3
+ /**
4
+ * Merges the current schema with the alter request to produce the desired final schema
5
+ * and the column copy plan.
6
+ * @param {TableData} currentTableData - Current schema as introspected from the database.
7
+ * @param {TableData} alterTableData - Alter request: new columns (`isNewColumn`), renames (`newName`), drops (`dropColumn`), modifies, and new foreign keys.
8
+ * @returns {{targetTableData: TableData, columnPairs: Array<[string, string]>}} - The merged target schema and the [oldName, newName] pairs for INSERT...SELECT.
9
+ */
10
+ _buildTargetSchema(currentTableData: TableData, alterTableData: TableData): {
11
+ targetTableData: TableData;
12
+ columnPairs: Array<[string, string]>;
13
+ };
14
+ /**
15
+ * Returns the foreign key with its column name updated when the column was renamed in the
16
+ * alter request. SQLite re-creates the constraint inside the rebuilt CREATE TABLE, so a
17
+ * stale column name there would reference a column that no longer exists.
18
+ * @param {TableForeignKey} foreignKey - Foreign key to evaluate.
19
+ * @param {Map<string, string>} columnRenames - Map of old → new column names from the alter request.
20
+ * @returns {TableForeignKey} - The original foreign key, or a fresh instance with the renamed column.
21
+ */
22
+ _renameForeignKeyColumn(foreignKey: TableForeignKey, columnRenames: Map<string, string>): TableForeignKey;
3
23
  }
4
24
  import AlterTableBase from "../../../query/alter-table-base.js";
5
25
  import Logger from "../../../../logger.js";
26
+ import TableData from "../../../table-data/index.js";
27
+ import TableForeignKey from "../../../table-data/table-foreign-key.js";
6
28
  //# sourceMappingURL=alter-table.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"alter-table.d.ts","sourceRoot":"","sources":["../../../../../../src/database/drivers/sqlite/sql/alter-table.js"],"names":[],"mappings":"AAQA;IAYI,eAA8B;CA4IjC;2BA9J0B,oCAAoC;mBAE5C,uBAAuB"}
1
+ {"version":3,"file":"alter-table.d.ts","sourceRoot":"","sources":["../../../../../../src/database/drivers/sqlite/sql/alter-table.js"],"names":[],"mappings":"AAUA;IAYI,eAA8B;IA8ChC;;;;;;OAMG;IACH,qCAJW,SAAS,kBACT,SAAS,GACP;QAAC,eAAe,EAAE,SAAS,CAAC;QAAC,WAAW,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;KAAC,CAmF9E;IAED;;;;;;;OAOG;IACH,oCAJW,eAAe,iBACf,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACjB,eAAe,CAe3B;CACF;2BAlL0B,oCAAoC;mBAC5C,uBAAuB;sBAEpB,8BAA8B;4BACxB,0CAA0C"}
@@ -1,9 +1,11 @@
1
1
  // @ts-check
2
2
  import AlterTableBase from "../../../query/alter-table-base.js";
3
- import CreateIndexBase from "../../../query/create-index-base.js";
4
3
  import Logger from "../../../../logger.js";
5
4
  import restArgsError from "../../../../utils/rest-args-error.js";
6
5
  import TableData from "../../../table-data/index.js";
6
+ import TableForeignKey from "../../../table-data/table-foreign-key.js";
7
+ import TableIndex from "../../../table-data/table-index.js";
8
+ import TableRebuilder from "../table-rebuilder.js";
7
9
  export default class VelociousDatabaseConnectionDriversSqliteSqlAlterTable extends AlterTableBase {
8
10
  /**
9
11
  * @param {object} args - Options object.
@@ -22,109 +24,138 @@ export default class VelociousDatabaseConnectionDriversSqliteSqlAlterTable exten
22
24
  * @returns {Promise<string[]>} - Resolves with SQL statements.
23
25
  */
24
26
  async toSQLs() {
25
- const { tableData } = this;
26
- const table = await this.getDriver().getTableByName(tableData.getName());
27
+ const driver = this.getDriver();
28
+ const { tableData: alterTableData } = this;
29
+ const tableName = alterTableData.getName();
30
+ const table = await driver.getTableByName(tableName);
27
31
  if (!table)
28
- throw new Error(`Table ${tableData.getName()} does not exist`);
32
+ throw new Error(`Table ${tableName} does not exist`);
29
33
  const currentTableData = await table.getTableData();
30
- const options = this.getOptions();
31
- const tableName = tableData.getName();
32
- const tempTableName = `${tableData.getName()}AlterTableTemp`;
33
- const newColumnNames = currentTableData.getColumns()
34
- .filter((column) => !column.isNewColumn())
35
- .map((column) => {
36
- const newTableColumn = tableData.getColumns().find((tableColumn) => tableColumn.getName() == column.getName());
37
- return newTableColumn?.getNewName() || newTableColumn?.getName() || column.getNewName() || column.getName();
34
+ const { targetTableData, columnPairs } = this._buildTargetSchema(currentTableData, alterTableData);
35
+ const rebuilder = new TableRebuilder({
36
+ columnPairs,
37
+ driver,
38
+ originalTableName: tableName,
39
+ targetTableData
38
40
  });
39
- const oldColumnNames = currentTableData.getColumns().filter((column) => !column.isNewColumn()).map((column) => column.getName());
40
- const newColumnsSQL = newColumnNames.map((name) => options.quoteColumnName(name)).join(", ");
41
- const oldColumnsSQL = oldColumnNames.map((name) => options.quoteColumnName(name)).join(", ");
42
- tableData.setName(tempTableName);
43
- const newTableData = new TableData(tempTableName);
44
- for (const tableDataColumn of currentTableData.getColumns()) {
45
- let newTableDataColumn = tableData.getColumns().find((newTableDataColumn) => newTableDataColumn.getName() == tableDataColumn.getName());
46
- if (newTableDataColumn && newTableDataColumn.isNewColumn()) {
47
- newTableDataColumn = undefined;
41
+ const rebuildSQLs = await rebuilder.toSQLs();
42
+ const sqls = [];
43
+ // PRAGMA foreign_keys can only be toggled outside an active transaction; when the
44
+ // caller is already inside one these become no-ops (matching prior behavior). Outside
45
+ // a transaction they protect the rebuild from cross-table FK enforcement during the
46
+ // DROP/RENAME swap. Capture the prior state so we restore it instead of unconditionally
47
+ // forcing ON — callers that deliberately disabled FK enforcement (e.g. bulk data fixes)
48
+ // shouldn't be silently flipped back on by a migration.
49
+ const priorState = await driver.query("PRAGMA foreign_keys");
50
+ const wasEnabled = priorState[0]?.foreign_keys == 1;
51
+ sqls.push("PRAGMA foreign_keys = OFF");
52
+ for (const sql of rebuildSQLs)
53
+ sqls.push(sql);
54
+ sqls.push(`PRAGMA foreign_keys = ${wasEnabled ? "ON" : "OFF"}`);
55
+ return sqls;
56
+ }
57
+ /**
58
+ * Merges the current schema with the alter request to produce the desired final schema
59
+ * and the column copy plan.
60
+ * @param {TableData} currentTableData - Current schema as introspected from the database.
61
+ * @param {TableData} alterTableData - Alter request: new columns (`isNewColumn`), renames (`newName`), drops (`dropColumn`), modifies, and new foreign keys.
62
+ * @returns {{targetTableData: TableData, columnPairs: Array<[string, string]>}} - The merged target schema and the [oldName, newName] pairs for INSERT...SELECT.
63
+ */
64
+ _buildTargetSchema(currentTableData, alterTableData) {
65
+ const targetTableData = new TableData(currentTableData.getName());
66
+ /** @type {Array<[string, string]>} */
67
+ const columnPairs = [];
68
+ const alterColumns = alterTableData.getColumns();
69
+ const existingNames = new Set(currentTableData.getColumns().map((column) => column.getName()));
70
+ /** @type {Map<string, string>} */
71
+ const columnRenames = new Map();
72
+ for (const alterColumn of alterColumns) {
73
+ if (alterColumn.isNewColumn())
74
+ continue;
75
+ const newName = alterColumn.getNewName();
76
+ if (newName)
77
+ columnRenames.set(alterColumn.getName(), newName);
78
+ }
79
+ for (const currentColumn of currentTableData.getColumns()) {
80
+ const alterColumn = alterColumns.find((column) => column.getName() == currentColumn.getName() && !column.isNewColumn());
81
+ if (alterColumn?.getDropColumn())
82
+ continue;
83
+ let targetColumn;
84
+ if (alterColumn) {
85
+ // The alter request supplies a partial column spec (e.g. just a rename or a type change);
86
+ // inherit unset properties from the current column so we don't lose existing definitions.
87
+ alterColumn.setAutoIncrement(alterColumn.getAutoIncrement() || currentColumn.getAutoIncrement());
88
+ if (alterColumn.getDefault() === undefined)
89
+ alterColumn.setDefault(currentColumn.getDefault());
90
+ if (!alterColumn.getIndex())
91
+ alterColumn.setIndex(currentColumn.getIndex());
92
+ if (!alterColumn.getForeignKey())
93
+ alterColumn.setForeignKey(currentColumn.getForeignKey());
94
+ if (alterColumn.getMaxLength() === undefined)
95
+ alterColumn.setMaxLength(currentColumn.getMaxLength());
96
+ alterColumn.setPrimaryKey(alterColumn.getPrimaryKey() || currentColumn.getPrimaryKey());
97
+ if (!alterColumn.getType())
98
+ alterColumn.setType(currentColumn.getType());
99
+ targetColumn = alterColumn;
48
100
  }
49
- if (newTableDataColumn) {
50
- newTableDataColumn.setAutoIncrement(tableDataColumn.getAutoIncrement());
51
- newTableDataColumn.setDefault(tableDataColumn.getDefault());
52
- newTableDataColumn.setIndex(tableDataColumn.getIndex());
53
- newTableDataColumn.setForeignKey(tableDataColumn.getForeignKey());
54
- newTableDataColumn.setMaxLength(tableDataColumn.getMaxLength());
55
- newTableDataColumn.setPrimaryKey(tableDataColumn.getPrimaryKey());
56
- newTableDataColumn.setType(tableDataColumn.getType());
101
+ else {
102
+ targetColumn = currentColumn;
57
103
  }
58
- newTableData.addColumn(newTableDataColumn || tableDataColumn);
104
+ targetTableData.addColumn(targetColumn);
105
+ columnPairs.push([currentColumn.getName(), targetColumn.getNewName() || targetColumn.getName()]);
59
106
  }
60
- // SQLite rebuilds use existing columns plus new ones; avoid duplicating a column that already exists.
61
- const existingColumnNames = new Set(currentTableData.getColumns().map((column) => column.getName()));
62
- for (const tableDataColumn of tableData.getColumns()) {
63
- if (!tableDataColumn.isNewColumn())
107
+ for (const alterColumn of alterColumns) {
108
+ if (!alterColumn.isNewColumn())
64
109
  continue;
65
- if (existingColumnNames.has(tableDataColumn.getName()))
110
+ if (existingNames.has(alterColumn.getName()))
66
111
  continue;
67
- newTableData.addColumn(tableDataColumn);
112
+ targetTableData.addColumn(alterColumn);
68
113
  }
69
- const foundForeignKeys = [];
70
- for (const tableDataForeignKey of currentTableData.getForeignKeys()) {
71
- const newTableDataForeignKey = newTableData.getForeignKeys().find((newTableDataForeignKey) => newTableDataForeignKey.getName() == tableDataForeignKey.getName());
72
- if (newTableDataForeignKey)
73
- foundForeignKeys.push(newTableDataForeignKey.getName());
74
- const actualTableDataForeignKey = newTableDataForeignKey || tableDataForeignKey;
75
- // Register foreign key on the table
76
- newTableData.addForeignKey(actualTableDataForeignKey);
77
- // Register foreign key on the column
78
- const tableDataColumn = newTableData.getColumns().find((newTableDataColumn) => newTableDataColumn.getName() == actualTableDataForeignKey.getColumnName());
79
- if (!tableDataColumn)
80
- throw new Error(`Couldn't find column for foreign key: ${actualTableDataForeignKey.getName()}`);
81
- this.logger.debugLowLevel(() => `Setting foreign key on column ${tableDataColumn.getName()}`);
82
- tableDataColumn.setForeignKey(actualTableDataForeignKey);
114
+ const seenForeignKeyNames = new Set();
115
+ for (const currentForeignKey of currentTableData.getForeignKeys()) {
116
+ const alterForeignKey = alterTableData.getForeignKeys().find((foreignKey) => foreignKey.getName() == currentForeignKey.getName());
117
+ const finalForeignKey = this._renameForeignKeyColumn(alterForeignKey || currentForeignKey, columnRenames);
118
+ seenForeignKeyNames.add(finalForeignKey.getName());
119
+ targetTableData.addForeignKey(finalForeignKey);
83
120
  }
84
- for (const foreignKey of tableData.getForeignKeys()) {
85
- if (foundForeignKeys.includes(foreignKey.getName()))
121
+ for (const alterForeignKey of alterTableData.getForeignKeys()) {
122
+ if (seenForeignKeyNames.has(alterForeignKey.getName()))
86
123
  continue;
87
- // Register foreign key on the table
88
- newTableData.addForeignKey(foreignKey);
89
- // Register foreign key on the column
90
- const tableDataColumn = newTableData.getColumns().find((newTableDataColumn) => newTableDataColumn.getName() == foreignKey.getColumnName());
91
- if (!tableDataColumn)
92
- throw new Error(`Couldn't find column for foreign key: ${foreignKey.getName()}`);
93
- this.logger.debugLowLevel(() => `Setting foreign key on column ${tableDataColumn.getName()}`);
94
- tableDataColumn.setForeignKey(foreignKey);
124
+ targetTableData.addForeignKey(this._renameForeignKeyColumn(alterForeignKey, columnRenames));
95
125
  }
96
- const createNewTableSQL = await this.getDriver().createTableSql(newTableData);
97
- const insertSQL = `INSERT INTO ${options.quoteTableName(tempTableName)} (${newColumnsSQL}) SELECT ${oldColumnsSQL} FROM ${options.quoteTableName(tableName)}`;
98
- const dropTableSQLs = `DROP TABLE ${options.quoteTableName(tableName)}`;
99
- const renameTableSQL = `ALTER TABLE ${options.quoteTableName(tempTableName)} RENAME TO ${options.quoteTableName(tableName)}`;
100
- const sqls = [];
101
- for (const sql of createNewTableSQL) {
102
- sqls.push(sql);
103
- }
104
- sqls.push(insertSQL);
105
- sqls.push(dropTableSQLs);
106
- sqls.push(renameTableSQL);
107
- for (const tableDataIndex of currentTableData.getIndexes()) {
108
- const newTableDataIndex = newTableData.getIndexes().find((newTableDataIndex) => newTableDataIndex.getName() == tableDataIndex.getName());
109
- const actualTableIndex = newTableDataIndex || tableDataIndex;
110
- newTableData.addIndex(actualTableIndex);
111
- const columnNames = actualTableIndex.getColumns().map((columnName) => {
112
- const newTableColumn = tableData.getColumns().find((tableColumn) => tableColumn.getName() == columnName);
113
- return newTableColumn?.getNewName() || newTableColumn?.getName() || columnName;
126
+ for (const currentIndex of currentTableData.getIndexes()) {
127
+ const renamedColumns = currentIndex.getColumns().map((columnName) => {
128
+ if (typeof columnName != "string")
129
+ return columnName;
130
+ return columnRenames.get(columnName) || columnName;
114
131
  });
115
- const createIndexArgs = {
116
- columns: columnNames,
117
- driver: this.getDriver(),
118
- name: actualTableIndex.getName(),
119
- tableName,
120
- unique: actualTableIndex.getUnique()
121
- };
122
- const createIndexSQLs = await new CreateIndexBase(createIndexArgs).toSQLs();
123
- for (const createIndexSQL of createIndexSQLs) {
124
- sqls.push(createIndexSQL);
125
- }
132
+ targetTableData.addIndex(new TableIndex(renamedColumns, {
133
+ name: currentIndex.getName(),
134
+ unique: currentIndex.getUnique()
135
+ }));
126
136
  }
127
- return sqls;
137
+ return { targetTableData, columnPairs };
138
+ }
139
+ /**
140
+ * Returns the foreign key with its column name updated when the column was renamed in the
141
+ * alter request. SQLite re-creates the constraint inside the rebuilt CREATE TABLE, so a
142
+ * stale column name there would reference a column that no longer exists.
143
+ * @param {TableForeignKey} foreignKey - Foreign key to evaluate.
144
+ * @param {Map<string, string>} columnRenames - Map of old → new column names from the alter request.
145
+ * @returns {TableForeignKey} - The original foreign key, or a fresh instance with the renamed column.
146
+ */
147
+ _renameForeignKeyColumn(foreignKey, columnRenames) {
148
+ const renamed = columnRenames.get(foreignKey.getColumnName());
149
+ if (!renamed)
150
+ return foreignKey;
151
+ return new TableForeignKey({
152
+ columnName: renamed,
153
+ isNewForeignKey: foreignKey.getIsNewForeignKey(),
154
+ name: foreignKey.getName(),
155
+ referencedColumnName: foreignKey.getReferencedColumnName(),
156
+ referencedTableName: foreignKey.getReferencedTableName(),
157
+ tableName: foreignKey.getTableName()
158
+ });
128
159
  }
129
160
  }
130
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWx0ZXItdGFibGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvZGF0YWJhc2UvZHJpdmVycy9zcWxpdGUvc3FsL2FsdGVyLXRhYmxlLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLGNBQWMsTUFBTSxvQ0FBb0MsQ0FBQTtBQUMvRCxPQUFPLGVBQWUsTUFBTSxxQ0FBcUMsQ0FBQTtBQUNqRSxPQUFPLE1BQU0sTUFBTSx1QkFBdUIsQ0FBQTtBQUMxQyxPQUFPLGFBQWEsTUFBTSxzQ0FBc0MsQ0FBQTtBQUNoRSxPQUFPLFNBQVMsTUFBTSw4QkFBOEIsQ0FBQTtBQUVwRCxNQUFNLENBQUMsT0FBTyxPQUFPLHFEQUFzRCxTQUFRLGNBQWM7SUFDL0Y7Ozs7T0FJRztJQUNILFlBQVksRUFBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLEdBQUcsUUFBUSxFQUFDO1FBQzFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUV2QixJQUFJLENBQUMsQ0FBQyxTQUFTLFlBQVksU0FBUyxDQUFDO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyw4QkFBOEIsQ0FBQyxDQUFBO1FBRXRGLEtBQUssQ0FBQyxFQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUMsQ0FBQyxDQUFBO1FBQzFCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDOUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUE7SUFDNUIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLE1BQU07UUFDVixNQUFNLEVBQUMsU0FBUyxFQUFDLEdBQUcsSUFBSSxDQUFBO1FBQ3hCLE1BQU0sS0FBSyxHQUFHLE1BQU0sSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQTtRQUV4RSxJQUFJLENBQUMsS0FBSztZQUFFLE1BQU0sSUFB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YmxlQmFzZSBmcm9tIFwiLi4vLi4vLi4vcXVlcnkvYWx0ZXItdGFibGUtYmFzZS5qc1wiXG5pbXBvcnQgQ3JlYXRlSW5kZXhCYXNlIGZyb20gXCIuLi8uLi8uLi9xdWVyeS9jcmVhdGUtaW5kZXgtYmFzZS5qc1wiXG5pbXBvcnQgTG9nZ2VyIGZyb20gXCIuLi8uLi8uLi8uLi9sb2dnZXIuanNcIlxuaW1wb3J0IHJlc3RBcmdzRXJyb3IgZnJvbSBcIi4uLy4uLy4uLy4uL3V0aWxzL3Jlc3QtYXJncy1lcnJvci5qc1wiXG5pbXBvcnQgVGFibGVEYXRhIGZyb20gXCIuLi8uLi8uLi90YWJsZS1kYXRhL2luZGV4LmpzXCJcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVmVsb2Npb3VzRGF0YWJhc2VDb25uZWN0aW9uRHJpdmVyc1NxbGl0ZVNxbEFsdGVyVGFibGUgZXh0ZW5kcyBBbHRlclRhYmxlQmFzZSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2Jhc2UuanNcIikuZGVmYXVsdH0gYXJncy5kcml2ZXIgLSBEYXRhYmFzZSBkcml2ZXIgaW5zdGFuY2UuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vLi4vdGFibGUtZGF0YS9pbmRleC5qc1wiKS5kZWZhdWx0fSBhcmdzLnRhYmxlRGF0YSAtIFRhYmxlIGRhdGEuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7ZHJpdmVyLCB0YWJsZURhdGEsIC4uLnJlc3RBcmdzfSkge1xuICAgIHJlc3RBcmdzRXJyb3IocmVzdEFyZ3MpXG5cbiAgICBpZiAoISh0YWJsZURhdGEgaW5zdGFuY2VvZiBUYWJsZURhdGEpKSB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIHRhYmxlIGRhdGEgd2FzIGdpdmVuXCIpXG5cbiAgICBzdXBlcih7ZHJpdmVyLCB0YWJsZURhdGF9KVxuICAgIHRoaXMubG9nZ2VyID0gbmV3IExvZ2dlcih0aGlzKVxuICAgIHRoaXMudGFibGVEYXRhID0gdGFibGVEYXRhXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nW10+fSAtIFJlc29sdmVzIHdpdGggU1FMIHN0YXRlbWVudHMuXG4gICAqL1xuICBhc3luYyB0b1NRTHMoKSB7XG4gICAgY29uc3Qge3RhYmxlRGF0YX0gPSB0aGlzXG4gICAgY29uc3QgdGFibGUgPSBhd2FpdCB0aGlzLmdldERyaXZlcigpLmdldFRhYmxlQnlOYW1lKHRhYmxlRGF0YS5nZXROYW1lKCkpXG5cbiAgICBpZiAoIXRhYmxlKSB0aHJvdyBuZXcgRXJyb3IoYFRhYmxlICR7dGFibGVEYXRhLmdldE5hbWUoKX0gZG9lcyBub3QgZXhpc3RgKVxuXG4gICAgY29uc3QgY3VycmVudFRhYmxlRGF0YSA9IGF3YWl0IHRhYmxlLmdldFRhYmxlRGF0YSgpXG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMuZ2V0T3B0aW9ucygpXG4gICAgY29uc3QgdGFibGVOYW1lID0gdGFibGVEYXRhLmdldE5hbWUoKVxuICAgIGNvbnN0IHRlbXBUYWJsZU5hbWUgPSBgJHt0YWJsZURhdGEuZ2V0TmFtZSgpfUFsdGVyVGFibGVUZW1wYFxuICAgIGNvbnN0IG5ld0NvbHVtbk5hbWVzID0gY3VycmVudFRhYmxlRGF0YS5nZXRDb2x1bW5zKClcbiAgICAgIC5maWx0ZXIoKGNvbHVtbikgPT4gIWNvbHVtbi5pc05ld0NvbHVtbigpKVxuICAgICAgLm1hcCgoY29sdW1uKSA9PiB7XG4gICAgICAgIGNvbnN0IG5ld1RhYmxlQ29sdW1uID0gdGFibGVEYXRhLmdldENvbHVtbnMoKS5maW5kKCh0YWJsZUNvbHVtbikgPT4gdGFibGVDb2x1bW4uZ2V0TmFtZSgpID09IGNvbHVtbi5nZXROYW1lKCkpXG5cbiAgICAgICAgcmV0dXJuIG5ld1RhYmxlQ29sdW1uPy5nZXROZXdOYW1lKCkgfHwgbmV3VGFibGVDb2x1bW4/LmdldE5hbWUoKSB8fCBjb2x1bW4uZ2V0TmV3TmFtZSgpIHx8IGNvbHVtbi5nZXROYW1lKClcbiAgICAgIH0pXG4gICAgY29uc3Qgb2xkQ29sdW1uTmFtZXMgPSBjdXJyZW50VGFibGVEYXRhLmdldENvbHVtbnMoKS5maWx0ZXIoKGNvbHVtbikgPT4gIWNvbHVtbi5pc05ld0NvbHVtbigpKS5tYXAoKGNvbHVtbikgPT4gY29sdW1uLmdldE5hbWUoKSlcbiAgICBjb25zdCBuZXdDb2x1bW5zU1FMID0gbmV3Q29sdW1uTmFtZXMubWFwKChuYW1lKSA9PiBvcHRpb25zLnF1b3RlQ29sdW1uTmFtZShuYW1lKSkuam9pbihcIiwgXCIpXG4gICAgY29uc3Qgb2xkQ29sdW1uc1NRTCA9IG9sZENvbHVtbk5hbWVzLm1hcCgobmFtZSkgPT4gb3B0aW9ucy5xdW90ZUNvbHVtbk5hbWUobmFtZSkpLmpvaW4oXCIsIFwiKVxuXG4gICAgdGFibGVEYXRhLnNldE5hbWUodGVtcFRhYmxlTmFtZSlcblxuICAgIGNvbnN0IG5ld1RhYmxlRGF0YSA9IG5ldyBUYWJsZURhdGEodGVtcFRhYmxlTmFtZSlcblxuICAgIGZvciAoY29uc3QgdGFibGVEYXRhQ29sdW1uIG9mIGN1cnJlbnRUYWJsZURhdGEuZ2V0Q29sdW1ucygpKSB7XG4gICAgICBsZXQgbmV3VGFibGVEYXRhQ29sdW1uID0gdGFibGVEYXRhLmdldENvbHVtbnMoKS5maW5kKChuZXdUYWJsZURhdGFDb2x1bW4pID0+IG5ld1RhYmxlRGF0YUNvbHVtbi5nZXROYW1lKCkgPT0gdGFibGVEYXRhQ29sdW1uLmdldE5hbWUoKSlcblxuICAgICAgaWYgKG5ld1RhYmxlRGF0YUNvbHVtbiAmJiBuZXdUYWJsZURhdGFDb2x1bW4uaXNOZXdDb2x1bW4oKSkge1xuICAgICAgICBuZXdUYWJsZURhdGFDb2x1bW4gPSB1bmRlZmluZWRcbiAgICAgIH1cblxuICAgICAgaWYgKG5ld1RhYmxlRGF0YUNvbHVtbikge1xuICAgICAgICBuZXdUYWJsZURhdGFDb2x1bW4uc2V0QXV0b0luY3JlbWVudCh0YWJsZURhdGFDb2x1bW4uZ2V0QXV0b0luY3JlbWVudCgpKVxuICAgICAgICBuZXdUYWJsZURhdGFDb2x1bW4uc2V0RGVmYXVsdCh0YWJsZURhdGFDb2x1bW4uZ2V0RGVmYXVsdCgpKVxuICAgICAgICBuZXdUYWJsZURhdGFDb2x1bW4uc2V0SW5kZXgodGFibGVEYXRhQ29sdW1uLmdldEluZGV4KCkpXG4gICAgICAgIG5ld1RhYmxlRGF0YUNvbHVtbi5zZXRGb3JlaWduS2V5KHRhYmxlRGF0YUNvbHVtbi5nZXRGb3JlaWduS2V5KCkpXG4gICAgICAgIG5ld1RhYmxlRGF0YUNvbHVtbi5zZXRNYXhMZW5ndGgodGFibGVEYXRhQ29sdW1uLmdldE1heExlbmd0aCgpKVxuICAgICAgICBuZXdUYWJsZURhdGFDb2x1bW4uc2V0UHJpbWFyeUtleSh0YWJsZURhdGFDb2x1bW4uZ2V0UHJpbWFyeUtleSgpKVxuICAgICAgICBuZXdUYWJsZURhdGFDb2x1bW4uc2V0VHlwZSh0YWJsZURhdGFDb2x1bW4uZ2V0VHlwZSgpKVxuICAgICAgfVxuXG4gICAgICBuZXdUYWJsZURhdGEuYWRkQ29sdW1uKG5ld1RhYmxlRGF0YUNvbHVtbiB8fCB0YWJsZURhdGFDb2x1bW4pXG4gICAgfVxuXG4gICAgLy8gU1FMaXRlIHJlYnVpbGRzIHVzZSBleGlzdGluZyBjb2x1bW5zIHBsdXMgbmV3IG9uZXM7IGF2b2lkIGR1cGxpY2F0aW5nIGEgY29sdW1uIHRoYXQgYWxyZWFkeSBleGlzdHMuXG4gICAgY29uc3QgZXhpc3RpbmdDb2x1bW5OYW1lcyA9IG5ldyBTZXQoY3VycmVudFRhYmxlRGF0YS5nZXRDb2x1bW5zKCkubWFwKChjb2x1bW4pID0+IGNvbHVtbi5nZXROYW1lKCkpKVxuXG4gICAgZm9yIChjb25zdCB0YWJsZURhdGFDb2x1bW4gb2YgdGFibGVEYXRhLmdldENvbHVtbnMoKSkge1xuICAgICAgaWYgKCF0YWJsZURhdGFDb2x1bW4uaXNOZXdDb2x1bW4oKSkgY29udGludWVcbiAgICAgIGlmIChleGlzdGluZ0NvbHVtbk5hbWVzLmhhcyh0YWJsZURhdGFDb2x1bW4uZ2V0TmFtZSgpKSkgY29udGludWVcblxuICAgICAgbmV3VGFibGVEYXRhLmFkZENvbHVtbih0YWJsZURhdGFDb2x1bW4pXG4gICAgfVxuXG4gICAgY29uc3QgZm91bmRGb3JlaWduS2V5cyA9IFtdXG5cbiAgICBmb3IgKGNvbnN0IHRhYmxlRGF0YUZvcmVpZ25LZXkgb2YgY3VycmVudFRhYmxlRGF0YS5nZXRGb3JlaWduS2V5cygpKSB7XG4gICAgICBjb25zdCBuZXdUYWJsZURhdGFGb3JlaWduS2V5ID0gbmV3VGFibGVEYXRhLmdldEZvcmVpZ25LZXlzKCkuZmluZCgobmV3VGFibGVEYXRhRm9yZWlnbktleSkgPT4gbmV3VGFibGVEYXRhRm9yZWlnbktleS5nZXROYW1lKCkgPT0gdGFibGVEYXRhRm9yZWlnbktleS5nZXROYW1lKCkpXG5cbiAgICAgIGlmIChuZXdUYWJsZURhdGFGb3JlaWduS2V5KSBmb3VuZEZvcmVpZ25LZXlzLnB1c2gobmV3VGFibGVEYXRhRm9yZWlnbktleS5nZXROYW1lKCkpXG5cbiAgICAgIGNvbnN0IGFjdHVhbFRhYmxlRGF0YUZvcmVpZ25LZXkgPSBuZXdUYWJsZURhdGFGb3JlaWduS2V5IHx8IHRhYmxlRGF0YUZvcmVpZ25LZXlcblxuICAgICAgLy8gUmVnaXN0ZXIgZm9yZWlnbiBrZXkgb24gdGhlIHRhYmxlXG4gICAgICBuZXdUYWJsZURhdGEuYWRkRm9yZWlnbktleShhY3R1YWxUYWJsZURhdGFGb3JlaWduS2V5KVxuXG4gICAgICAvLyBSZWdpc3RlciBmb3JlaWduIGtleSBvbiB0aGUgY29sdW1uXG4gICAgICBjb25zdCB0YWJsZURhdGFDb2x1bW4gPSBuZXdUYWJsZURhdGEuZ2V0Q29sdW1ucygpLmZpbmQoKG5ld1RhYmxlRGF0YUNvbHVtbikgPT4gbmV3VGFibGVEYXRhQ29sdW1uLmdldE5hbWUoKSA9PSBhY3R1YWxUYWJsZURhdGFGb3JlaWduS2V5LmdldENvbHVtbk5hbWUoKSlcblxuICAgICAgaWYgKCF0YWJsZURhdGFDb2x1bW4pIHRocm93IG5ldyBFcnJvcihgQ291bGRuJ3QgZmluZCBjb2x1bW4gZm9yIGZvcmVpZ24ga2V5OiAke2FjdHVhbFRhYmxlRGF0YUZvcmVpZ25LZXkuZ2V0TmFtZSgpfWApXG5cbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnTG93TGV2ZWwoKCkgPT4gYFNldHRpbmcgZm9yZWlnbiBrZXkgb24gY29sdW1uICR7dGFibGVEYXRhQ29sdW1uLmdldE5hbWUoKX1gKVxuICAgICAgdGFibGVEYXRhQ29sdW1uLnNldEZvcmVpZ25LZXkoYWN0dWFsVGFibGVEYXRhRm9yZWlnbktleSlcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGZvcmVpZ25LZXkgb2YgdGFibGVEYXRhLmdldEZvcmVpZ25LZXlzKCkpIHtcbiAgICAgIGlmIChmb3VuZEZvcmVpZ25LZXlzLmluY2x1ZGVzKGZvcmVpZ25LZXkuZ2V0TmFtZSgpKSkgY29udGludWVcblxuICAgICAgLy8gUmVnaXN0ZXIgZm9yZWlnbiBrZXkgb24gdGhlIHRhYmxlXG4gICAgICBuZXdUYWJsZURhdGEuYWRkRm9yZWlnbktleShmb3JlaWduS2V5KVxuXG4gICAgICAvLyBSZWdpc3RlciBmb3JlaWduIGtleSBvbiB0aGUgY29sdW1uXG4gICAgICBjb25zdCB0YWJsZURhdGFDb2x1bW4gPSBuZXdUYWJsZURhdGEuZ2V0Q29sdW1ucygpLmZpbmQoKG5ld1RhYmxlRGF0YUNvbHVtbikgPT4gbmV3VGFibGVEYXRhQ29sdW1uLmdldE5hbWUoKSA9PSBmb3JlaWduS2V5LmdldENvbHVtbk5hbWUoKSlcblxuICAgICAgaWYgKCF0YWJsZURhdGFDb2x1bW4pIHRocm93IG5ldyBFcnJvcihgQ291bGRuJ3QgZmluZCBjb2x1bW4gZm9yIGZvcmVpZ24ga2V5OiAke2ZvcmVpZ25LZXkuZ2V0TmFtZSgpfWApXG5cbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnTG93TGV2ZWwoKCkgPT4gYFNldHRpbmcgZm9yZWlnbiBrZXkgb24gY29sdW1uICR7dGFibGVEYXRhQ29sdW1uLmdldE5hbWUoKX1gKVxuICAgICAgdGFibGVEYXRhQ29sdW1uLnNldEZvcmVpZ25LZXkoZm9yZWlnbktleSlcbiAgICB9XG5cbiAgICBjb25zdCBjcmVhdGVOZXdUYWJsZVNRTCA9IGF3YWl0IHRoaXMuZ2V0RHJpdmVyKCkuY3JlYXRlVGFibGVTcWwobmV3VGFibGVEYXRhKVxuICAgIGNvbnN0IGluc2VydFNRTCA9IGBJTlNFUlQgSU5UTyAke29wdGlvbnMucXVvdGVUYWJsZU5hbWUodGVtcFRhYmxlTmFtZSl9ICgke25ld0NvbHVtbnNTUUx9KSBTRUxFQ1QgJHtvbGRDb2x1bW5zU1FMfSBGUk9NICR7b3B0aW9ucy5xdW90ZVRhYmxlTmFtZSh0YWJsZU5hbWUpfWBcbiAgICBjb25zdCBkcm9wVGFibGVTUUxzID0gYERST1AgVEFCTEUgJHtvcHRpb25zLnF1b3RlVGFibGVOYW1lKHRhYmxlTmFtZSl9YFxuICAgIGNvbnN0IHJlbmFtZVRhYmxlU1FMID0gYEFMVEVSIFRBQkxFICR7b3B0aW9ucy5xdW90ZVRhYmxlTmFtZSh0ZW1wVGFibGVOYW1lKX0gUkVOQU1FIFRPICR7b3B0aW9ucy5xdW90ZVRhYmxlTmFtZSh0YWJsZU5hbWUpfWBcbiAgICBjb25zdCBzcWxzID0gW11cblxuICAgIGZvciAoY29uc3Qgc3FsIG9mIGNyZWF0ZU5ld1RhYmxlU1FMKSB7XG4gICAgICBzcWxzLnB1c2goc3FsKVxuICAgIH1cblxuICAgIHNxbHMucHVzaChpbnNlcnRTUUwpXG4gICAgc3Fscy5wdXNoKGRyb3BUYWJsZVNRTHMpXG4gICAgc3Fscy5wdXNoKHJlbmFtZVRhYmxlU1FMKVxuXG4gICAgZm9yIChjb25zdCB0YWJsZURhdGFJbmRleCBvZiBjdXJyZW50VGFibGVEYXRhLmdldEluZGV4ZXMoKSkge1xuICAgICAgY29uc3QgbmV3VGFibGVEYXRhSW5kZXggPSBuZXdUYWJsZURhdGEuZ2V0SW5kZXhlcygpLmZpbmQoKG5ld1RhYmxlRGF0YUluZGV4KSA9PiBuZXdUYWJsZURhdGFJbmRleC5nZXROYW1lKCkgPT0gdGFibGVEYXRhSW5kZXguZ2V0TmFtZSgpKVxuICAgICAgY29uc3QgYWN0dWFsVGFibGVJbmRleCA9IG5ld1RhYmxlRGF0YUluZGV4IHx8IHRhYmxlRGF0YUluZGV4XG5cbiAgICAgIG5ld1RhYmxlRGF0YS5hZGRJbmRleChhY3R1YWxUYWJsZUluZGV4KVxuXG4gICAgICBjb25zdCBjb2x1bW5OYW1lcyA9IGFjdHVhbFRhYmxlSW5kZXguZ2V0Q29sdW1ucygpLm1hcCgoY29sdW1uTmFtZSkgPT4ge1xuICAgICAgICBjb25zdCBuZXdUYWJsZUNvbHVtbiA9IHRhYmxlRGF0YS5nZXRDb2x1bW5zKCkuZmluZCgodGFibGVDb2x1bW4pID0+IHRhYmxlQ29sdW1uLmdldE5hbWUoKSA9PSBjb2x1bW5OYW1lKVxuXG4gICAgICAgIHJldHVybiBuZXdUYWJsZUNvbHVtbj8uZ2V0TmV3TmFtZSgpIHx8IG5ld1RhYmxlQ29sdW1uPy5nZXROYW1lKCkgfHwgY29sdW1uTmFtZVxuICAgICAgfSlcblxuICAgICAgY29uc3QgY3JlYXRlSW5kZXhBcmdzID0ge1xuICAgICAgICBjb2x1bW5zOiBjb2x1bW5OYW1lcyxcbiAgICAgICAgZHJpdmVyOiB0aGlzLmdldERyaXZlcigpLFxuICAgICAgICBuYW1lOiBhY3R1YWxUYWJsZUluZGV4LmdldE5hbWUoKSxcbiAgICAgICAgdGFibGVOYW1lLFxuICAgICAgICB1bmlxdWU6IGFjdHVhbFRhYmxlSW5kZXguZ2V0VW5pcXVlKClcbiAgICAgIH1cbiAgICAgIGNvbnN0IGNyZWF0ZUluZGV4U1FMcyA9IGF3YWl0IG5ldyBDcmVhdGVJbmRleEJhc2UoY3JlYXRlSW5kZXhBcmdzKS50b1NRTHMoKVxuXG4gICAgICBmb3IgKGNvbnN0IGNyZWF0ZUluZGV4U1FMIG9mIGNyZWF0ZUluZGV4U1FMcykge1xuICAgICAgICBzcWxzLnB1c2goY3JlYXRlSW5kZXhTUUwpXG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHNxbHNcbiAgfVxufVxuIl19
161
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWx0ZXItdGFibGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvZGF0YWJhc2UvZHJpdmVycy9zcWxpdGUvc3FsL2FsdGVyLXRhYmxlLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLGNBQWMsTUFBTSxvQ0FBb0MsQ0FBQTtBQUMvRCxPQUFPLE1BQU0sTUFBTSx1QkFBdUIsQ0FBQTtBQUMxQyxPQUFPLGFBQWEsTUFBTSxzQ0FBc0MsQ0FBQTtBQUNoRSxPQUFPLFNBQVMsTUFBTSw4QkFBOEIsQ0FBQTtBQUNwRCxPQUFPLGVBQWUsTUFBTSwwQ0FBMEMsQ0FBQTtBQUN0RSxPQUFPLFVBQVUsTUFBTSxvQ0FBb0MsQ0FBQTtBQUMzRCxPQUFPLGNBQWMsTUFBTSx1QkFBdUIsQ0FBQTtBQUVsRCxNQUFNLENBQUMsT0FBTyxPQUFPLHFEQUFzRCxTQUFRLGNBQWM7SUFDL0Y7Ozs7T0FJRztJQUNILFlBQVksRUFBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLEdBQUcsUUFBUSxFQUFDO1FBQzFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUV2QixJQUFJLENBQUMsQ0FBQyxTQUFTLFlBQVksU0FBUyxDQUFDO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyw4QkFBOEIsQ0FBQyxDQUFBO1FBRXRGLEtBQUssQ0FBQyxFQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUMsQ0FBQyxDQUFBO1FBQzFCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDOUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUE7SUFDNUIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLE1BQU07UUFDVixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUE7UUFDL0IsTUFBTSxFQUFDLFNBQVMsRUFBRSxjQUFjLEVBQUMsR0FBRyxJQUFJLENBQUE7UUFD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LEVBQUU7U0FDckMsQ0FBQyxDQUFBO0lBQ0osQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCBBbHRlclRhYmxlQmFzZSBmcm9tIFwiLi4vLi4vLi4vcXVlcnkvYWx0ZXItdGFibGUtYmFzZS5qc1wiXG5pbXBvcnQgTG9nZ2VyIGZyb20gXCIuLi8uLi8uLi8uLi9sb2dnZXIuanNcIlxuaW1wb3J0IHJlc3RBcmdzRXJyb3IgZnJvbSBcIi4uLy4uLy4uLy4uL3V0aWxzL3Jlc3QtYXJncy1lcnJvci5qc1wiXG5pbXBvcnQgVGFibGVEYXRhIGZyb20gXCIuLi8uLi8uLi90YWJsZS1kYXRhL2luZGV4LmpzXCJcbmltcG9ydCBUYWJsZUZvcmVpZ25LZXkgZnJvbSBcIi4uLy4uLy4uL3RhYmxlLWRhdGEvdGFibGUtZm9yZWlnbi1rZXkuanNcIlxuaW1wb3J0IFRhYmxlSW5kZXggZnJvbSBcIi4uLy4uLy4uL3RhYmxlLWRhdGEvdGFibGUtaW5kZXguanNcIlxuaW1wb3J0IFRhYmxlUmVidWlsZGVyIGZyb20gXCIuLi90YWJsZS1yZWJ1aWxkZXIuanNcIlxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWZWxvY2lvdXNEYXRhYmFzZUNvbm5lY3Rpb25Ecml2ZXJzU3FsaXRlU3FsQWx0ZXJUYWJsZSBleHRlbmRzIEFsdGVyVGFibGVCYXNlIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vYmFzZS5qc1wiKS5kZWZhdWx0fSBhcmdzLmRyaXZlciAtIERhdGFiYXNlIGRyaXZlciBpbnN0YW5jZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi8uLi90YWJsZS1kYXRhL2luZGV4LmpzXCIpLmRlZmF1bHR9IGFyZ3MudGFibGVEYXRhIC0gVGFibGUgZGF0YS5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHtkcml2ZXIsIHRhYmxlRGF0YSwgLi4ucmVzdEFyZ3N9KSB7XG4gICAgcmVzdEFyZ3NFcnJvcihyZXN0QXJncylcblxuICAgIGlmICghKHRhYmxlRGF0YSBpbnN0YW5jZW9mIFRhYmxlRGF0YSkpIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgdGFibGUgZGF0YSB3YXMgZ2l2ZW5cIilcblxuICAgIHN1cGVyKHtkcml2ZXIsIHRhYmxlRGF0YX0pXG4gICAgdGhpcy5sb2dnZXIgPSBuZXcgTG9nZ2VyKHRoaXMpXG4gICAgdGhpcy50YWJsZURhdGEgPSB0YWJsZURhdGFcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmdbXT59IC0gUmVzb2x2ZXMgd2l0aCBTUUwgc3RhdGVtZW50cy5cbiAgICovXG4gIGFzeW5jIHRvU1FMcygpIHtcbiAgICBjb25zdCBkcml2ZXIgPSB0aGlzLmdldERyaXZlcigpXG4gICAgY29uc3Qge3RhYmxlRGF0YTogYWx0ZXJUYWJsZURhdGF9ID0gdGhpc1xuICAgIGNvbnN0IHRhYmxlTmFtZSA9IGFsdGVyVGFibGVEYXRhLmdldE5hbWUoKVxuICAgIGNvbnN0IHRhYmxlID0gYXdhaXQgZHJpdmVyLmdldFRhYmxlQnlOYW1lKHRhYmxlTmFtZSlcblxuICAgIGlmICghdGFibGUpIHRocm93IG5ldyBFcnJvcihgVGFibGUgJHt0YWJsZU5hbWV9IGRvZXMgbm90IGV4aXN0YClcblxuICAgIGNvbnN0IGN1cnJlbnRUYWJsZURhdGEgPSBhd2FpdCB0YWJsZS5nZXRUYWJsZURhdGEoKVxuICAgIGNvbnN0IHt0YXJnZXRUYWJsZURhdGEsIGNvbHVtblBhaXJzfSA9IHRoaXMuX2J1aWxkVGFyZ2V0U2NoZW1hKGN1cnJlbnRUYWJsZURhdGEsIGFsdGVyVGFibGVEYXRhKVxuXG4gICAgY29uc3QgcmVidWlsZGVyID0gbmV3IFRhYmxlUmVidWlsZGVyKHtcbiAgICAgIGNvbHVtblBhaXJzLFxuICAgICAgZHJpdmVyLFxuICAgICAgb3JpZ2luYWxUYWJsZU5hbWU6IHRhYmxlTmFtZSxcbiAgICAgIHRhcmdldFRhYmxlRGF0YVxuICAgIH0pXG5cbiAgICBjb25zdCByZWJ1aWxkU1FMcyA9IGF3YWl0IHJlYnVpbGRlci50b1NRTHMoKVxuICAgIGNvbnN0IHNxbHMgPSBbXVxuXG4gICAgLy8gUFJBR01BIGZvcmVpZ25fa2V5cyBjYW4gb25seSBiZSB0b2dnbGVkIG91dHNpZGUgYW4gYWN0aXZlIHRyYW5zYWN0aW9uOyB3aGVuIHRoZVxuICAgIC8vIGNhbGxlciBpcyBhbHJlYWR5IGluc2lkZSBvbmUgdGhlc2UgYmVjb21lIG5vLW9wcyAobWF0Y2hpbmcgcHJpb3IgYmVoYXZpb3IpLiBPdXRzaWRlXG4gICAgLy8gYSB0cmFuc2FjdGlvbiB0aGV5IHByb3RlY3QgdGhlIHJlYnVpbGQgZnJvbSBjcm9zcy10YWJsZSBGSyBlbmZvcmNlbWVudCBkdXJpbmcgdGhlXG4gICAgLy8gRFJPUC9SRU5BTUUgc3dhcC4gQ2FwdHVyZSB0aGUgcHJpb3Igc3RhdGUgc28gd2UgcmVzdG9yZSBpdCBpbnN0ZWFkIG9mIHVuY29uZGl0aW9uYWxseVxuICAgIC8vIGZvcmNpbmcgT04g4oCUIGNhbGxlcnMgdGhhdCBkZWxpYmVyYXRlbHkgZGlzYWJsZWQgRksgZW5mb3JjZW1lbnQgKGUuZy4gYnVsayBkYXRhIGZpeGVzKVxuICAgIC8vIHNob3VsZG4ndCBiZSBzaWxlbnRseSBmbGlwcGVkIGJhY2sgb24gYnkgYSBtaWdyYXRpb24uXG4gICAgY29uc3QgcHJpb3JTdGF0ZSA9IGF3YWl0IGRyaXZlci5xdWVyeShcIlBSQUdNQSBmb3JlaWduX2tleXNcIilcbiAgICBjb25zdCB3YXNFbmFibGVkID0gcHJpb3JTdGF0ZVswXT8uZm9yZWlnbl9rZXlzID09IDFcblxuICAgIHNxbHMucHVzaChcIlBSQUdNQSBmb3JlaWduX2tleXMgPSBPRkZcIilcblxuICAgIGZvciAoY29uc3Qgc3FsIG9mIHJlYnVpbGRTUUxzKSBzcWxzLnB1c2goc3FsKVxuXG4gICAgc3Fscy5wdXNoKGBQUkFHTUEgZm9yZWlnbl9rZXlzID0gJHt3YXNFbmFibGVkID8gXCJPTlwiIDogXCJPRkZcIn1gKVxuXG4gICAgcmV0dXJuIHNxbHNcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXJnZXMgdGhlIGN1cnJlbnQgc2NoZW1hIHdpdGggdGhlIGFsdGVyIHJlcXVlc3QgdG8gcHJvZHVjZSB0aGUgZGVzaXJlZCBmaW5hbCBzY2hlbWFcbiAgICogYW5kIHRoZSBjb2x1bW4gY29weSBwbGFuLlxuICAgKiBAcGFyYW0ge1RhYmxlRGF0YX0gY3VycmVudFRhYmxlRGF0YSAtIEN1cnJlbnQgc2NoZW1hIGFzIGludHJvc3BlY3RlZCBmcm9tIHRoZSBkYXRhYmFzZS5cbiAgICogQHBhcmFtIHtUYWJsZURhdGF9IGFsdGVyVGFibGVEYXRhIC0gQWx0ZXIgcmVxdWVzdDogbmV3IGNvbHVtbnMgKGBpc05ld0NvbHVtbmApLCByZW5hbWVzIChgbmV3TmFtZWApLCBkcm9wcyAoYGRyb3BDb2x1bW5gKSwgbW9kaWZpZXMsIGFuZCBuZXcgZm9yZWlnbiBrZXlzLlxuICAgKiBAcmV0dXJucyB7e3RhcmdldFRhYmxlRGF0YTogVGFibGVEYXRhLCBjb2x1bW5QYWlyczogQXJyYXk8W3N0cmluZywgc3RyaW5nXT59fSAtIFRoZSBtZXJnZWQgdGFyZ2V0IHNjaGVtYSBhbmQgdGhlIFtvbGROYW1lLCBuZXdOYW1lXSBwYWlycyBmb3IgSU5TRVJULi4uU0VMRUNULlxuICAgKi9cbiAgX2J1aWxkVGFyZ2V0U2NoZW1hKGN1cnJlbnRUYWJsZURhdGEsIGFsdGVyVGFibGVEYXRhKSB7XG4gICAgY29uc3QgdGFyZ2V0VGFibGVEYXRhID0gbmV3IFRhYmxlRGF0YShjdXJyZW50VGFibGVEYXRhLmdldE5hbWUoKSlcbiAgICAvKiogQHR5cGUge0FycmF5PFtzdHJpbmcsIHN0cmluZ10+fSAqL1xuICAgIGNvbnN0IGNvbHVtblBhaXJzID0gW11cbiAgICBjb25zdCBhbHRlckNvbHVtbnMgPSBhbHRlclRhYmxlRGF0YS5nZXRDb2x1bW5zKClcbiAgICBjb25zdCBleGlzdGluZ05hbWVzID0gbmV3IFNldChjdXJyZW50VGFibGVEYXRhLmdldENvbHVtbnMoKS5tYXAoKGNvbHVtbikgPT4gY29sdW1uLmdldE5hbWUoKSkpXG4gICAgLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBzdHJpbmc+fSAqL1xuICAgIGNvbnN0IGNvbHVtblJlbmFtZXMgPSBuZXcgTWFwKClcblxuICAgIGZvciAoY29uc3QgYWx0ZXJDb2x1bW4gb2YgYWx0ZXJDb2x1bW5zKSB7XG4gICAgICBpZiAoYWx0ZXJDb2x1bW4uaXNOZXdDb2x1bW4oKSkgY29udGludWVcblxuICAgICAgY29uc3QgbmV3TmFtZSA9IGFsdGVyQ29sdW1uLmdldE5ld05hbWUoKVxuXG4gICAgICBpZiAobmV3TmFtZSkgY29sdW1uUmVuYW1lcy5zZXQoYWx0ZXJDb2x1bW4uZ2V0TmFtZSgpLCBuZXdOYW1lKVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgY3VycmVudENvbHVtbiBvZiBjdXJyZW50VGFibGVEYXRhLmdldENvbHVtbnMoKSkge1xuICAgICAgY29uc3QgYWx0ZXJDb2x1bW4gPSBhbHRlckNvbHVtbnMuZmluZCgoY29sdW1uKSA9PiBjb2x1bW4uZ2V0TmFtZSgpID09IGN1cnJlbnRDb2x1bW4uZ2V0TmFtZSgpICYmICFjb2x1bW4uaXNOZXdDb2x1bW4oKSlcblxuICAgICAgaWYgKGFsdGVyQ29sdW1uPy5nZXREcm9wQ29sdW1uKCkpIGNvbnRpbnVlXG5cbiAgICAgIGxldCB0YXJnZXRDb2x1bW5cblxuICAgICAgaWYgKGFsdGVyQ29sdW1uKSB7XG4gICAgICAgIC8vIFRoZSBhbHRlciByZXF1ZXN0IHN1cHBsaWVzIGEgcGFydGlhbCBjb2x1bW4gc3BlYyAoZS5nLiBqdXN0IGEgcmVuYW1lIG9yIGEgdHlwZSBjaGFuZ2UpO1xuICAgICAgICAvLyBpbmhlcml0IHVuc2V0IHByb3BlcnRpZXMgZnJvbSB0aGUgY3VycmVudCBjb2x1bW4gc28gd2UgZG9uJ3QgbG9zZSBleGlzdGluZyBkZWZpbml0aW9ucy5cbiAgICAgICAgYWx0ZXJDb2x1bW4uc2V0QXV0b0luY3JlbWVudChhbHRlckNvbHVtbi5nZXRBdXRvSW5jcmVtZW50KCkgfHwgY3VycmVudENvbHVtbi5nZXRBdXRvSW5jcmVtZW50KCkpXG4gICAgICAgIGlmIChhbHRlckNvbHVtbi5nZXREZWZhdWx0KCkgPT09IHVuZGVmaW5lZCkgYWx0ZXJDb2x1bW4uc2V0RGVmYXVsdChjdXJyZW50Q29sdW1uLmdldERlZmF1bHQoKSlcbiAgICAgICAgaWYgKCFhbHRlckNvbHVtbi5nZXRJbmRleCgpKSBhbHRlckNvbHVtbi5zZXRJbmRleChjdXJyZW50Q29sdW1uLmdldEluZGV4KCkpXG4gICAgICAgIGlmICghYWx0ZXJDb2x1bW4uZ2V0Rm9yZWlnbktleSgpKSBhbHRlckNvbHVtbi5zZXRGb3JlaWduS2V5KGN1cnJlbnRDb2x1bW4uZ2V0Rm9yZWlnbktleSgpKVxuICAgICAgICBpZiAoYWx0ZXJDb2x1bW4uZ2V0TWF4TGVuZ3RoKCkgPT09IHVuZGVmaW5lZCkgYWx0ZXJDb2x1bW4uc2V0TWF4TGVuZ3RoKGN1cnJlbnRDb2x1bW4uZ2V0TWF4TGVuZ3RoKCkpXG4gICAgICAgIGFsdGVyQ29sdW1uLnNldFByaW1hcnlLZXkoYWx0ZXJDb2x1bW4uZ2V0UHJpbWFyeUtleSgpIHx8IGN1cnJlbnRDb2x1bW4uZ2V0UHJpbWFyeUtleSgpKVxuICAgICAgICBpZiAoIWFsdGVyQ29sdW1uLmdldFR5cGUoKSkgYWx0ZXJDb2x1bW4uc2V0VHlwZShjdXJyZW50Q29sdW1uLmdldFR5cGUoKSlcblxuICAgICAgICB0YXJnZXRDb2x1bW4gPSBhbHRlckNvbHVtblxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGFyZ2V0Q29sdW1uID0gY3VycmVudENvbHVtblxuICAgICAgfVxuXG4gICAgICB0YXJnZXRUYWJsZURhdGEuYWRkQ29sdW1uKHRhcmdldENvbHVtbilcbiAgICAgIGNvbHVtblBhaXJzLnB1c2goW2N1cnJlbnRDb2x1bW4uZ2V0TmFtZSgpLCB0YXJnZXRDb2x1bW4uZ2V0TmV3TmFtZSgpIHx8IHRhcmdldENvbHVtbi5nZXROYW1lKCldKVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgYWx0ZXJDb2x1bW4gb2YgYWx0ZXJDb2x1bW5zKSB7XG4gICAgICBpZiAoIWFsdGVyQ29sdW1uLmlzTmV3Q29sdW1uKCkpIGNvbnRpbnVlXG4gICAgICBpZiAoZXhpc3RpbmdOYW1lcy5oYXMoYWx0ZXJDb2x1bW4uZ2V0TmFtZSgpKSkgY29udGludWVcblxuICAgICAgdGFyZ2V0VGFibGVEYXRhLmFkZENvbHVtbihhbHRlckNvbHVtbilcbiAgICB9XG5cbiAgICBjb25zdCBzZWVuRm9yZWlnbktleU5hbWVzID0gbmV3IFNldCgpXG5cbiAgICBmb3IgKGNvbnN0IGN1cnJlbnRGb3JlaWduS2V5IG9mIGN1cnJlbnRUYWJsZURhdGEuZ2V0Rm9yZWlnbktleXMoKSkge1xuICAgICAgY29uc3QgYWx0ZXJGb3JlaWduS2V5ID0gYWx0ZXJUYWJsZURhdGEuZ2V0Rm9yZWlnbktleXMoKS5maW5kKChmb3JlaWduS2V5KSA9PiBmb3JlaWduS2V5LmdldE5hbWUoKSA9PSBjdXJyZW50Rm9yZWlnbktleS5nZXROYW1lKCkpXG4gICAgICBjb25zdCBmaW5hbEZvcmVpZ25LZXkgPSB0aGlzLl9yZW5hbWVGb3JlaWduS2V5Q29sdW1uKGFsdGVyRm9yZWlnbktleSB8fCBjdXJyZW50Rm9yZWlnbktleSwgY29sdW1uUmVuYW1lcylcblxuICAgICAgc2VlbkZvcmVpZ25LZXlOYW1lcy5hZGQoZmluYWxGb3JlaWduS2V5LmdldE5hbWUoKSlcbiAgICAgIHRhcmdldFRhYmxlRGF0YS5hZGRGb3JlaWduS2V5KGZpbmFsRm9yZWlnbktleSlcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGFsdGVyRm9yZWlnbktleSBvZiBhbHRlclRhYmxlRGF0YS5nZXRGb3JlaWduS2V5cygpKSB7XG4gICAgICBpZiAoc2VlbkZvcmVpZ25LZXlOYW1lcy5oYXMoYWx0ZXJGb3JlaWduS2V5LmdldE5hbWUoKSkpIGNvbnRpbnVlXG5cbiAgICAgIHRhcmdldFRhYmxlRGF0YS5hZGRGb3JlaWduS2V5KHRoaXMuX3JlbmFtZUZvcmVpZ25LZXlDb2x1bW4oYWx0ZXJGb3JlaWduS2V5LCBjb2x1bW5SZW5hbWVzKSlcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGN1cnJlbnRJbmRleCBvZiBjdXJyZW50VGFibGVEYXRhLmdldEluZGV4ZXMoKSkge1xuICAgICAgY29uc3QgcmVuYW1lZENvbHVtbnMgPSBjdXJyZW50SW5kZXguZ2V0Q29sdW1ucygpLm1hcCgoY29sdW1uTmFtZSkgPT4ge1xuICAgICAgICBpZiAodHlwZW9mIGNvbHVtbk5hbWUgIT0gXCJzdHJpbmdcIikgcmV0dXJuIGNvbHVtbk5hbWVcblxuICAgICAgICByZXR1cm4gY29sdW1uUmVuYW1lcy5nZXQoY29sdW1uTmFtZSkgfHwgY29sdW1uTmFtZVxuICAgICAgfSlcblxuICAgICAgdGFyZ2V0VGFibGVEYXRhLmFkZEluZGV4KG5ldyBUYWJsZUluZGV4KHJlbmFtZWRDb2x1bW5zLCB7XG4gICAgICAgIG5hbWU6IGN1cnJlbnRJbmRleC5nZXROYW1lKCksXG4gICAgICAgIHVuaXF1ZTogY3VycmVudEluZGV4LmdldFVuaXF1ZSgpXG4gICAgICB9KSlcbiAgICB9XG5cbiAgICByZXR1cm4ge3RhcmdldFRhYmxlRGF0YSwgY29sdW1uUGFpcnN9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgZm9yZWlnbiBrZXkgd2l0aCBpdHMgY29sdW1uIG5hbWUgdXBkYXRlZCB3aGVuIHRoZSBjb2x1bW4gd2FzIHJlbmFtZWQgaW4gdGhlXG4gICAqIGFsdGVyIHJlcXVlc3QuIFNRTGl0ZSByZS1jcmVhdGVzIHRoZSBjb25zdHJhaW50IGluc2lkZSB0aGUgcmVidWlsdCBDUkVBVEUgVEFCTEUsIHNvIGFcbiAgICogc3RhbGUgY29sdW1uIG5hbWUgdGhlcmUgd291bGQgcmVmZXJlbmNlIGEgY29sdW1uIHRoYXQgbm8gbG9uZ2VyIGV4aXN0cy5cbiAgICogQHBhcmFtIHtUYWJsZUZvcmVpZ25LZXl9IGZvcmVpZ25LZXkgLSBGb3JlaWduIGtleSB0byBldmFsdWF0ZS5cbiAgICogQHBhcmFtIHtNYXA8c3RyaW5nLCBzdHJpbmc+fSBjb2x1bW5SZW5hbWVzIC0gTWFwIG9mIG9sZCDihpIgbmV3IGNvbHVtbiBuYW1lcyBmcm9tIHRoZSBhbHRlciByZXF1ZXN0LlxuICAgKiBAcmV0dXJucyB7VGFibGVGb3JlaWduS2V5fSAtIFRoZSBvcmlnaW5hbCBmb3JlaWduIGtleSwgb3IgYSBmcmVzaCBpbnN0YW5jZSB3aXRoIHRoZSByZW5hbWVkIGNvbHVtbi5cbiAgICovXG4gIF9yZW5hbWVGb3JlaWduS2V5Q29sdW1uKGZvcmVpZ25LZXksIGNvbHVtblJlbmFtZXMpIHtcbiAgICBjb25zdCByZW5hbWVkID0gY29sdW1uUmVuYW1lcy5nZXQoZm9yZWlnbktleS5nZXRDb2x1bW5OYW1lKCkpXG5cbiAgICBpZiAoIXJlbmFtZWQpIHJldHVybiBmb3JlaWduS2V5XG5cbiAgICByZXR1cm4gbmV3IFRhYmxlRm9yZWlnbktleSh7XG4gICAgICBjb2x1bW5OYW1lOiByZW5hbWVkLFxuICAgICAgaXNOZXdGb3JlaWduS2V5OiBmb3JlaWduS2V5LmdldElzTmV3Rm9yZWlnbktleSgpLFxuICAgICAgbmFtZTogZm9yZWlnbktleS5nZXROYW1lKCksXG4gICAgICByZWZlcmVuY2VkQ29sdW1uTmFtZTogZm9yZWlnbktleS5nZXRSZWZlcmVuY2VkQ29sdW1uTmFtZSgpLFxuICAgICAgcmVmZXJlbmNlZFRhYmxlTmFtZTogZm9yZWlnbktleS5nZXRSZWZlcmVuY2VkVGFibGVOYW1lKCksXG4gICAgICB0YWJsZU5hbWU6IGZvcmVpZ25LZXkuZ2V0VGFibGVOYW1lKClcbiAgICB9KVxuICB9XG59XG4iXX0=
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Emits the SQL sequence for SQLite's "rebuild" approach to schema changes.
3
+ *
4
+ * SQLite cannot add/drop foreign-key constraints, drop columns on older
5
+ * versions, change column types, or add CHECK constraints via ALTER TABLE.
6
+ * The standard workaround (https://sqlite.org/lang_altertable.html) is to
7
+ * create a new table with the desired schema, copy rows over, drop the
8
+ * original, and rename the replacement.
9
+ *
10
+ * Caller passes the desired final schema; this class handles the mechanical
11
+ * sequence (CREATE temp / INSERT...SELECT / DROP / RENAME / recreate
12
+ * indexes). Caller is responsible for any FK toggling or transaction setup
13
+ * around the returned SQL — `PRAGMA foreign_keys` is connection-scoped and
14
+ * cannot be flipped inside a transaction, so wrapping policy is left to the
15
+ * caller (see `sql/alter-table.js`).
16
+ */
17
+ export default class VelociousDatabaseDriversSqliteTableRebuilder {
18
+ /**
19
+ * @param {object} args - Options object.
20
+ * @param {import("../base.js").default} args.driver - Database driver instance.
21
+ * @param {string} args.originalTableName - Name of the existing table to rebuild.
22
+ * @param {TableData} args.targetTableData - Desired final schema (columns + foreign keys + indexes). The instance's name is overwritten internally during emission.
23
+ * @param {Array<[string, string]>} args.columnPairs - Pairs of [oldColumnName, newColumnName] describing how rows from the original table should populate the rebuilt table.
24
+ */
25
+ constructor({ driver, originalTableName, targetTableData, columnPairs, ...restArgs }: {
26
+ driver: import("../base.js").default;
27
+ originalTableName: string;
28
+ targetTableData: TableData;
29
+ columnPairs: Array<[string, string]>;
30
+ });
31
+ driver: import("../base.js").default;
32
+ originalTableName: string;
33
+ targetTableData: TableData;
34
+ columnPairs: [string, string][];
35
+ /**
36
+ * @returns {Promise<string[]>} - Resolves with SQL statements to execute in order.
37
+ */
38
+ toSQLs(): Promise<string[]>;
39
+ }
40
+ import TableData from "../../table-data/index.js";
41
+ //# sourceMappingURL=table-rebuilder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-rebuilder.d.ts","sourceRoot":"","sources":["../../../../../src/database/drivers/sqlite/table-rebuilder.js"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;GAeG;AACH;IACE;;;;;;OAMG;IACH,sFALG;QAA2C,MAAM,EAAzC,OAAO,YAAY,EAAE,OAAO;QACf,iBAAiB,EAA9B,MAAM;QACU,eAAe,EAA/B,SAAS;QACqB,WAAW,EAAzC,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACjC,EAUA;IAJC,qCAAoB;IACpB,0BAA0C;IAC1C,2BAAsC;IACtC,gCAA8B;IAGhC;;OAEG;IACH,UAFa,OAAO,CAAC,MAAM,EAAE,CAAC,CAkD7B;CACF;sBAzFqB,2BAA2B"}
@@ -0,0 +1,81 @@
1
+ // @ts-check
2
+ import CreateIndexBase from "../../query/create-index-base.js";
3
+ import restArgsError from "../../../utils/rest-args-error.js";
4
+ import TableData from "../../table-data/index.js";
5
+ /**
6
+ * Emits the SQL sequence for SQLite's "rebuild" approach to schema changes.
7
+ *
8
+ * SQLite cannot add/drop foreign-key constraints, drop columns on older
9
+ * versions, change column types, or add CHECK constraints via ALTER TABLE.
10
+ * The standard workaround (https://sqlite.org/lang_altertable.html) is to
11
+ * create a new table with the desired schema, copy rows over, drop the
12
+ * original, and rename the replacement.
13
+ *
14
+ * Caller passes the desired final schema; this class handles the mechanical
15
+ * sequence (CREATE temp / INSERT...SELECT / DROP / RENAME / recreate
16
+ * indexes). Caller is responsible for any FK toggling or transaction setup
17
+ * around the returned SQL — `PRAGMA foreign_keys` is connection-scoped and
18
+ * cannot be flipped inside a transaction, so wrapping policy is left to the
19
+ * caller (see `sql/alter-table.js`).
20
+ */
21
+ export default class VelociousDatabaseDriversSqliteTableRebuilder {
22
+ /**
23
+ * @param {object} args - Options object.
24
+ * @param {import("../base.js").default} args.driver - Database driver instance.
25
+ * @param {string} args.originalTableName - Name of the existing table to rebuild.
26
+ * @param {TableData} args.targetTableData - Desired final schema (columns + foreign keys + indexes). The instance's name is overwritten internally during emission.
27
+ * @param {Array<[string, string]>} args.columnPairs - Pairs of [oldColumnName, newColumnName] describing how rows from the original table should populate the rebuilt table.
28
+ */
29
+ constructor({ driver, originalTableName, targetTableData, columnPairs, ...restArgs }) {
30
+ restArgsError(restArgs);
31
+ if (!(targetTableData instanceof TableData))
32
+ throw new Error("Invalid target table data was given");
33
+ this.driver = driver;
34
+ this.originalTableName = originalTableName;
35
+ this.targetTableData = targetTableData;
36
+ this.columnPairs = columnPairs;
37
+ }
38
+ /**
39
+ * @returns {Promise<string[]>} - Resolves with SQL statements to execute in order.
40
+ */
41
+ async toSQLs() {
42
+ const driver = this.driver;
43
+ const options = driver.options();
44
+ const originalTableName = this.originalTableName;
45
+ const tempTableName = `${originalTableName}_velocious_rebuild`;
46
+ const targetTableData = this.targetTableData;
47
+ const previousTargetName = targetTableData.getName();
48
+ targetTableData.setName(tempTableName);
49
+ let createTableSQLs;
50
+ try {
51
+ createTableSQLs = await driver.createTableSql(targetTableData);
52
+ }
53
+ finally {
54
+ targetTableData.setName(previousTargetName);
55
+ }
56
+ const newColumnsSQL = this.columnPairs.map(([, newName]) => options.quoteColumnName(newName)).join(", ");
57
+ const oldColumnsSQL = this.columnPairs.map(([oldName]) => options.quoteColumnName(oldName)).join(", ");
58
+ const sqls = [];
59
+ for (const sql of createTableSQLs)
60
+ sqls.push(sql);
61
+ if (this.columnPairs.length > 0) {
62
+ sqls.push(`INSERT INTO ${options.quoteTableName(tempTableName)} (${newColumnsSQL}) ` +
63
+ `SELECT ${oldColumnsSQL} FROM ${options.quoteTableName(originalTableName)}`);
64
+ }
65
+ sqls.push(`DROP TABLE ${options.quoteTableName(originalTableName)}`);
66
+ sqls.push(`ALTER TABLE ${options.quoteTableName(tempTableName)} RENAME TO ${options.quoteTableName(originalTableName)}`);
67
+ for (const tableDataIndex of targetTableData.getIndexes()) {
68
+ const createIndexSQLs = await new CreateIndexBase({
69
+ columns: tableDataIndex.getColumns(),
70
+ driver,
71
+ name: tableDataIndex.getName(),
72
+ tableName: originalTableName,
73
+ unique: tableDataIndex.getUnique()
74
+ }).toSQLs();
75
+ for (const sql of createIndexSQLs)
76
+ sqls.push(sql);
77
+ }
78
+ return sqls;
79
+ }
80
+ }
81
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUtcmVidWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2RhdGFiYXNlL2RyaXZlcnMvc3FsaXRlL3RhYmxlLXJlYnVpbGRlci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxlQUFlLE1BQU0sa0NBQWtDLENBQUE7QUFDOUQsT0FBTyxhQUFhLE1BQU0sbUNBQW1DLENBQUE7QUFDN0QsT0FBTyxTQUFTLE1BQU0sMkJBQTJCLENBQUE7QUFFakQ7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBQ0gsTUFBTSxDQUFDLE9BQU8sT0FBTyw0Q0FBNEM7SUFDL0Q7Ozs7OztPQU1HO0lBQ0gsWUFBWSxFQUFDLE1BQU0sRUFBRSxpQkFBaUIsRUFBRSxlQUFlLEVBQUUsV0FBVyxFQUFFLEdBQUcsUUFBUSxFQUFDO1FBQ2hGLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUV2QixJQUFJLENBQUMsQ0FBQyxlQUFlLFlBQVksU0FBUyxDQUFDO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFBO1FBRW5HLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFBO1FBQ3BCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxpQkFBaUIsQ0FBQTtRQUMxQyxJQUFJLENBQUMsZUFBZSxHQUFHLGVBQWUsQ0FBQTtRQUN0QyxJQUFJLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQTtJQUNoQyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsTUFBTTtRQUNWLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUE7UUFDMUIsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFBO1FBQ2hDLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFBO1FBQ2hELE1BQU0sYUFBYSxHQUFHLEdBQUcsaUJBQWlCLG9CQUFvQixDQUFBO1FBQzlELE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUE7UUFDNUMsTUFBTSxrQkFBa0IsR0FBRyxlQUFlLENBQUMsT0FBTyxFQUFFLENBQUE7UUFFcEQsZUFBZSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQTtRQUV0QyxJQUFJLGVBQWUsQ0FBQTtRQUVuQixJQUFJLENBQUM7WUFDSCxlQUFlLEdBQUcsTUFBTSxNQUFNLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyxDQUFBO1FBQ2hFLENBQUM7Z0JBQVMsQ0FBQztZQUNULGVBQWUsQ0FBQyxPQUFPLENBQUMsa0JBQWtCLENBQUMsQ0FBQTtRQUM3QyxDQUFDO1FBRUQsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDeEcsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBRXRHLE1BQU0sSUFBSSxHQUFHLEVBQUUsQ0FBQTtRQUVmLEtBQUssTUFBTSxHQUFHLElBQUksZUFBZTtZQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUE7UUFFakQsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNoQyxJQUFJLENBQUMsSUFBSSxDQUNQLGVBQWUsT0FBTyxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsS0FBSyxhQUFhLElBQUk7Z0JBQzFFLFVBQVUsYUFBYSxTQUFTLE9BQU8sQ0FBQyxjQUFjLENBQUMsaUJBQWlCLENBQUMsRUFBRSxDQUM1RSxDQUFBO1FBQ0gsQ0FBQztRQUVELElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxPQUFPLENBQUMsY0FBYyxDQUFDLGlCQUFpQixDQUFDLEVBQUUsQ0FBQyxDQUFBO1FBQ3BFLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxPQUFPLENBQUMsY0FBYyxDQUFDLGFBQWEsQ0FBQyxjQUFjLE9BQU8sQ0FBQyxjQUFjLENBQUMsaUJBQWlCLENBQUMsRUFBRSxDQUFDLENBQUE7UUFFeEgsS0FBSyxNQUFNLGNBQWMsSUFBSSxlQUFlLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQztZQUMxRCxNQUFNLGVBQWUsR0FBRyxNQUFNLElBQUksZUFBZSxDQUFDO2dCQUNoRCxPQUFPLEVBQUUsY0FBYyxDQUFDLFVBQVUsRUFBRTtnQkFDcEMsTUFBTTtnQkFDTixJQUFJLEVBQUUsY0FBYyxDQUFDLE9BQU8sRUFBRTtnQkFDOUIsU0FBUyxFQUFFLGlCQUFpQjtnQkFDNUIsTUFBTSxFQUFFLGNBQWMsQ0FBQyxTQUFTLEVBQUU7YUFDbkMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFBO1lBRVgsS0FBSyxNQUFNLEdBQUcsSUFBSSxlQUFlO2dCQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUE7UUFDbkQsQ0FBQztRQUVELE9BQU8sSUFBSSxDQUFBO0lBQ2IsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCBDcmVhdGVJbmRleEJhc2UgZnJvbSBcIi4uLy4uL3F1ZXJ5L2NyZWF0ZS1pbmRleC1iYXNlLmpzXCJcbmltcG9ydCByZXN0QXJnc0Vycm9yIGZyb20gXCIuLi8uLi8uLi91dGlscy9yZXN0LWFyZ3MtZXJyb3IuanNcIlxuaW1wb3J0IFRhYmxlRGF0YSBmcm9tIFwiLi4vLi4vdGFibGUtZGF0YS9pbmRleC5qc1wiXG5cbi8qKlxuICogRW1pdHMgdGhlIFNRTCBzZXF1ZW5jZSBmb3IgU1FMaXRlJ3MgXCJyZWJ1aWxkXCIgYXBwcm9hY2ggdG8gc2NoZW1hIGNoYW5nZXMuXG4gKlxuICogU1FMaXRlIGNhbm5vdCBhZGQvZHJvcCBmb3JlaWduLWtleSBjb25zdHJhaW50cywgZHJvcCBjb2x1bW5zIG9uIG9sZGVyXG4gKiB2ZXJzaW9ucywgY2hhbmdlIGNvbHVtbiB0eXBlcywgb3IgYWRkIENIRUNLIGNvbnN0cmFpbnRzIHZpYSBBTFRFUiBUQUJMRS5cbiAqIFRoZSBzdGFuZGFyZCB3b3JrYXJvdW5kIChodHRwczovL3NxbGl0ZS5vcmcvbGFuZ19hbHRlcnRhYmxlLmh0bWwpIGlzIHRvXG4gKiBjcmVhdGUgYSBuZXcgdGFibGUgd2l0aCB0aGUgZGVzaXJlZCBzY2hlbWEsIGNvcHkgcm93cyBvdmVyLCBkcm9wIHRoZVxuICogb3JpZ2luYWwsIGFuZCByZW5hbWUgdGhlIHJlcGxhY2VtZW50LlxuICpcbiAqIENhbGxlciBwYXNzZXMgdGhlIGRlc2lyZWQgZmluYWwgc2NoZW1hOyB0aGlzIGNsYXNzIGhhbmRsZXMgdGhlIG1lY2hhbmljYWxcbiAqIHNlcXVlbmNlIChDUkVBVEUgdGVtcCAvIElOU0VSVC4uLlNFTEVDVCAvIERST1AgLyBSRU5BTUUgLyByZWNyZWF0ZVxuICogaW5kZXhlcykuIENhbGxlciBpcyByZXNwb25zaWJsZSBmb3IgYW55IEZLIHRvZ2dsaW5nIG9yIHRyYW5zYWN0aW9uIHNldHVwXG4gKiBhcm91bmQgdGhlIHJldHVybmVkIFNRTCDigJQgYFBSQUdNQSBmb3JlaWduX2tleXNgIGlzIGNvbm5lY3Rpb24tc2NvcGVkIGFuZFxuICogY2Fubm90IGJlIGZsaXBwZWQgaW5zaWRlIGEgdHJhbnNhY3Rpb24sIHNvIHdyYXBwaW5nIHBvbGljeSBpcyBsZWZ0IHRvIHRoZVxuICogY2FsbGVyIChzZWUgYHNxbC9hbHRlci10YWJsZS5qc2ApLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWZWxvY2lvdXNEYXRhYmFzZURyaXZlcnNTcWxpdGVUYWJsZVJlYnVpbGRlciB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Jhc2UuanNcIikuZGVmYXVsdH0gYXJncy5kcml2ZXIgLSBEYXRhYmFzZSBkcml2ZXIgaW5zdGFuY2UuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLm9yaWdpbmFsVGFibGVOYW1lIC0gTmFtZSBvZiB0aGUgZXhpc3RpbmcgdGFibGUgdG8gcmVidWlsZC5cbiAgICogQHBhcmFtIHtUYWJsZURhdGF9IGFyZ3MudGFyZ2V0VGFibGVEYXRhIC0gRGVzaXJlZCBmaW5hbCBzY2hlbWEgKGNvbHVtbnMgKyBmb3JlaWduIGtleXMgKyBpbmRleGVzKS4gVGhlIGluc3RhbmNlJ3MgbmFtZSBpcyBvdmVyd3JpdHRlbiBpbnRlcm5hbGx5IGR1cmluZyBlbWlzc2lvbi5cbiAgICogQHBhcmFtIHtBcnJheTxbc3RyaW5nLCBzdHJpbmddPn0gYXJncy5jb2x1bW5QYWlycyAtIFBhaXJzIG9mIFtvbGRDb2x1bW5OYW1lLCBuZXdDb2x1bW5OYW1lXSBkZXNjcmliaW5nIGhvdyByb3dzIGZyb20gdGhlIG9yaWdpbmFsIHRhYmxlIHNob3VsZCBwb3B1bGF0ZSB0aGUgcmVidWlsdCB0YWJsZS5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHtkcml2ZXIsIG9yaWdpbmFsVGFibGVOYW1lLCB0YXJnZXRUYWJsZURhdGEsIGNvbHVtblBhaXJzLCAuLi5yZXN0QXJnc30pIHtcbiAgICByZXN0QXJnc0Vycm9yKHJlc3RBcmdzKVxuXG4gICAgaWYgKCEodGFyZ2V0VGFibGVEYXRhIGluc3RhbmNlb2YgVGFibGVEYXRhKSkgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCB0YXJnZXQgdGFibGUgZGF0YSB3YXMgZ2l2ZW5cIilcblxuICAgIHRoaXMuZHJpdmVyID0gZHJpdmVyXG4gICAgdGhpcy5vcmlnaW5hbFRhYmxlTmFtZSA9IG9yaWdpbmFsVGFibGVOYW1lXG4gICAgdGhpcy50YXJnZXRUYWJsZURhdGEgPSB0YXJnZXRUYWJsZURhdGFcbiAgICB0aGlzLmNvbHVtblBhaXJzID0gY29sdW1uUGFpcnNcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmdbXT59IC0gUmVzb2x2ZXMgd2l0aCBTUUwgc3RhdGVtZW50cyB0byBleGVjdXRlIGluIG9yZGVyLlxuICAgKi9cbiAgYXN5bmMgdG9TUUxzKCkge1xuICAgIGNvbnN0IGRyaXZlciA9IHRoaXMuZHJpdmVyXG4gICAgY29uc3Qgb3B0aW9ucyA9IGRyaXZlci5vcHRpb25zKClcbiAgICBjb25zdCBvcmlnaW5hbFRhYmxlTmFtZSA9IHRoaXMub3JpZ2luYWxUYWJsZU5hbWVcbiAgICBjb25zdCB0ZW1wVGFibGVOYW1lID0gYCR7b3JpZ2luYWxUYWJsZU5hbWV9X3ZlbG9jaW91c19yZWJ1aWxkYFxuICAgIGNvbnN0IHRhcmdldFRhYmxlRGF0YSA9IHRoaXMudGFyZ2V0VGFibGVEYXRhXG4gICAgY29uc3QgcHJldmlvdXNUYXJnZXROYW1lID0gdGFyZ2V0VGFibGVEYXRhLmdldE5hbWUoKVxuXG4gICAgdGFyZ2V0VGFibGVEYXRhLnNldE5hbWUodGVtcFRhYmxlTmFtZSlcblxuICAgIGxldCBjcmVhdGVUYWJsZVNRTHNcblxuICAgIHRyeSB7XG4gICAgICBjcmVhdGVUYWJsZVNRTHMgPSBhd2FpdCBkcml2ZXIuY3JlYXRlVGFibGVTcWwodGFyZ2V0VGFibGVEYXRhKVxuICAgIH0gZmluYWxseSB7XG4gICAgICB0YXJnZXRUYWJsZURhdGEuc2V0TmFtZShwcmV2aW91c1RhcmdldE5hbWUpXG4gICAgfVxuXG4gICAgY29uc3QgbmV3Q29sdW1uc1NRTCA9IHRoaXMuY29sdW1uUGFpcnMubWFwKChbLCBuZXdOYW1lXSkgPT4gb3B0aW9ucy5xdW90ZUNvbHVtbk5hbWUobmV3TmFtZSkpLmpvaW4oXCIsIFwiKVxuICAgIGNvbnN0IG9sZENvbHVtbnNTUUwgPSB0aGlzLmNvbHVtblBhaXJzLm1hcCgoW29sZE5hbWVdKSA9PiBvcHRpb25zLnF1b3RlQ29sdW1uTmFtZShvbGROYW1lKSkuam9pbihcIiwgXCIpXG5cbiAgICBjb25zdCBzcWxzID0gW11cblxuICAgIGZvciAoY29uc3Qgc3FsIG9mIGNyZWF0ZVRhYmxlU1FMcykgc3Fscy5wdXNoKHNxbClcblxuICAgIGlmICh0aGlzLmNvbHVtblBhaXJzLmxlbmd0aCA+IDApIHtcbiAgICAgIHNxbHMucHVzaChcbiAgICAgICAgYElOU0VSVCBJTlRPICR7b3B0aW9ucy5xdW90ZVRhYmxlTmFtZSh0ZW1wVGFibGVOYW1lKX0gKCR7bmV3Q29sdW1uc1NRTH0pIGAgK1xuICAgICAgICBgU0VMRUNUICR7b2xkQ29sdW1uc1NRTH0gRlJPTSAke29wdGlvbnMucXVvdGVUYWJsZU5hbWUob3JpZ2luYWxUYWJsZU5hbWUpfWBcbiAgICAgIClcbiAgICB9XG5cbiAgICBzcWxzLnB1c2goYERST1AgVEFCTEUgJHtvcHRpb25zLnF1b3RlVGFibGVOYW1lKG9yaWdpbmFsVGFibGVOYW1lKX1gKVxuICAgIHNxbHMucHVzaChgQUxURVIgVEFCTEUgJHtvcHRpb25zLnF1b3RlVGFibGVOYW1lKHRlbXBUYWJsZU5hbWUpfSBSRU5BTUUgVE8gJHtvcHRpb25zLnF1b3RlVGFibGVOYW1lKG9yaWdpbmFsVGFibGVOYW1lKX1gKVxuXG4gICAgZm9yIChjb25zdCB0YWJsZURhdGFJbmRleCBvZiB0YXJnZXRUYWJsZURhdGEuZ2V0SW5kZXhlcygpKSB7XG4gICAgICBjb25zdCBjcmVhdGVJbmRleFNRTHMgPSBhd2FpdCBuZXcgQ3JlYXRlSW5kZXhCYXNlKHtcbiAgICAgICAgY29sdW1uczogdGFibGVEYXRhSW5kZXguZ2V0Q29sdW1ucygpLFxuICAgICAgICBkcml2ZXIsXG4gICAgICAgIG5hbWU6IHRhYmxlRGF0YUluZGV4LmdldE5hbWUoKSxcbiAgICAgICAgdGFibGVOYW1lOiBvcmlnaW5hbFRhYmxlTmFtZSxcbiAgICAgICAgdW5pcXVlOiB0YWJsZURhdGFJbmRleC5nZXRVbmlxdWUoKVxuICAgICAgfSkudG9TUUxzKClcblxuICAgICAgZm9yIChjb25zdCBzcWwgb2YgY3JlYXRlSW5kZXhTUUxzKSBzcWxzLnB1c2goc3FsKVxuICAgIH1cblxuICAgIHJldHVybiBzcWxzXG4gIH1cbn1cbiJdfQ==
@@ -73,11 +73,40 @@ export default class VelociousDatabaseMigration {
73
73
  unique?: boolean | undefined;
74
74
  }): Promise<void>;
75
75
  /**
76
- * @param {string} tableName - Table name.
77
- * @param {string} referenceName - Reference name.
76
+ * @typedef {object} AddForeignKeyArgsType
77
+ * @property {string} [columnName] - Override the derived FK column name (default: `${reference_underscored}_id`).
78
+ * @property {string} [name] - Override the derived constraint name (default: `fk_${tableName}_${referenceName}`).
79
+ * @property {string} [referencedColumnName] - Override the referenced column name (default: `id`).
80
+ * @property {string} [referencedTableName] - Override the derived referenced table (default: pluralized `referenceName`).
81
+ */
82
+ /**
83
+ * @param {string} tableName - Table the FK lives on.
84
+ * @param {string} referenceName - Singular reference name. Defaults derive
85
+ * the FK column as `${reference}_id`, the referenced table by pluralizing
86
+ * the reference, the referenced column as `id`, and the constraint name
87
+ * as `fk_${tableName}_${referenceName}`. Override any of those via `args`
88
+ * when the schema doesn't follow the convention.
89
+ * @param {AddForeignKeyArgsType} [args] - Optional overrides.
78
90
  * @returns {Promise<void>} - Resolves when complete.
79
91
  */
80
- addForeignKey(tableName: string, referenceName: string): Promise<void>;
92
+ addForeignKey(tableName: string, referenceName: string, args?: {
93
+ /**
94
+ * - Override the derived FK column name (default: `${reference_underscored}_id`).
95
+ */
96
+ columnName?: string | undefined;
97
+ /**
98
+ * - Override the derived constraint name (default: `fk_${tableName}_${referenceName}`).
99
+ */
100
+ name?: string | undefined;
101
+ /**
102
+ * - Override the referenced column name (default: `id`).
103
+ */
104
+ referencedColumnName?: string | undefined;
105
+ /**
106
+ * - Override the derived referenced table (default: pluralized `referenceName`).
107
+ */
108
+ referencedTableName?: string | undefined;
109
+ }): Promise<void>;
81
110
  /**
82
111
  * @param {string} tableName - Table name.
83
112
  * @param {string} referenceName - Reference name.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/database/migration/index.js"],"names":[],"mappings":"AA+BA;IACE;;;OAGG;IACH,wCAHW,MAAM,EAAE,GACN,IAAI,CAIhB;IAED,mEAAmE;IACnE,iCADc,MAAM,EAAE,GAAG,SAAS,CAGjC;IAED;;;;;OAKG;IACH,uDAJG;QAAuD,aAAa,EAA5D,OAAO,wBAAwB,EAAE,OAAO;QAC3B,kBAAkB,EAA/B,MAAM;QACqC,EAAE,EAA7C,OAAO,oBAAoB,EAAE,OAAO;KAC9C,EAQA;IAHC,wDAAkC;IAClC,4BAA6C;IAC7C,0CAAa;IAGf,iCAIC;IAED,qEAAqE;IACrE,aADc,OAAO,oBAAoB,EAAE,OAAO,CACnB;IAC/B,mDAAwC;IAExC,wBAEC;IAED,oBAEC;IAED,sBAEC;IAED;;;OAGG;IACH,aAHW,MAAM,GACJ,OAAO,CAAC,OAAO,oBAAoB,EAAE,eAAe,CAAC,CAIjE;IAED;;;;;;OAMG;IACH,qBANW,MAAM,cACN,MAAM,cACN,MAAM,SACN,iBAAiB,GACf,OAAO,CAAC,IAAI,CAAC,CAezB;IAED;;;;OAIG;IACH,wBAJW,MAAM,cACN,MAAM,GACJ,OAAO,CAAC,IAAI,CAAC,CAazB;IAED;;;;;OAKG;IACH;;;;;OAKG;IACH,oBALW,MAAM,WACN,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,OAAO,+BAA+B,EAAE,OAAO,CAAC;;;;;;;;;;;;;QAEtE,OAAO,CAAC,IAAI,CAAC,CAgBzB;IAED;;;;OAIG;IACH,yBAJW,MAAM,iBACN,MAAM,GACJ,OAAO,CAAC,IAAI,CAAC,CAkBzB;IAED;;;;;;;;;OASG;IACH,wBATW,MAAM,iBACN,MAAM,QAEd;QAAuB,UAAU;QACV,IAAI;QACL,IAAI;QACH,MAAM;KAC7B,GAAU,OAAO,CAAC,IAAI,CAAC,CAiBzB;IAED;;;;OAIG;IACH,2BAJW,MAAM,iBACN,MAAM,GACJ,OAAO,CAAC,IAAI,CAAC,CAMzB;IAED;;;;;OAKG;IACH,4BALW,MAAM,cACN,MAAM,YACN,OAAO,GACL,OAAO,CAAC,IAAI,CAAC,CAYzB;IAED;;;;OAIG;IACH,wBAJW,MAAM,cACN,MAAM,GACJ,OAAO,CAAC,OAAO,CAAC,CAc5B;;;;;;;IAGE,uBACQ,MAAM,YACN,uBAAuB,GACrB,OAAO,CAAC,IAAI,CAAC,CACzB;;;;;;;;IAEE,uBACQ,MAAM,QACN,mBAAmB,YACnB,uBAAuB,GACrB,OAAO,CAAC,IAAI,CAAC,CACzB;IA0ED;;;OAGG;IACH,qBAHW,MAAM,GACJ,OAAO,CAAC,IAAI,CAAC,CAIzB;IAED;;;;;OAKG;IACH,wBALW,MAAM,iBACN,MAAM,iBACN,MAAM,GACJ,OAAO,CAAC,IAAI,CAAC,CAIzB;IAED;;;OAGG;IACH,uBAHW,MAAM,GACJ,OAAO,CAAC,OAAO,CAAC,CAM5B;CACF;;;;;cA7Wa,GAAG;;;;;;;;;gBAEgB,OAAO;;;;;;;;;;;;;;;;;;;cAO1B,GAAG;;;;;;;;;;;;sCAQJ,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI;AAMvC;CAA0C;sBADpB,wBAAwB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/database/migration/index.js"],"names":[],"mappings":"AA+BA;IACE;;;OAGG;IACH,wCAHW,MAAM,EAAE,GACN,IAAI,CAIhB;IAED,mEAAmE;IACnE,iCADc,MAAM,EAAE,GAAG,SAAS,CAGjC;IAED;;;;;OAKG;IACH,uDAJG;QAAuD,aAAa,EAA5D,OAAO,wBAAwB,EAAE,OAAO;QAC3B,kBAAkB,EAA/B,MAAM;QACqC,EAAE,EAA7C,OAAO,oBAAoB,EAAE,OAAO;KAC9C,EAQA;IAHC,wDAAkC;IAClC,4BAA6C;IAC7C,0CAAa;IAGf,iCAIC;IAED,qEAAqE;IACrE,aADc,OAAO,oBAAoB,EAAE,OAAO,CACnB;IAC/B,mDAAwC;IAExC,wBAEC;IAED,oBAEC;IAED,sBAEC;IAED;;;OAGG;IACH,aAHW,MAAM,GACJ,OAAO,CAAC,OAAO,oBAAoB,EAAE,eAAe,CAAC,CAIjE;IAED;;;;;;OAMG;IACH,qBANW,MAAM,cACN,MAAM,cACN,MAAM,SACN,iBAAiB,GACf,OAAO,CAAC,IAAI,CAAC,CAezB;IAED;;;;OAIG;IACH,wBAJW,MAAM,cACN,MAAM,GACJ,OAAO,CAAC,IAAI,CAAC,CAazB;IAED;;;;;OAKG;IACH;;;;;OAKG;IACH,oBALW,MAAM,WACN,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,OAAO,+BAA+B,EAAE,OAAO,CAAC;;;;;;;;;;;;;QAEtE,OAAO,CAAC,IAAI,CAAC,CAgBzB;IAED;;;;;;OAMG;IACH;;;;;;;;;OASG;IACH,yBATW,MAAM,iBACN,MAAM;;;;;;;;;;;;;;;;;QAMJ,OAAO,CAAC,IAAI,CAAC,CAuBzB;IAED;;;;;;;;;OASG;IACH,wBATW,MAAM,iBACN,MAAM,QAEd;QAAuB,UAAU;QACV,IAAI;QACL,IAAI;QACH,MAAM;KAC7B,GAAU,OAAO,CAAC,IAAI,CAAC,CAiBzB;IAED;;;;OAIG;IACH,2BAJW,MAAM,iBACN,MAAM,GACJ,OAAO,CAAC,IAAI,CAAC,CAMzB;IAED;;;;;OAKG;IACH,4BALW,MAAM,cACN,MAAM,YACN,OAAO,GACL,OAAO,CAAC,IAAI,CAAC,CAYzB;IAED;;;;OAIG;IACH,wBAJW,MAAM,cACN,MAAM,GACJ,OAAO,CAAC,OAAO,CAAC,CAc5B;;;;;;;IAGE,uBACQ,MAAM,YACN,uBAAuB,GACrB,OAAO,CAAC,IAAI,CAAC,CACzB;;;;;;;;IAEE,uBACQ,MAAM,QACN,mBAAmB,YACnB,uBAAuB,GACrB,OAAO,CAAC,IAAI,CAAC,CACzB;IA0ED;;;OAGG;IACH,qBAHW,MAAM,GACJ,OAAO,CAAC,IAAI,CAAC,CAIzB;IAED;;;;;OAKG;IACH,wBALW,MAAM,iBACN,MAAM,iBACN,MAAM,GACJ,OAAO,CAAC,IAAI,CAAC,CAIzB;IAED;;;OAGG;IACH,uBAHW,MAAM,GACJ,OAAO,CAAC,OAAO,CAAC,CAM5B;CACF;;;;;cA9Xa,GAAG;;;;;;;;;gBAEgB,OAAO;;;;;;;;;;;;;;;;;;;cAO1B,GAAG;;;;;;;;;;;;sCAQJ,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI;AAMvC;CAA0C;sBADpB,wBAAwB"}