@h3ravel/arquebus 2.0.0 → 3.0.1

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.
Files changed (47) hide show
  1. package/README.md +1 -1
  2. package/bin/index.cjs +554 -420
  3. package/bin/index.js +542 -408
  4. package/dist/browser/index.cjs +54 -51
  5. package/dist/browser/index.d.ts +804 -737
  6. package/dist/browser/index.js +48 -44
  7. package/dist/concerns/index.cjs +152 -143
  8. package/dist/concerns/index.d.ts +849 -776
  9. package/dist/concerns/index.js +143 -133
  10. package/dist/index.cjs +186 -185
  11. package/dist/index.d.ts +856 -782
  12. package/dist/index.js +179 -177
  13. package/dist/inspector/index.cjs +175 -174
  14. package/dist/inspector/index.d.ts +0 -1
  15. package/dist/inspector/index.js +161 -159
  16. package/dist/migrations/index.cjs +183 -182
  17. package/dist/migrations/index.d.ts +799 -727
  18. package/dist/migrations/index.js +172 -170
  19. package/dist/relations/index.cjs +152 -143
  20. package/dist/relations/index.d.ts +835 -762
  21. package/dist/relations/index.js +143 -133
  22. package/dist/seeders/index.cjs +7 -5
  23. package/dist/seeders/index.d.ts +797 -724
  24. package/dist/seeders/index.js +8 -6
  25. package/dist/{migrations/stubs/stubs → stubs}/migration-js.stub +1 -0
  26. package/dist/{migrations/stubs/stubs → stubs}/migration-ts.stub +1 -0
  27. package/dist/{migrations/stubs/stubs → stubs}/migration.create-js.stub +1 -0
  28. package/dist/{migrations/stubs/stubs → stubs}/migration.create-ts.stub +1 -0
  29. package/dist/{migrations/stubs/stubs → stubs}/migration.update-js.stub +1 -0
  30. package/dist/{migrations/stubs/stubs → stubs}/migration.update-ts.stub +1 -0
  31. package/dist/stubs/model-ts.stub +9 -0
  32. package/package.json +31 -31
  33. package/types/builder.ts +1 -1
  34. package/types/cli.ts +20 -0
  35. package/types/database.ts +69 -0
  36. package/types/index.ts +4 -0
  37. package/types/model-builder.ts +132 -0
  38. package/types/query-builder.ts +0 -1
  39. package/types/query-methods.ts +0 -1
  40. package/types/schema.ts +92 -0
  41. package/types/utils.ts +1 -40
  42. package/dist/stubs/stubs/model-ts.stub +0 -5
  43. /package/dist/stubs/{stubs/arquebus.config-js.stub → arquebus.config-js.stub} +0 -0
  44. /package/dist/stubs/{stubs/arquebus.config-ts.stub → arquebus.config-ts.stub} +0 -0
  45. /package/dist/stubs/{stubs/model-js.stub → model-js.stub} +0 -0
  46. /package/dist/stubs/{stubs/seeder-js.stub → seeder-js.stub} +0 -0
  47. /package/dist/stubs/{stubs/seeder-ts.stub → seeder-ts.stub} +0 -0
package/bin/index.js CHANGED
@@ -1,19 +1,19 @@
1
1
  #!/usr/bin/env node
2
- import { Argument, Option, program } from "commander";
3
- import { FileSystem, Logger, TaskManager } from "@h3ravel/shared";
2
+ import { Application, Command, Kernel } from "@h3ravel/musket";
3
+ import { FileSystem, Logger, TaskManager, importFile } from "@h3ravel/shared";
4
4
  import path from "path";
5
5
  import resolveFrom from "resolve-from";
6
6
  import fs, { access, copyFile, mkdir, readFile, readdir, writeFile } from "node:fs/promises";
7
- import { dirname } from "node:path";
7
+ import path$1, { dirname } from "node:path";
8
+ import { existsSync } from "node:fs";
8
9
  import { fileURLToPath } from "node:url";
9
- import { assign, camel, diff, flat, get, isArray, isEmpty, isEqual, isString, omit, pick, set, snake, trim } from "radashi";
10
- import advancedFormat from "dayjs/plugin/advancedFormat.js";
11
- import dayjs from "dayjs";
12
- import collect, { Collection, collect as collect$1 } from "collect.js";
10
+ import { Arr, Obj, Str, data_get, data_set } from "@h3ravel/support";
11
+ import * as dayjsModule from "dayjs";
12
+ import * as advancedFormatModule from "dayjs/plugin/advancedFormat.js";
13
+ import { Collection, collect } from "@h3ravel/collect.js";
13
14
  import Knex from "knex";
14
- import { existsSync } from "fs";
15
+ import { existsSync as existsSync$1 } from "fs";
15
16
  import pluralize from "pluralize";
16
- import { Str } from "@h3ravel/support";
17
17
  import { config } from "dotenv";
18
18
  //#region \0rolldown/runtime.js
19
19
  var __defProp = Object.defineProperty;
@@ -61,6 +61,169 @@ var TableGuesser = class TableGuesser {
61
61
  }
62
62
  };
63
63
  //#endregion
64
+ //#region src/cli/commands.ts
65
+ var ArquebusCommand = class extends Command {
66
+ pathOption(signature) {
67
+ return signature.option("path", {
68
+ short: "p",
69
+ optionalValue: true,
70
+ description: "The path used by the command."
71
+ });
72
+ }
73
+ };
74
+ var InitCommand = class extends ArquebusCommand {
75
+ buildSignature(signature) {
76
+ return signature.command("init").describe("Create a fresh Arquebus config.").argument("type", {
77
+ required: false,
78
+ default: "js",
79
+ choices: ["js", "ts"],
80
+ description: "Type of config to generate."
81
+ });
82
+ }
83
+ async handle() {
84
+ await this.app.initialize(this.argument("type", "js"));
85
+ }
86
+ };
87
+ var MakeMigrationCommand = class extends ArquebusCommand {
88
+ buildSignature(signature) {
89
+ return this.pathOption(signature.command("make:migration").describe("Create a new migration file.").argument("name", { description: "The migration name." }).option("type", {
90
+ short: "l",
91
+ default: "js",
92
+ choices: ["js", "ts"],
93
+ description: "Type of migration file to generate."
94
+ }).option("table", {
95
+ short: "t",
96
+ optionalValue: true,
97
+ description: "The table to migrate."
98
+ }).option("create", {
99
+ short: "c",
100
+ optionalValue: true,
101
+ description: "The table to create."
102
+ }));
103
+ }
104
+ async handle() {
105
+ await this.app.makeMigration(this.argument("name"), this.options());
106
+ }
107
+ };
108
+ var PublishMigrationsCommand = class extends ArquebusCommand {
109
+ buildSignature(signature) {
110
+ return this.pathOption(signature.command("migrate:publish").describe("Publish migration files from a package.").argument("package", { description: "The package to publish from." }));
111
+ }
112
+ async handle() {
113
+ await this.app.publishMigrations(this.argument("package"), this.options());
114
+ }
115
+ };
116
+ var MigrationPathCommand = class extends ArquebusCommand {
117
+ buildSignature(signature) {
118
+ return this.pathOption(signature.command(this.commandName).describe(this.commandDescription));
119
+ }
120
+ async handle() {
121
+ await this.execute(this.options());
122
+ }
123
+ };
124
+ var MigrateCommand = class extends ArquebusCommand {
125
+ buildSignature(signature) {
126
+ return this.pathOption(signature.command("migrate").describe("Run all pending migrations.").option("step", {
127
+ short: "s",
128
+ optionalValue: true,
129
+ description: "Run migrations in individual batches."
130
+ }));
131
+ }
132
+ async handle() {
133
+ await this.app.migrate(this.options());
134
+ }
135
+ };
136
+ var RollbackCommand = class extends ArquebusCommand {
137
+ buildSignature(signature) {
138
+ return this.pathOption(signature.command("migrate:rollback").describe("Rollback the last database migration.").option("step", {
139
+ short: "s",
140
+ optionalValue: true,
141
+ description: "The number of migrations to revert."
142
+ }));
143
+ }
144
+ async handle() {
145
+ await this.app.rollback(this.options());
146
+ }
147
+ };
148
+ var ResetCommand = class extends MigrationPathCommand {
149
+ commandName = "migrate:reset";
150
+ commandDescription = "Rollback all database migrations.";
151
+ execute(options) {
152
+ return this.app.reset(options);
153
+ }
154
+ };
155
+ var RefreshCommand = class extends MigrationPathCommand {
156
+ commandName = "migrate:refresh";
157
+ commandDescription = "Reset and re-run all migrations.";
158
+ execute(options) {
159
+ return this.app.refresh(options);
160
+ }
161
+ };
162
+ var FreshCommand = class extends MigrationPathCommand {
163
+ commandName = "migrate:fresh";
164
+ commandDescription = "Drop all tables and re-run all migrations.";
165
+ execute(options) {
166
+ return this.app.fresh(options);
167
+ }
168
+ };
169
+ var MigrationStatusCommand = class extends MigrationPathCommand {
170
+ commandName = "migrate:status";
171
+ commandDescription = "Show the status of each migration.";
172
+ execute(options) {
173
+ return this.app.status(options);
174
+ }
175
+ };
176
+ var SeedCommand = class extends MigrationPathCommand {
177
+ commandName = "db:seed";
178
+ commandDescription = "Run database seeders.";
179
+ execute(options) {
180
+ return this.app.seed(options);
181
+ }
182
+ };
183
+ var MakeFileCommand = class extends ArquebusCommand {
184
+ buildSignature(signature) {
185
+ return this.pathOption(signature.command(this.commandName).describe(this.commandDescription).argument("name", { description: `The ${this.fileDescription} name.` }).option("type", {
186
+ short: "l",
187
+ default: "js",
188
+ choices: ["js", "ts"],
189
+ description: `Type of ${this.fileDescription} file to generate.`
190
+ }).option("force", { description: `Overwrite an existing ${this.fileDescription} file.` }));
191
+ }
192
+ async handle() {
193
+ await this.execute(this.argument("name"), this.options());
194
+ }
195
+ };
196
+ var MakeSeederCommand = class extends MakeFileCommand {
197
+ commandName = "make:seeder";
198
+ commandDescription = "Create a new seeder file.";
199
+ fileDescription = "seeder";
200
+ execute(name, options) {
201
+ return this.app.makeSeeder(name, options);
202
+ }
203
+ };
204
+ var MakeModelCommand = class extends MakeFileCommand {
205
+ commandName = "make:model";
206
+ commandDescription = "Create a new model file.";
207
+ fileDescription = "model";
208
+ execute(name, options) {
209
+ return this.app.makeModel(name, options);
210
+ }
211
+ };
212
+ const ArquebusCommands = [
213
+ InitCommand,
214
+ MakeMigrationCommand,
215
+ PublishMigrationsCommand,
216
+ MigrateCommand,
217
+ RollbackCommand,
218
+ ResetCommand,
219
+ RefreshCommand,
220
+ FreshCommand,
221
+ MigrationStatusCommand,
222
+ SeedCommand,
223
+ MakeSeederCommand,
224
+ MakeModelCommand
225
+ ];
226
+ //#endregion
64
227
  //#region src/migrations/migration-repository.ts
65
228
  var MigrationRepository = class {
66
229
  resolver;
@@ -206,8 +369,7 @@ var CockroachDB = class {
206
369
  */
207
370
  async hasTable(table) {
208
371
  const subquery = this.knex.select().from("information_schema.tables").whereIn("table_schema", this.explodedSchema).andWhere({ table_name: table });
209
- const record = await this.knex.select(this.knex.raw("exists (?)", [subquery])).first();
210
- return (record === null || record === void 0 ? void 0 : record.exists) || false;
372
+ return (await this.knex.select(this.knex.raw("exists (?)", [subquery])).first())?.exists || false;
211
373
  }
212
374
  /**
213
375
  * Get all the available columns in the current schema/database. Can be filtered to a specific table
@@ -307,18 +469,17 @@ var CockroachDB = class {
307
469
  ${column ? "AND att.attname = ?" : ""}
308
470
  `, bindings)]);
309
471
  const parsedColumms = columns.rows.map((col) => {
310
- var _col$default_value;
311
472
  const constraintsForColumn = constraints.rows.filter((constraint) => constraint.table === col.table && constraint.column === col.name);
312
473
  const foreignKeyConstraint = constraintsForColumn.find((constraint) => constraint.type === "f");
313
474
  return {
314
475
  ...col,
315
476
  is_unique: constraintsForColumn.some((constraint) => ["u", "p"].includes(constraint.type)),
316
477
  is_primary_key: constraintsForColumn.some((constraint) => constraint.type === "p"),
317
- has_auto_increment: ["integer", "bigint"].includes(col.data_type) && (((_col$default_value = col.default_value) === null || _col$default_value === void 0 ? void 0 : _col$default_value.startsWith("nextval(")) ?? false),
478
+ has_auto_increment: ["integer", "bigint"].includes(col.data_type) && (col.default_value?.startsWith("nextval(") ?? false),
318
479
  default_value: parseDefaultValue$5(col.default_value),
319
- foreign_key_schema: (foreignKeyConstraint === null || foreignKeyConstraint === void 0 ? void 0 : foreignKeyConstraint.foreign_key_schema) ?? null,
320
- foreign_key_table: (foreignKeyConstraint === null || foreignKeyConstraint === void 0 ? void 0 : foreignKeyConstraint.foreign_key_table) ?? null,
321
- foreign_key_column: (foreignKeyConstraint === null || foreignKeyConstraint === void 0 ? void 0 : foreignKeyConstraint.foreign_key_column) ?? null
480
+ foreign_key_schema: foreignKeyConstraint?.foreign_key_schema ?? null,
481
+ foreign_key_table: foreignKeyConstraint?.foreign_key_table ?? null,
482
+ foreign_key_column: foreignKeyConstraint?.foreign_key_column ?? null
322
483
  };
323
484
  });
324
485
  if (table && column) return parsedColumms[0];
@@ -332,8 +493,7 @@ var CockroachDB = class {
332
493
  table_name: table,
333
494
  column_name: column
334
495
  });
335
- const record = await this.knex.select(this.knex.raw("exists (?)", [subquery])).first();
336
- return (record === null || record === void 0 ? void 0 : record.exists) || false;
496
+ return (await this.knex.select(this.knex.raw("exists (?)", [subquery])).first())?.exists || false;
337
497
  }
338
498
  /**
339
499
  * Get the primary key column for the given table
@@ -645,14 +805,13 @@ var MSSQL = class {
645
805
  WHERE
646
806
  OBJECT_SCHEMA_NAME (f.parent_object_id) = ?;
647
807
  `, [this.schema]);
648
- if (table) return result === null || result === void 0 ? void 0 : result.filter((row) => row.table === table);
808
+ if (table) return result?.filter((row) => row.table === table);
649
809
  return result;
650
810
  }
651
811
  };
652
812
  //#endregion
653
813
  //#region src/inspector/dialects/mysql.ts
654
814
  function rawColumnToColumn$1(rawColumn) {
655
- var _rawColumn$EXTRA;
656
815
  let dataType = rawColumn.COLUMN_TYPE.replace(/\(.*?\)/, "");
657
816
  if (rawColumn.COLUMN_TYPE.startsWith("tinyint(1)")) dataType = "boolean";
658
817
  return {
@@ -665,7 +824,7 @@ function rawColumnToColumn$1(rawColumn) {
665
824
  max_length: rawColumn.CHARACTER_MAXIMUM_LENGTH,
666
825
  numeric_precision: rawColumn.NUMERIC_PRECISION,
667
826
  numeric_scale: rawColumn.NUMERIC_SCALE,
668
- is_generated: !!((_rawColumn$EXTRA = rawColumn.EXTRA) === null || _rawColumn$EXTRA === void 0 ? void 0 : _rawColumn$EXTRA.endsWith("GENERATED")),
827
+ is_generated: !!rawColumn.EXTRA?.endsWith("GENERATED"),
669
828
  is_nullable: rawColumn.IS_NULLABLE === "YES",
670
829
  is_unique: rawColumn.COLUMN_KEY === "UNI",
671
830
  is_primary_key: rawColumn.CONSTRAINT_NAME === "PRIMARY" || rawColumn.COLUMN_KEY === "PRI",
@@ -858,11 +1017,10 @@ var oracleDB = class {
858
1017
  * Check if a table exists in the current schema/database
859
1018
  */
860
1019
  async hasTable(table) {
861
- const result = await this.knex.select(this.knex.raw(`
1020
+ return !!(await this.knex.select(this.knex.raw(`
862
1021
  /*+ OPTIMIZER_FEATURES_ENABLE('${OPTIMIZER_FEATURES}') */
863
1022
  COUNT(*) "count"
864
- `)).from("USER_TABLES").where({ TABLE_NAME: table }).first();
865
- return !!(result === null || result === void 0 ? void 0 : result.count);
1023
+ `)).from("USER_TABLES").where({ TABLE_NAME: table }).first())?.count;
866
1024
  }
867
1025
  /**
868
1026
  * Get all the available columns in the current schema/database. Can be filtered to a specific table
@@ -938,15 +1096,14 @@ var oracleDB = class {
938
1096
  * Check if a table exists in the current schema/database
939
1097
  */
940
1098
  async hasColumn(table, column) {
941
- const result = await this.knex.select(this.knex.raw(`
1099
+ return !!(await this.knex.select(this.knex.raw(`
942
1100
  /*+ OPTIMIZER_FEATURES_ENABLE('${OPTIMIZER_FEATURES}') NO_QUERY_TRANSFORMATION */
943
1101
  COUNT(*) "count"
944
1102
  `)).from("USER_TAB_COLS").where({
945
1103
  TABLE_NAME: table,
946
1104
  COLUMN_NAME: column,
947
1105
  HIDDEN_COLUMN: "NO"
948
- }).first();
949
- return !!(result === null || result === void 0 ? void 0 : result.count);
1106
+ }).first())?.count;
950
1107
  }
951
1108
  /**
952
1109
  * Get the primary key column for the given table
@@ -1112,13 +1269,12 @@ var Postgres = class {
1112
1269
  `, bindings)).rows;
1113
1270
  }
1114
1271
  async columnInfo(table, column) {
1115
- var _versionResponse$rows;
1116
1272
  const { knex } = this;
1117
1273
  const bindings = [];
1118
1274
  if (table) bindings.push(table);
1119
1275
  if (column) bindings.push(column);
1120
1276
  const schemaIn = this.explodedSchema.map((schemaName) => `${this.knex.raw("?", [schemaName])}::regnamespace`);
1121
- const majorVersion = ((_versionResponse$rows = (await this.knex.raw("SHOW server_version")).rows) === null || _versionResponse$rows === void 0 || (_versionResponse$rows = _versionResponse$rows[0]) === null || _versionResponse$rows === void 0 || (_versionResponse$rows = _versionResponse$rows.server_version) === null || _versionResponse$rows === void 0 || (_versionResponse$rows = _versionResponse$rows.split(".")) === null || _versionResponse$rows === void 0 ? void 0 : _versionResponse$rows[0]) ?? 10;
1277
+ const majorVersion = (await this.knex.raw("SHOW server_version")).rows?.[0]?.server_version?.split(".")?.[0] ?? 10;
1122
1278
  let generationSelect = `
1123
1279
  NULL AS generation_expression,
1124
1280
  pg_get_expr(ad.adbin, ad.adrelid) AS default_value,
@@ -1210,9 +1366,9 @@ var Postgres = class {
1210
1366
  is_primary_key: constraintsForColumn.some((constraint) => constraint.type === "p"),
1211
1367
  has_auto_increment: constraintsForColumn.some((constraint) => constraint.has_auto_increment),
1212
1368
  default_value: parseDefaultValue$1(col.default_value),
1213
- foreign_key_schema: (foreignKeyConstraint === null || foreignKeyConstraint === void 0 ? void 0 : foreignKeyConstraint.foreign_key_schema) ?? null,
1214
- foreign_key_table: (foreignKeyConstraint === null || foreignKeyConstraint === void 0 ? void 0 : foreignKeyConstraint.foreign_key_table) ?? null,
1215
- foreign_key_column: (foreignKeyConstraint === null || foreignKeyConstraint === void 0 ? void 0 : foreignKeyConstraint.foreign_key_column) ?? null
1369
+ foreign_key_schema: foreignKeyConstraint?.foreign_key_schema ?? null,
1370
+ foreign_key_table: foreignKeyConstraint?.foreign_key_table ?? null,
1371
+ foreign_key_column: foreignKeyConstraint?.foreign_key_column ?? null
1216
1372
  };
1217
1373
  });
1218
1374
  if (table && column) return parsedColumms[0];
@@ -1384,16 +1540,14 @@ var SeederRunner = class {
1384
1540
  this.resolver = resolver;
1385
1541
  }
1386
1542
  path(p) {
1387
- this.paths = Array.from(new Set([...this.paths, p]));
1543
+ this.paths = Array.from(/* @__PURE__ */ new Set([...this.paths, p]));
1388
1544
  }
1389
1545
  getPaths() {
1390
1546
  return this.paths;
1391
1547
  }
1392
1548
  resolveConnection(connection) {
1393
- var _getInstance, _ref, _instance$connections;
1394
1549
  const name = connection || this.connection || "default";
1395
- const instance = ((_getInstance = (_ref = this.resolver).getInstance) === null || _getInstance === void 0 ? void 0 : _getInstance.call(_ref)) ?? null;
1396
- if (!!!(instance === null || instance === void 0 || (_instance$connections = instance.connections) === null || _instance$connections === void 0 ? void 0 : _instance$connections[name])) this.resolver.autoLoad().catch(() => {
1550
+ if (!!!(this.resolver.getInstance?.() ?? null)?.connections?.[name]) this.resolver.autoLoad().catch(() => {
1397
1551
  /** noop */
1398
1552
  });
1399
1553
  return this.resolver.fire(name);
@@ -1431,9 +1585,6 @@ var SeederRunner = class {
1431
1585
  }
1432
1586
  };
1433
1587
  //#endregion
1434
- //#region src/seeders/index.ts
1435
- var seeders_exports = /* @__PURE__ */ __exportAll({ SeederRunner: () => SeederRunner });
1436
- //#endregion
1437
1588
  //#region src/casts/attribute.ts
1438
1589
  var Attribute = class Attribute {
1439
1590
  get;
@@ -1483,7 +1634,7 @@ var ModelNotFoundError = class extends BaseError {
1483
1634
  }
1484
1635
  setModel(model, ids = []) {
1485
1636
  this.model = model;
1486
- this.ids = isArray(ids) ? ids : [ids];
1637
+ this.ids = Array.isArray(ids) ? ids : [ids];
1487
1638
  this.message = `No query results for model [${model}]`;
1488
1639
  if (this.ids.length > 0) this.message += " " + this.ids.join(", ");
1489
1640
  else this.message += ".";
@@ -1574,25 +1725,29 @@ function compose$1(Base, ...mixins) {
1574
1725
  }, Base);
1575
1726
  }
1576
1727
  //#endregion
1577
- //#region src/utils.ts
1728
+ //#region src/dayjs.ts
1729
+ const dayjs = dayjsModule.default ?? dayjsModule;
1730
+ const advancedFormat = advancedFormatModule.default ?? advancedFormatModule;
1578
1731
  dayjs.extend(advancedFormat);
1732
+ //#endregion
1733
+ //#region src/utils.ts
1579
1734
  const getRelationName = (relationMethod) => {
1580
- return snake(relationMethod.substring(8));
1735
+ return Str.snake(relationMethod.substring(8));
1581
1736
  };
1582
1737
  const getRelationMethod = (relation) => {
1583
- return camel(`relation_${relation}`);
1738
+ return Str.camel(`relation_${relation}`);
1584
1739
  };
1585
1740
  const getScopeMethod = (scope) => {
1586
- return camel(`scope_${scope}`);
1741
+ return Str.camel(`scope_${scope}`);
1587
1742
  };
1588
1743
  const getAttrMethod = (attr) => {
1589
- return camel(`attribute_${attr}`);
1744
+ return Str.camel(`attribute_${attr}`);
1590
1745
  };
1591
1746
  const getGetterMethod = (attr) => {
1592
- return camel(`get_${attr}_attribute`);
1747
+ return Str.camel(`get_${attr}_attribute`);
1593
1748
  };
1594
1749
  const getSetterMethod = (attr) => {
1595
- return camel(`set_${attr}_attribute`);
1750
+ return Str.camel(`set_${attr}_attribute`);
1596
1751
  };
1597
1752
  /**
1598
1753
  * Tap into a model a collection instance
@@ -1608,7 +1763,7 @@ const tap = (instance, callback) => {
1608
1763
  const { compose } = mixin_exports;
1609
1764
  const flatten = (arr) => arr.flat();
1610
1765
  const flattenDeep = (arr) => Array.isArray(arr) ? arr.reduce((a, b) => a.concat(flattenDeep(b)), []) : [arr];
1611
- const snakeCase = (str) => trim(snake(str.replace(/[^a-zA-Z0-9_-]/g, "-")), "_-");
1766
+ const snakeCase = (str) => Str.trim(Str.snake(str.replace(/[^a-zA-Z0-9_-]/g, "-")), "_-").replace(/_+/g, "_");
1612
1767
  //#endregion
1613
1768
  //#region src/relations/relation.ts
1614
1769
  var Relation = class {
@@ -1695,8 +1850,7 @@ var Relation = class {
1695
1850
  return this.parent.getQualifiedKeyName();
1696
1851
  }
1697
1852
  getExistenceCompareKey() {
1698
- var _this$getQualifiedFor;
1699
- return (_this$getQualifiedFor = this.getQualifiedForeignKeyName) === null || _this$getQualifiedFor === void 0 ? void 0 : _this$getQualifiedFor.call(this);
1853
+ return this.getQualifiedForeignKeyName?.();
1700
1854
  }
1701
1855
  };
1702
1856
  //#endregion
@@ -1837,8 +1991,7 @@ const HasAttributes = (Model) => {
1837
1991
  return this;
1838
1992
  }
1839
1993
  normalizeCastClassResponse(key, value) {
1840
- var _value$constructor;
1841
- return (value === null || value === void 0 || (_value$constructor = value.constructor) === null || _value$constructor === void 0 ? void 0 : _value$constructor.name) === "Object" ? value : { [key]: value };
1994
+ return value?.constructor?.name === "Object" ? value : { [key]: value };
1842
1995
  }
1843
1996
  syncOriginal() {
1844
1997
  this.original = this.getAttributes();
@@ -1963,8 +2116,8 @@ const HasAttributes = (Model) => {
1963
2116
  attributesToData() {
1964
2117
  let attributes = { ...this.attributes };
1965
2118
  for (const key in attributes) {
1966
- if (this.hidden.includes(key)) attributes = omit(attributes, [key]);
1967
- if (this.visible.length > 0 && this.visible.includes(key) === false) attributes = omit(attributes, [key]);
2119
+ if (this.hidden.includes(key)) attributes = Arr.except(attributes, [key]);
2120
+ if (this.visible.length > 0 && this.visible.includes(key) === false) attributes = Arr.except(attributes, [key]);
1968
2121
  }
1969
2122
  for (const key of this.getDates()) {
1970
2123
  if (attributes[key] === void 0) continue;
@@ -2019,7 +2172,7 @@ const HasAttributes = (Model) => {
2019
2172
  }
2020
2173
  hasCast(key, types = []) {
2021
2174
  if (key in this.casts) {
2022
- types = flat(types);
2175
+ types = flatten(types);
2023
2176
  return types.length > 0 ? types.includes(this.getCastType(key)) : true;
2024
2177
  }
2025
2178
  return false;
@@ -2078,10 +2231,14 @@ const HasGlobalScopes = (Model) => {
2078
2231
  static globalScopes;
2079
2232
  static addGlobalScope(scope, implementation = null) {
2080
2233
  if (typeof scope === "string" && implementation instanceof Scope) {
2081
- this.globalScopes = set(this.globalScopes ?? {}, this.name + "." + scope, implementation);
2234
+ const scopes = this.globalScopes ?? {};
2235
+ data_set(scopes, this.name + "." + scope, implementation);
2236
+ this.globalScopes = scopes;
2082
2237
  return implementation;
2083
2238
  } else if (scope instanceof Scope) {
2084
- this.globalScopes = set(this.globalScopes ?? {}, this.name + "." + scope.constructor.name, scope);
2239
+ const scopes = this.globalScopes ?? {};
2240
+ data_set(scopes, this.name + "." + scope.constructor.name, scope);
2241
+ this.globalScopes = scopes;
2085
2242
  return scope;
2086
2243
  }
2087
2244
  throw new InvalidArgumentError("Global scope must be an instance of Scope.");
@@ -2090,8 +2247,8 @@ const HasGlobalScopes = (Model) => {
2090
2247
  return this.getGlobalScope(scope) !== null;
2091
2248
  }
2092
2249
  static getGlobalScope(scope) {
2093
- if (typeof scope === "string") return get(this.globalScopes, this.name + "." + scope);
2094
- return get(this.globalScopes, this.name + "." + scope.constructor.name);
2250
+ if (typeof scope === "string") return data_get(this.globalScopes ?? {}, this.name + "." + scope);
2251
+ return data_get(this.globalScopes ?? {}, this.name + "." + scope.constructor.name);
2095
2252
  }
2096
2253
  static getAllGlobalScopes() {
2097
2254
  return this.globalScopes;
@@ -2100,7 +2257,7 @@ const HasGlobalScopes = (Model) => {
2100
2257
  this.globalScopes = scopes;
2101
2258
  }
2102
2259
  getGlobalScopes() {
2103
- return get(this.constructor.globalScopes, this.constructor.name, {});
2260
+ return data_get(this.constructor.globalScopes ?? {}, this.constructor.name, {});
2104
2261
  }
2105
2262
  };
2106
2263
  };
@@ -2271,13 +2428,11 @@ var HasMany = class extends compose(Relation, HasOneOrMany) {
2271
2428
  return this.getParentKey() !== null ? await this.query.get() : new Collection$1([]);
2272
2429
  }
2273
2430
  getForeignKeyName() {
2274
- var _this$foreignKey;
2275
- const segments = (_this$foreignKey = this.foreignKey) === null || _this$foreignKey === void 0 ? void 0 : _this$foreignKey.split(".");
2276
- return segments === null || segments === void 0 ? void 0 : segments.pop();
2431
+ return (this.foreignKey?.split("."))?.pop();
2277
2432
  }
2278
2433
  buildDictionary(results) {
2279
2434
  const foreign = this.getForeignKeyName();
2280
- return collect$1(results).mapToDictionary((result) => [result[foreign], result]).all();
2435
+ return collect(results).mapToDictionary((result) => [result[foreign], result]).all();
2281
2436
  }
2282
2437
  match(models, results, relation) {
2283
2438
  return this.matchOneOrMany(models, results, relation, "many");
@@ -2308,9 +2463,7 @@ var HasOne = class extends compose(Relation, HasOneOrMany, SupportsDefaultModels
2308
2463
  return this.matchOneOrMany(models, results, relation, "one");
2309
2464
  }
2310
2465
  getForeignKeyName() {
2311
- var _this$foreignKey;
2312
- const segments = (_this$foreignKey = this.foreignKey) === null || _this$foreignKey === void 0 ? void 0 : _this$foreignKey.split(".");
2313
- return segments === null || segments === void 0 ? void 0 : segments.pop();
2466
+ return (this.foreignKey?.split("."))?.pop();
2314
2467
  }
2315
2468
  async getResults() {
2316
2469
  if (this.getParentKey() === null) return this.getDefaultFor(this.parent);
@@ -2419,10 +2572,10 @@ var HasManyThrough = class extends Relation {
2419
2572
  }
2420
2573
  const model = await this.first(columns);
2421
2574
  if (model) return model;
2422
- return callback === null || callback === void 0 ? void 0 : callback();
2575
+ return callback?.();
2423
2576
  }
2424
2577
  async find(id, columns = ["*"]) {
2425
- if (isArray(id)) return await this.findMany(id, columns);
2578
+ if (Array.isArray(id)) return await this.findMany(id, columns);
2426
2579
  return await this.where(this.getRelated().getQualifiedKeyName(), "=", id).first(columns);
2427
2580
  }
2428
2581
  async findMany(ids, columns = ["*"]) {
@@ -2450,7 +2603,7 @@ var HasManyThrough = class extends Relation {
2450
2603
  return await this.query.paginate(perPage ?? 15, columns, pageName, page);
2451
2604
  }
2452
2605
  shouldSelect(columns = ["*"]) {
2453
- if ((columns === null || columns === void 0 ? void 0 : columns.at(0)) == "*") columns = [this.related.getTable() + ".*"];
2606
+ if (columns?.at(0) == "*") columns = [this.related.getTable() + ".*"];
2454
2607
  return [...columns, this.getQualifiedFirstKeyName() + " as laravel_through_key"];
2455
2608
  }
2456
2609
  async chunk(count, callback) {
@@ -2544,7 +2697,7 @@ const HasRelations = (Model) => {
2544
2697
  return this;
2545
2698
  }
2546
2699
  unsetRelation(relation) {
2547
- this.relations = omit(this.relations, [relation]);
2700
+ this.relations = Arr.except(this.relations, [relation]);
2548
2701
  return this;
2549
2702
  }
2550
2703
  relationLoaded(relation) {
@@ -2567,8 +2720,7 @@ const HasRelations = (Model) => {
2567
2720
  return data;
2568
2721
  }
2569
2722
  guessBelongsToRelation() {
2570
- var _e$stack;
2571
- const functionName = (((_e$stack = (/* @__PURE__ */ new Error()).stack) === null || _e$stack === void 0 ? void 0 : _e$stack.split("\n")[2]) ?? "").split(" ")[5];
2723
+ const functionName = ((/* @__PURE__ */ new Error()).stack?.split("\n")[2] ?? "").split(" ")[5];
2572
2724
  return getRelationName(functionName);
2573
2725
  }
2574
2726
  joiningTable(related, instance = null) {
@@ -2678,7 +2830,7 @@ const HidesAttributes = (Model) => {
2678
2830
  makeVisible(...keys) {
2679
2831
  const visible = flattenDeep(keys);
2680
2832
  if (this.visible.length > 0) this.visible = [...this.visible, ...visible];
2681
- this.hidden = diff(this.hidden, visible);
2833
+ this.hidden = collect(this.hidden).diff(visible).all();
2682
2834
  return this;
2683
2835
  }
2684
2836
  makeHidden(key, ...keys) {
@@ -2822,10 +2974,9 @@ var QueryBuilder = class QueryBuilder extends Inference$1 {
2822
2974
  asProxy() {
2823
2975
  return new Proxy(this, {
2824
2976
  get: function(target, prop) {
2825
- var _target$connector$cli;
2826
2977
  if (typeof target[prop] !== "undefined") return target[prop];
2827
2978
  if (["destroy", "schema"].includes(prop)) return target.connector.schema;
2828
- const skipReturning = !!((_target$connector$cli = target.connector.client.config) === null || _target$connector$cli === void 0 || (_target$connector$cli = _target$connector$cli.client) === null || _target$connector$cli === void 0 ? void 0 : _target$connector$cli.includes("mysql")) && prop === "returning";
2979
+ const skipReturning = !!target.connector.client.config?.client?.includes("mysql") && prop === "returning";
2829
2980
  if ([
2830
2981
  "select",
2831
2982
  "from",
@@ -3028,6 +3179,9 @@ var arquebus = class arquebus {
3028
3179
  if (this.instance === null) this.instance = new arquebus();
3029
3180
  return this.instance;
3030
3181
  }
3182
+ static withSchema() {
3183
+ return this;
3184
+ }
3031
3185
  /**
3032
3186
  * Initialize a new database connection
3033
3187
  *
@@ -3116,13 +3270,13 @@ var arquebus = class arquebus {
3116
3270
  const jsPath = path.resolve("arquebus.config.js");
3117
3271
  const tsPath = path.resolve("arquebus.config.ts");
3118
3272
  const instance = this.getInstance();
3119
- if (existsSync(jsPath)) {
3120
- config = (await import(jsPath)).default;
3273
+ if (existsSync$1(jsPath)) {
3274
+ config = (await importFile(jsPath)).default;
3121
3275
  if (addConnection) instance.addConnection(config, config.client);
3122
3276
  return config;
3123
3277
  }
3124
- if (existsSync(tsPath)) if (process.env.NODE_ENV !== "production") {
3125
- config = (await import(tsPath)).default;
3278
+ if (existsSync$1(tsPath)) if (process.env.NODE_ENV !== "production") {
3279
+ config = (await importFile(tsPath)).default;
3126
3280
  if (addConnection) instance.addConnection(config, config.client);
3127
3281
  return config;
3128
3282
  } else throw new Error("arquebus.config.ts found in production without build step");
@@ -3138,7 +3292,7 @@ var arquebus = class arquebus {
3138
3292
  "cjs"
3139
3293
  ], dir);
3140
3294
  if (found) if (!found.endsWith(".ts") || process.env.NODE_ENV !== "production") {
3141
- config = (await import(found)).default;
3295
+ config = (await importFile(found)).default;
3142
3296
  if (addConnection) instance.addConnection(config, config.client);
3143
3297
  return config;
3144
3298
  } else throw new Error("arquebus.config.ts found in production without build step");
@@ -3159,7 +3313,7 @@ var arquebus = class arquebus {
3159
3313
  }
3160
3314
  async destroyAll() {
3161
3315
  await Promise.all(Object.values(this.manager).map((connection) => {
3162
- return connection === null || connection === void 0 ? void 0 : connection.destroy();
3316
+ return connection?.destroy();
3163
3317
  }));
3164
3318
  }
3165
3319
  createModel(name, options = {}) {
@@ -3168,29 +3322,25 @@ var arquebus = class arquebus {
3168
3322
  this.models = {
3169
3323
  ...this.models,
3170
3324
  [name]: class extends BaseModel {
3171
- table = (options === null || options === void 0 ? void 0 : options.table) ?? null;
3172
- connection = (options === null || options === void 0 ? void 0 : options.connection) ?? null;
3173
- timestamps = (options === null || options === void 0 ? void 0 : options.timestamps) ?? true;
3174
- primaryKey = (options === null || options === void 0 ? void 0 : options.primaryKey) ?? "id";
3175
- keyType = (options === null || options === void 0 ? void 0 : options.keyType) ?? "int";
3176
- incrementing = (options === null || options === void 0 ? void 0 : options.incrementing) ?? true;
3177
- with = (options === null || options === void 0 ? void 0 : options.with) ?? [];
3178
- casts = (options === null || options === void 0 ? void 0 : options.casts) ?? {};
3179
- static CREATED_AT = (options === null || options === void 0 ? void 0 : options.CREATED_AT) ?? "created_at";
3180
- static UPDATED_AT = (options === null || options === void 0 ? void 0 : options.UPDATED_AT) ?? "updated_at";
3181
- static DELETED_AT = (options === null || options === void 0 ? void 0 : options.DELETED_AT) ?? "deleted_at";
3325
+ table = options?.table ?? null;
3326
+ connection = options?.connection ?? null;
3327
+ timestamps = options?.timestamps ?? true;
3328
+ primaryKey = options?.primaryKey ?? "id";
3329
+ keyType = options?.keyType ?? "int";
3330
+ incrementing = options?.incrementing ?? true;
3331
+ with = options?.with ?? [];
3332
+ casts = options?.casts ?? {};
3333
+ static CREATED_AT = options?.CREATED_AT ?? "created_at";
3334
+ static UPDATED_AT = options?.UPDATED_AT ?? "updated_at";
3335
+ static DELETED_AT = options?.DELETED_AT ?? "deleted_at";
3182
3336
  }
3183
3337
  };
3184
3338
  if ("attributes" in options) for (const attribute in options.attributes) {
3185
3339
  if (options.attributes[attribute] instanceof Attribute === false) throw new Error("Attribute must be an instance of \"Attribute\"");
3186
- this.models[name].prototype[getAttrMethod(attribute)] = () => {
3187
- var _options$attributes;
3188
- return (_options$attributes = options.attributes) === null || _options$attributes === void 0 ? void 0 : _options$attributes[attribute];
3189
- };
3340
+ this.models[name].prototype[getAttrMethod(attribute)] = () => options.attributes?.[attribute];
3190
3341
  }
3191
3342
  if ("relations" in options) for (const relation in options.relations) this.models[name].prototype[getRelationMethod(relation)] = function() {
3192
- var _options$relations;
3193
- return (_options$relations = options.relations) === null || _options$relations === void 0 ? void 0 : _options$relations[relation](this);
3343
+ return options.relations?.[relation](this);
3194
3344
  };
3195
3345
  if ("scopes" in options) for (const scope in options.scopes) this.models[name].prototype[getScopeMethod(scope)] = options.scopes[scope];
3196
3346
  this.models[name].setConnectionResolver(this);
@@ -3228,6 +3378,9 @@ var Model = class Model extends BaseModel {
3228
3378
  this.buildRelationships(attributes);
3229
3379
  return this.asProxy();
3230
3380
  }
3381
+ static define() {
3382
+ return this;
3383
+ }
3231
3384
  static query(trx = null) {
3232
3385
  return new this().newQuery(trx);
3233
3386
  }
@@ -3411,7 +3564,7 @@ var Model = class Model extends BaseModel {
3411
3564
  });
3412
3565
  }
3413
3566
  toData() {
3414
- return assign(this.attributesToData(), this.relationsToData());
3567
+ return Obj.deepMerge(this.attributesToData(), this.relationsToData());
3415
3568
  }
3416
3569
  toJSON() {
3417
3570
  return this.toData();
@@ -3422,6 +3575,15 @@ var Model = class Model extends BaseModel {
3422
3575
  toString() {
3423
3576
  return this.toJson();
3424
3577
  }
3578
+ getAttributes() {
3579
+ return super.getAttributes();
3580
+ }
3581
+ getAttribute(key) {
3582
+ return super.getAttribute(key);
3583
+ }
3584
+ setAttribute(key, value) {
3585
+ return super.setAttribute(key, value);
3586
+ }
3425
3587
  fill(attributes) {
3426
3588
  for (const key in attributes) this.setAttribute(key, attributes[key]);
3427
3589
  return this;
@@ -3462,10 +3624,9 @@ var Model = class Model extends BaseModel {
3462
3624
  if (this.usesTimestamps()) this.updateTimestamps();
3463
3625
  const attributes = this.getAttributes();
3464
3626
  if (this.getIncrementing()) {
3465
- var _data$;
3466
3627
  const keyName = this.getKeyName();
3467
3628
  const data = await query.insert([attributes], [keyName]);
3468
- this.setAttribute(keyName, ((_data$ = data[0]) === null || _data$ === void 0 ? void 0 : _data$[keyName]) || data[0]);
3629
+ this.setAttribute(keyName, data[0]?.[keyName] || data[0]);
3469
3630
  } else if (Object.keys(attributes).length > 0) await query.insert(attributes);
3470
3631
  this.exists = true;
3471
3632
  await this.execHooks("created", options);
@@ -3571,7 +3732,7 @@ var Pivot = class extends Model {
3571
3732
  };
3572
3733
  //#endregion
3573
3734
  //#region src/collection.ts
3574
- var Collection$1 = class Collection$1 extends Collection {
3735
+ var Collection$1 = class extends Collection {
3575
3736
  newConstructor(...args) {
3576
3737
  return new (this.getConstructor())(...args);
3577
3738
  }
@@ -3580,17 +3741,18 @@ var Collection$1 = class Collection$1 extends Collection {
3580
3741
  }
3581
3742
  async load(...relations) {
3582
3743
  if (this.isNotEmpty()) {
3583
- const items = await this.first().constructor.query().with(...relations).eagerLoadRelations(this.items);
3744
+ const items = await this.first().constructor.query().with(...relations).eagerLoadRelations(this.all());
3584
3745
  return this.newConstructor(items);
3585
3746
  }
3586
3747
  return this;
3587
3748
  }
3588
3749
  async loadAggregate(relations, column, action = null) {
3589
3750
  if (this.isEmpty()) return this;
3590
- const models = (await this.first().newModelQuery().whereIn(this.first().getKeyName(), this.modelKeys()).select(this.first().getKeyName()).withAggregate(relations, column, action).get()).keyBy(this.first().getKeyName());
3591
- const attributes = diff(Object.keys(models.first().getAttributes()), [models.first().getKeyName()]);
3751
+ const first = this.first();
3752
+ const models = (await first.newModelQuery().whereIn(first.getKeyName(), this.modelKeys()).select(first.getKeyName()).withAggregate(relations, column, action).get()).keyBy(first.getKeyName());
3753
+ const attributes = collect(Object.keys(models.first().getAttributes())).diff([models.first().getKeyName()]).all();
3592
3754
  this.each((model) => {
3593
- const extraAttributes = pick(models.get(model.getKey()).getAttributes(), attributes);
3755
+ const extraAttributes = Arr.select(models.get(model.getKey()).getAttributes(), attributes);
3594
3756
  model.fill(extraAttributes).syncOriginalAttributes(...attributes);
3595
3757
  });
3596
3758
  return this;
@@ -3628,20 +3790,21 @@ var Collection$1 = class Collection$1 extends Collection {
3628
3790
  diff(items) {
3629
3791
  const diff = new this.constructor();
3630
3792
  const dictionary = this.getDictionary(items);
3631
- this.items.map((item) => {
3793
+ this.all().map((item) => {
3632
3794
  if (dictionary[item.getKey()] === void 0) diff.add(item);
3633
3795
  });
3634
3796
  return diff;
3635
3797
  }
3636
- except(keys) {
3637
- const dictionary = omit(this.getDictionary(), keys);
3798
+ except(...keys) {
3799
+ const values = keys.length === 1 && Array.isArray(keys[0]) ? keys[0].map(String) : keys.map(String);
3800
+ const dictionary = Arr.except(this.getDictionary(), values);
3638
3801
  return new this.constructor(Object.values(dictionary));
3639
3802
  }
3640
3803
  intersect(items) {
3641
3804
  const intersect = new this.constructor();
3642
- if (isEmpty(items)) return intersect;
3805
+ if (Arr.isEmpty(items)) return intersect;
3643
3806
  const dictionary = this.getDictionary(items);
3644
- for (const item of this.items) if (dictionary[item.getKey()] !== void 0) intersect.add(item);
3807
+ for (const item of this.all()) if (dictionary[item.getKey()] !== void 0) intersect.add(item);
3645
3808
  return intersect;
3646
3809
  }
3647
3810
  unique(key, _strict = false) {
@@ -3650,20 +3813,21 @@ var Collection$1 = class Collection$1 extends Collection {
3650
3813
  }
3651
3814
  find(key, defaultValue = null) {
3652
3815
  if (key instanceof Model) key = key.getKey();
3653
- if (isArray(key)) {
3816
+ if (Array.isArray(key)) {
3654
3817
  if (this.isEmpty()) return new this.constructor();
3655
3818
  return this.whereIn(this.first().getKeyName(), key);
3656
3819
  }
3657
- collect$1(this.items).first((model) => {
3820
+ collect(this.all()).first((model) => {
3658
3821
  return model.getKey() == key;
3659
3822
  });
3660
- return this.items.filter((model) => {
3823
+ return this.all().filter((model) => {
3661
3824
  return model.getKey() == key;
3662
3825
  })[0] || defaultValue;
3663
3826
  }
3664
3827
  async fresh(...args) {
3665
3828
  if (this.isEmpty()) return new this.constructor();
3666
3829
  const model = this.first();
3830
+ if (!model) return new this.constructor();
3667
3831
  const freshModels = (await model.newQuery().with(...args).whereIn(model.getKeyName(), this.modelKeys()).get()).getDictionary();
3668
3832
  return this.filter((model) => {
3669
3833
  return model.exists && freshModels[model.getKey()] !== void 0;
@@ -3686,15 +3850,15 @@ var Collection$1 = class Collection$1 extends Collection {
3686
3850
  item.append(attributes);
3687
3851
  });
3688
3852
  }
3689
- only(keys) {
3690
- if (keys === null) return new Collection$1(this.items);
3691
- const dictionary = pick(this.getDictionary(), keys);
3853
+ only(...keys) {
3854
+ const values = keys.length === 1 && Array.isArray(keys[0]) ? keys[0].map(String) : keys.map(String);
3855
+ const dictionary = Arr.select(this.getDictionary(), values);
3692
3856
  return new this.constructor(Object.values(dictionary));
3693
3857
  }
3694
3858
  getDictionary(items) {
3695
- items = !items ? this.items : items;
3859
+ const values = !items ? this.all() : items instanceof Collection ? items.all() : items;
3696
3860
  const dictionary = {};
3697
- items.map((value) => {
3861
+ values.map((value) => {
3698
3862
  dictionary[value.getKey()] = value;
3699
3863
  });
3700
3864
  return dictionary;
@@ -3718,8 +3882,8 @@ var Collection$1 = class Collection$1 extends Collection {
3718
3882
  return JSON.stringify(this.toData(), ...args);
3719
3883
  }
3720
3884
  [Symbol.iterator] = () => {
3721
- const items = this.items;
3722
- const length = this.items.length;
3885
+ const items = this.all();
3886
+ const length = items.length;
3723
3887
  let n = 0;
3724
3888
  return { next() {
3725
3889
  return n < length ? {
@@ -3766,24 +3930,24 @@ const InteractsWithPivotTable = (Relation) => {
3766
3930
  let records;
3767
3931
  const results = await this.getCurrentlyAttachedPivots();
3768
3932
  const current = results.length === 0 ? [] : results.map((result) => result.toData()).pluck(this.relatedPivotKey).all().map((i) => String(i));
3769
- const detach = diff(current, Object.keys(records = this.formatRecordsList(this.parseIds(ids))));
3933
+ const detach = collect(current).diff(Object.keys(records = this.formatRecordsList(this.parseIds(ids)))).all();
3770
3934
  if (detaching && detach.length > 0) {
3771
3935
  await this.detach(detach);
3772
3936
  changes.detached = this.castKeys(detach);
3773
3937
  }
3774
- changes = assign(changes, await this.attachNew(records, current, false));
3938
+ changes = Obj.deepMerge(changes, await this.attachNew(records, current, false));
3775
3939
  return changes;
3776
3940
  }
3777
3941
  syncWithoutDetaching(ids) {
3778
3942
  return this.sync(ids, false);
3779
3943
  }
3780
3944
  syncWithPivotValues(ids, values, detaching = true) {
3781
- return this.sync(collect$1(this.parseIds(ids)).mapWithKeys((id) => {
3782
- return [id, values];
3945
+ return this.sync(collect(this.parseIds(ids)).mapWithKeys((id) => {
3946
+ return [String(id), values];
3783
3947
  }), detaching);
3784
3948
  }
3785
3949
  withPivot(columns) {
3786
- this.pivotColumns = this.pivotColumns.concat(isArray(columns) ? columns : Array.prototype.slice.call(columns));
3950
+ this.pivotColumns = this.pivotColumns.concat(Array.isArray(columns) ? columns : Array.prototype.slice.call(columns));
3787
3951
  return this;
3788
3952
  }
3789
3953
  async attachNew(records, current, touch = true) {
@@ -3819,9 +3983,9 @@ const InteractsWithPivotTable = (Relation) => {
3819
3983
  return parseInt(updated);
3820
3984
  }
3821
3985
  formatRecordsList(records) {
3822
- return collect$1(records).mapWithKeys((attributes, id) => {
3823
- if (!isArray(attributes)) [id, attributes] = [attributes, {}];
3824
- return [id, attributes];
3986
+ return collect(records).mapWithKeys((attributes, id) => {
3987
+ if (!Array.isArray(attributes)) [id, attributes] = [attributes, {}];
3988
+ return [String(id), attributes];
3825
3989
  }).all();
3826
3990
  }
3827
3991
  async getCurrentlyAttachedPivots() {
@@ -3891,7 +4055,7 @@ const InteractsWithPivotTable = (Relation) => {
3891
4055
  }
3892
4056
  formatAttachRecord(key, value, attributes, hasTimestamps) {
3893
4057
  const [id, newAttributes] = this.extractAttachIdAndAttributes(key, value, attributes);
3894
- return assign(this.baseAttachRecord(id, hasTimestamps), newAttributes);
4058
+ return Obj.deepMerge(this.baseAttachRecord(id, hasTimestamps), newAttributes);
3895
4059
  }
3896
4060
  baseAttachRecord(id, timed) {
3897
4061
  let record = {};
@@ -3904,7 +4068,7 @@ const InteractsWithPivotTable = (Relation) => {
3904
4068
  return record;
3905
4069
  }
3906
4070
  extractAttachIdAndAttributes(key, value, newAttributes) {
3907
- return isArray(value) ? [key, {
4071
+ return Array.isArray(value) ? [key, {
3908
4072
  ...value,
3909
4073
  ...newAttributes
3910
4074
  }] : [value, newAttributes];
@@ -3915,7 +4079,7 @@ const InteractsWithPivotTable = (Relation) => {
3915
4079
  parseIds(value) {
3916
4080
  if (value instanceof Model) return [value[this.relatedKey]];
3917
4081
  if (value instanceof Collection$1) return value.pluck(this.relatedKey).all();
3918
- return isArray(value) ? value : [value];
4082
+ return Array.isArray(value) ? value : [value];
3919
4083
  }
3920
4084
  };
3921
4085
  };
@@ -3975,9 +4139,8 @@ var BelongsToMany = class extends compose(Relation, InteractsWithPivotTable) {
3975
4139
  return this;
3976
4140
  }
3977
4141
  async get(columns) {
3978
- var _builder$query;
3979
4142
  const builder = this.query.applyScopes();
3980
- columns = ((_builder$query = builder.query) === null || _builder$query === void 0 || (_builder$query = _builder$query._statements) === null || _builder$query === void 0 ? void 0 : _builder$query.find((item) => item.grouping == "columns")) ? [] : columns;
4143
+ columns = builder.query?._statements?.find((item) => item.grouping == "columns") ? [] : columns;
3981
4144
  let models = await builder.select(this.shouldSelect(columns)).getModels();
3982
4145
  this.hydratePivotRelation(models);
3983
4146
  if (models.length > 0) models = await builder.eagerLoadRelations(models);
@@ -4026,7 +4189,7 @@ var BelongsToMany = class extends compose(Relation, InteractsWithPivotTable) {
4026
4189
  const value = model.attributes[key];
4027
4190
  if (key.startsWith("pivot_")) {
4028
4191
  values[key.substring(6)] = value;
4029
- model.attributes = omit(model.attributes, [key]);
4192
+ model.attributes = Arr.except(model.attributes, [key]);
4030
4193
  }
4031
4194
  }
4032
4195
  return values;
@@ -4037,11 +4200,11 @@ var BelongsToMany = class extends compose(Relation, InteractsWithPivotTable) {
4037
4200
  return this.withPivot(this.createdAt(), this.updatedAt());
4038
4201
  }
4039
4202
  shouldSelect(columns = ["*"]) {
4040
- if (isEqual(columns, ["*"])) columns = [this.related.getTable() + ".*"];
4203
+ if (columns.length === 1 && columns[0] === "*") columns = [this.related.getTable() + ".*"];
4041
4204
  return columns.concat(this.aliasedPivotColumns());
4042
4205
  }
4043
4206
  aliasedPivotColumns() {
4044
- return collect$1([this.foreignPivotKey, this.relatedPivotKey].concat(this.pivotColumns)).map((column) => {
4207
+ return collect([this.foreignPivotKey, this.relatedPivotKey].concat(this.pivotColumns)).map((column) => {
4045
4208
  return this.qualifyPivotColumn(column) + " as pivot_" + column;
4046
4209
  }).unique().all();
4047
4210
  }
@@ -4161,9 +4324,8 @@ var Builder = class Builder extends Inference {
4161
4324
  }
4162
4325
  asProxy() {
4163
4326
  return new Proxy(this, { get(target, prop) {
4164
- var _target$query$connect;
4165
4327
  if (typeof target[prop] !== "undefined") return target[prop];
4166
- const skipReturning = !!((_target$query$connect = target.query.connector) === null || _target$query$connect === void 0 || (_target$query$connect = _target$query$connect.client.config) === null || _target$query$connect === void 0 || (_target$query$connect = _target$query$connect.client) === null || _target$query$connect === void 0 ? void 0 : _target$query$connect.includes("mysql")) && prop === "returning";
4328
+ const skipReturning = !!target.query.connector?.client.config?.client?.includes("mysql") && prop === "returning";
4167
4329
  if ([
4168
4330
  "select",
4169
4331
  "from",
@@ -4257,7 +4419,7 @@ var Builder = class Builder extends Inference {
4257
4419
  };
4258
4420
  }
4259
4421
  if (prop.startsWith("where")) {
4260
- const column = snake(prop.substring(5));
4422
+ const column = Str.snake(prop.substring(5));
4261
4423
  return (...args) => {
4262
4424
  target.query.where(column, ...args);
4263
4425
  return target.asProxy();
@@ -4332,7 +4494,8 @@ var Builder = class Builder extends Inference {
4332
4494
  }
4333
4495
  addUpdatedAtColumn(values) {
4334
4496
  if (!this.model.usesTimestamps() || this.model.getUpdatedAtColumn() === null) return values;
4335
- values = assign({ [this.model.getUpdatedAtColumn()]: this.model.freshTimestampString() }, values);
4497
+ const column = this.model.getUpdatedAtColumn();
4498
+ values = Obj.deepMerge({ [column]: this.model.freshTimestampString() }, values);
4336
4499
  return values;
4337
4500
  }
4338
4501
  delete() {
@@ -4360,9 +4523,8 @@ var Builder = class Builder extends Inference {
4360
4523
  return this.model;
4361
4524
  }
4362
4525
  setModel(model) {
4363
- var _this$query;
4364
4526
  this.model = model;
4365
- if (typeof ((_this$query = this.query) === null || _this$query === void 0 || (_this$query = _this$query.client) === null || _this$query === void 0 ? void 0 : _this$query.table) == "function") this.query = this.query.client.table(this.model.getTable());
4527
+ if (typeof this.query?.client?.table == "function") this.query = this.query.client.table(this.model.getTable());
4366
4528
  else this.query = this.query.table(this.model.getTable());
4367
4529
  return this;
4368
4530
  }
@@ -4405,7 +4567,7 @@ var Builder = class Builder extends Inference {
4405
4567
  }
4406
4568
  withoutGlobalScope(scope) {
4407
4569
  if (typeof scope !== "string") scope = scope.constructor.name;
4408
- this.globalScopes = omit(this.globalScopes, [scope]);
4570
+ this.globalScopes = Arr.except(this.globalScopes, [scope]);
4409
4571
  return this;
4410
4572
  }
4411
4573
  macro(name, callback) {
@@ -4422,7 +4584,7 @@ var Builder = class Builder extends Inference {
4422
4584
  let eagerLoads = {};
4423
4585
  if (typeof args[1] === "function") {
4424
4586
  const eagerLoad = this.parseWithRelations({ [args[0]]: args[1] });
4425
- this.eagerLoad = assign(this.eagerLoad, eagerLoad);
4587
+ this.eagerLoad = Obj.deepMerge(this.eagerLoad, eagerLoad);
4426
4588
  return this;
4427
4589
  }
4428
4590
  const relations = flattenDeep(args);
@@ -4431,13 +4593,13 @@ var Builder = class Builder extends Inference {
4431
4593
  let eagerLoad;
4432
4594
  if (typeof relation === "string") eagerLoad = { [relation]: (q) => q };
4433
4595
  else if (typeof relation === "object") eagerLoad = relation;
4434
- eagerLoads = assign(eagerLoads, eagerLoad);
4596
+ eagerLoads = Obj.deepMerge(eagerLoads, eagerLoad);
4435
4597
  }
4436
- this.eagerLoad = assign(this.eagerLoad, this.parseWithRelations(eagerLoads));
4598
+ this.eagerLoad = Obj.deepMerge(this.eagerLoad, this.parseWithRelations(eagerLoads));
4437
4599
  return this;
4438
4600
  }
4439
4601
  has(relation, operator = ">=", count = 1, boolean = "and", callback = null) {
4440
- if (isString(relation)) {
4602
+ if (typeof relation === "string") {
4441
4603
  if (relation.includes(".")) return this.hasNested(relation, operator, count, boolean, callback);
4442
4604
  relation = this.getRelationWithoutConstraints(getRelationMethod(relation));
4443
4605
  }
@@ -4514,7 +4676,7 @@ var Builder = class Builder extends Inference {
4514
4676
  let eagerLoad;
4515
4677
  if (typeof relation === "string") eagerLoad = { [relation]: (q) => q };
4516
4678
  else if (typeof relation === "object") eagerLoad = relation;
4517
- eagerLoads = assign(eagerLoads, eagerLoad);
4679
+ eagerLoads = Obj.deepMerge(eagerLoads, eagerLoad);
4518
4680
  }
4519
4681
  relations = eagerLoads;
4520
4682
  const db = this.model.getConnection();
@@ -4533,7 +4695,7 @@ var Builder = class Builder extends Inference {
4533
4695
  } else expression = column;
4534
4696
  const query = relation.getRelationExistenceQuery(relation.getRelated().newModelQuery(), this, db.raw(expression));
4535
4697
  constraints(query);
4536
- alias = alias || snake(`${name} ${action} ${column}`.replace("/[^[:alnum:][:space:]_]/u", ""));
4698
+ alias = alias || Str.snake(`${name} ${action} ${column}`.replace("/[^[:alnum:][:space:]_]/u", ""));
4537
4699
  if (action === "exists") this.select(db.raw(`exists(${query.toSql().sql}) as ${alias}`));
4538
4700
  else this.selectSub(action ? query : query.limit(1), alias);
4539
4701
  }
@@ -4557,7 +4719,7 @@ var Builder = class Builder extends Inference {
4557
4719
  }
4558
4720
  parseSub(query) {
4559
4721
  if (query instanceof Builder || query instanceof Relation) return [query.toSql().sql, query.toSql().bindings];
4560
- else if (isString(query)) return [query, []];
4722
+ else if (typeof query === "string") return [query, []];
4561
4723
  else throw new Error("A subquery must be a query builder instance, a Closure, or a string.");
4562
4724
  }
4563
4725
  prependDatabaseNameIfCrossDatabaseQuery(query) {
@@ -4614,15 +4776,15 @@ var Builder = class Builder extends Inference {
4614
4776
  if (prefix !== "") prefix += ".";
4615
4777
  for (const key in relations) {
4616
4778
  const value = relations[key];
4617
- if (isString(value) || Number.isFinite(parseInt(value))) continue;
4779
+ if (typeof value === "string" || Number.isFinite(parseInt(value))) continue;
4618
4780
  const [attribute, attributeSelectConstraint] = this.parseNameAndAttributeSelectionConstraint(key, value);
4619
4781
  preparedRelationships = Object.assign({}, preparedRelationships, { [`${prefix}${attribute}`]: attributeSelectConstraint }, this.prepareNestedWithRelationships(value, `${prefix}${attribute}`));
4620
- relations = omit(relations, [key]);
4782
+ relations = Arr.except(relations, [key]);
4621
4783
  }
4622
4784
  for (const key in relations) {
4623
4785
  const value = relations[key];
4624
4786
  let attribute = key, attributeSelectConstraint = value;
4625
- if (isString(value)) [attribute, attributeSelectConstraint] = this.parseNameAndAttributeSelectionConstraint(value);
4787
+ if (typeof value === "string") [attribute, attributeSelectConstraint] = this.parseNameAndAttributeSelectionConstraint(value);
4626
4788
  preparedRelationships[`${prefix}${attribute}`] = this.combineConstraints([attributeSelectConstraint, preparedRelationships[`${prefix}${attribute}`] || (() => {})]);
4627
4789
  }
4628
4790
  return preparedRelationships;
@@ -4670,8 +4832,8 @@ var Builder = class Builder extends Inference {
4670
4832
  }
4671
4833
  async findOrFail(...args) {
4672
4834
  const data = await this.find(...args);
4673
- if (isArray(args[0])) {
4674
- if (data.count() !== args[0].length) throw new ModelNotFoundError().setModel(this.model.constructor.name, diff(args[0], data.modelKeys()));
4835
+ if (Array.isArray(args[0])) {
4836
+ if (data.count() !== args[0].length) throw new ModelNotFoundError().setModel(this.model.constructor.name, collect(args[0]).diff(data.modelKeys()).all());
4675
4837
  return data;
4676
4838
  }
4677
4839
  if (data === null) throw new ModelNotFoundError().setModel(this.model.constructor.name, args[0]);
@@ -4685,12 +4847,12 @@ var Builder = class Builder extends Inference {
4685
4847
  async firstOrNew(attributes = {}, values = {}) {
4686
4848
  const instance = await this.where(attributes).first();
4687
4849
  if (instance !== null) return instance;
4688
- return this.newModelInstance(assign(attributes, values));
4850
+ return this.newModelInstance(Obj.deepMerge(attributes, values));
4689
4851
  }
4690
4852
  async firstOrCreate(attributes = {}, values = {}) {
4691
4853
  const instance = await this.where(attributes).first();
4692
4854
  if (instance !== null) return instance;
4693
- return tap(this.newModelInstance(assign(attributes, values)), async (instance) => {
4855
+ return tap(this.newModelInstance(Obj.deepMerge(attributes, values)), async (instance) => {
4694
4856
  await instance.save({ client: this.query });
4695
4857
  });
4696
4858
  }
@@ -4710,14 +4872,13 @@ var Builder = class Builder extends Inference {
4710
4872
  return this;
4711
4873
  }
4712
4874
  async find(id, columns) {
4713
- if (isArray(id) || id instanceof Collection$1) return await this.findMany(id, columns);
4875
+ if (Array.isArray(id) || id instanceof Collection$1) return await this.findMany(id, columns);
4714
4876
  return await this.where(this.model.getKeyName(), id).first(columns);
4715
4877
  }
4716
4878
  async findMany(ids, columns = ["*"]) {
4717
- if (ids instanceof Collection$1) ids = ids.modelKeys();
4718
- ids = isArray(ids) ? ids : [ids];
4719
- if (ids.length === 0) return new Collection$1([]);
4720
- return await this.whereIn(this.model.getKeyName(), ids).get(columns);
4879
+ const values = ids instanceof Collection$1 ? ids.modelKeys() : Array.isArray(ids) ? ids : [ids];
4880
+ if (values.length === 0) return new Collection$1([]);
4881
+ return await this.whereIn(this.model.getKeyName(), values).get(columns);
4721
4882
  }
4722
4883
  async pluck(column) {
4723
4884
  return new Collection$1(await this.query.pluck(column));
@@ -4725,7 +4886,7 @@ var Builder = class Builder extends Inference {
4725
4886
  async destroy(ids) {
4726
4887
  if (ids instanceof Collection$1) ids = ids.modelKeys();
4727
4888
  if (ids instanceof Collection) ids = ids.all();
4728
- ids = isArray(ids) ? ids : Array.prototype.slice.call(ids);
4889
+ ids = Array.isArray(ids) ? ids : Array.prototype.slice.call(ids);
4729
4890
  if (ids.length === 0) return 0;
4730
4891
  const key = this.model.newInstance().getKeyName();
4731
4892
  let count = 0;
@@ -4743,12 +4904,11 @@ var Builder = class Builder extends Inference {
4743
4904
  return await this.model.newModelQuery().get(columns);
4744
4905
  }
4745
4906
  async paginate(page = 1, perPage = 10) {
4746
- var _this;
4747
4907
  page = page || 1;
4748
- perPage = perPage || ((_this = this) === null || _this === void 0 || (_this = _this.model) === null || _this === void 0 ? void 0 : _this.perPage) || 15;
4908
+ perPage = perPage || this?.model?.perPage || 15;
4749
4909
  this.applyScopes();
4750
4910
  const total = await this.query.clone().clearOrder().clearSelect().count(this.primaryKey);
4751
- let results = [];
4911
+ let results;
4752
4912
  if (total > 0) {
4753
4913
  const skip = (page - 1) * (perPage ?? 10);
4754
4914
  this.take(perPage).skip(skip);
@@ -4758,7 +4918,7 @@ var Builder = class Builder extends Inference {
4758
4918
  return new Paginator(results, parseInt(total), perPage, page);
4759
4919
  }
4760
4920
  async getModels(...columns) {
4761
- columns = flat(columns);
4921
+ columns = flatten(columns);
4762
4922
  if (columns.length > 0) {
4763
4923
  if (this.query._statements.filter((item) => item.grouping == "columns").length == 0 && columns[0] !== "*") this.query.select(...columns);
4764
4924
  }
@@ -4874,11 +5034,11 @@ var SQLite = class {
4874
5034
  is_generated: raw.hidden !== 0,
4875
5035
  generation_expression: null,
4876
5036
  is_nullable: raw.notnull === 0,
4877
- is_unique: !!(index === null || index === void 0 ? void 0 : index.unique) && (indexInfo === null || indexInfo === void 0 ? void 0 : indexInfo.length) === 1,
5037
+ is_unique: !!index?.unique && indexInfo?.length === 1,
4878
5038
  is_primary_key: raw.pk === 1,
4879
5039
  has_auto_increment: raw.pk === 1 && tablesWithAutoIncrementPrimaryKeys.includes(table),
4880
- foreign_key_column: (foreignKey === null || foreignKey === void 0 ? void 0 : foreignKey.to) || null,
4881
- foreign_key_table: (foreignKey === null || foreignKey === void 0 ? void 0 : foreignKey.table) || null
5040
+ foreign_key_column: foreignKey?.to || null,
5041
+ foreign_key_table: foreignKey?.table || null
4882
5042
  };
4883
5043
  });
4884
5044
  };
@@ -5100,8 +5260,7 @@ var Migrator = class {
5100
5260
  else await callback(connection);
5101
5261
  }
5102
5262
  async runMethod(connection, migration, method) {
5103
- var _migration$method;
5104
- await ((_migration$method = migration[method]) === null || _migration$method === void 0 ? void 0 : _migration$method.call(migration, connection.schema, connection));
5263
+ await migration[method]?.(connection.schema, connection);
5105
5264
  }
5106
5265
  async resolvePath(filePath) {
5107
5266
  try {
@@ -5130,7 +5289,7 @@ var Migrator = class {
5130
5289
  return path.basename(filePath).replace(".js", "");
5131
5290
  }
5132
5291
  path(p) {
5133
- this.paths = Array.from(new Set([...this.paths, p]));
5292
+ this.paths = Array.from(/* @__PURE__ */ new Set([...this.paths, p]));
5134
5293
  }
5135
5294
  getPaths() {
5136
5295
  return this.paths;
@@ -5299,8 +5458,7 @@ var Migrate = class {
5299
5458
  * @returns
5300
5459
  */
5301
5460
  async setupConnection(config) {
5302
- var _config$migrations;
5303
- const table = (config === null || config === void 0 || (_config$migrations = config.migrations) === null || _config$migrations === void 0 ? void 0 : _config$migrations.table) || "migrations";
5461
+ const table = config?.migrations?.table || "migrations";
5304
5462
  if (config.skipConnection !== true) {
5305
5463
  arquebus.addConnection(config, "default");
5306
5464
  Object.entries(config.connections || {}).forEach(([name, connection]) => {
@@ -5360,7 +5518,6 @@ var MigrationCreator = class {
5360
5518
  let stub;
5361
5519
  if (!table) {
5362
5520
  const customPath = path.join(this.customStubPath ?? "", `migration-${this.type}.stub`);
5363
- console.log("\n", customPath, "---");
5364
5521
  stub = await FileSystem.fileExists(customPath) ? customPath : this.stubPath(`/migration-${this.type}.stub`);
5365
5522
  } else if (create) {
5366
5523
  const customPath = path.join(this.customStubPath ?? "", `migration.create-${this.type}.stub`);
@@ -5393,7 +5550,9 @@ var MigrationCreator = class {
5393
5550
  }
5394
5551
  stubPath(stub = "") {
5395
5552
  const __dirname = this.getDirname(import.meta);
5396
- return path.join(__dirname, "stubs", stub);
5553
+ const resolved = [path.join(__dirname, "stubs", stub), path.join(__dirname, "../stubs", stub)].find((candidate) => existsSync(candidate));
5554
+ if (!resolved) throw new Error(`Migration stub not found: ${stub}`);
5555
+ return resolved;
5397
5556
  }
5398
5557
  getDirname(meta) {
5399
5558
  if (typeof __dirname !== "undefined") return __dirname;
@@ -5403,20 +5562,33 @@ var MigrationCreator = class {
5403
5562
  };
5404
5563
  //#endregion
5405
5564
  //#region package.json
5406
- var version = "2.0.0";
5565
+ var version = "3.0.1";
5407
5566
  //#endregion
5408
5567
  //#region src/cli/index.ts
5409
- (class Cli {
5568
+ (class Cli extends Application {
5410
5569
  cwd;
5411
- output = Logger.log();
5570
+ output = Logger;
5412
5571
  config = {};
5413
5572
  basePath = "";
5414
- modulePath;
5573
+ modulePath = "";
5415
5574
  configPath;
5416
- modulePackage;
5575
+ modulePackage = { version: "N/A" };
5417
5576
  constructor(basePath) {
5577
+ super();
5418
5578
  this.basePath = basePath ?? (process.env.TEST === "true" ? "test/cli" : "");
5419
5579
  }
5580
+ static async init() {
5581
+ config({ quiet: true });
5582
+ const instance = new Cli();
5583
+ await instance.loadPaths();
5584
+ await instance.loadConfig();
5585
+ await instance.run();
5586
+ }
5587
+ registerMusketListeners(musket) {
5588
+ musket.afterHandle.once(async () => {
5589
+ process.exit(0);
5590
+ });
5591
+ }
5420
5592
  terminateNotFound() {
5421
5593
  const cmd = Logger.log([["arquebus init", [
5422
5594
  "italic",
@@ -5425,13 +5597,24 @@ var version = "2.0.0";
5425
5597
  ]]], "", false);
5426
5598
  this.output.error(`ERROR: Arquebus config not found. Run ${cmd} first.`);
5427
5599
  }
5428
- static init() {
5429
- config({ quiet: true });
5430
- const instance = new Cli();
5431
- Promise.all([instance.loadPaths(), instance.loadConfig()]).then(([_, e]) => e.run());
5600
+ ensureConfigured() {
5601
+ if (!this.configPath) this.terminateNotFound();
5602
+ }
5603
+ resolveBasePath(requestedPath) {
5604
+ return requestedPath ? path$1.join(this.cwd, requestedPath) : this.cwd;
5605
+ }
5606
+ async resolveStub(name) {
5607
+ const candidates = [path$1.join(this.modulePath, "src/stubs", name), path$1.join(this.modulePath, "dist/stubs", name)];
5608
+ for (const candidate of candidates) if (await FileSystem.fileExists(candidate)) return candidate;
5609
+ throw new Error(`Arquebus stub not found: ${name}`);
5610
+ }
5611
+ migrationReporter() {
5612
+ return (message, status) => {
5613
+ if (status && status !== "quiet") this.output[status](message);
5614
+ };
5432
5615
  }
5433
5616
  async loadPaths() {
5434
- this.cwd = path.join(process.cwd(), this.basePath);
5617
+ this.cwd = path$1.join(process.cwd(), this.basePath);
5435
5618
  this.configPath = FileSystem.resolveFileUp("arquebus.config", [
5436
5619
  "js",
5437
5620
  "ts",
@@ -5439,7 +5622,7 @@ var version = "2.0.0";
5439
5622
  ], this.cwd) ?? void 0;
5440
5623
  this.modulePath = Utils.findModulePkg("@h3ravel/arquebus", this.cwd) ?? "";
5441
5624
  try {
5442
- this.modulePackage = await import(path.join(this.modulePath, "package.json"));
5625
+ this.modulePackage = JSON.parse(await readFile(path$1.join(this.modulePath, "package.json"), "utf8"));
5443
5626
  } catch {
5444
5627
  this.modulePackage = { version: "N/A" };
5445
5628
  }
@@ -5447,233 +5630,184 @@ var version = "2.0.0";
5447
5630
  }
5448
5631
  async loadConfig() {
5449
5632
  try {
5450
- var _this$config$migratio;
5451
- this.config = (await import(this.configPath ?? "----")).default;
5452
- if ((_this$config$migratio = this.config.migrations) === null || _this$config$migratio === void 0 ? void 0 : _this$config$migratio.path) {
5453
- var _this$config$migratio2;
5454
- await mkdir(path.join(this.cwd, (_this$config$migratio2 = this.config.migrations) === null || _this$config$migratio2 === void 0 ? void 0 : _this$config$migratio2.path), { recursive: true });
5455
- }
5633
+ this.config = (await importFile(this.configPath ?? "----")).default;
5634
+ if (this.config.migrations?.path) await mkdir(path$1.join(this.cwd, this.config.migrations.path), { recursive: true });
5456
5635
  } catch {
5457
5636
  this.config = {};
5458
5637
  }
5459
5638
  return this;
5460
5639
  }
5461
5640
  async run() {
5462
- const cliVersion = ["Arquebus CLI version:", Logger.log(version, "green", false)].join(" ");
5463
- const localVersion = ["Arquebus Local version:", Logger.log(this.modulePackage.version || "None", "green", false)].join(" ");
5464
- program.name("arquebus").version(`${cliVersion}\n${localVersion}`);
5465
- program.command("init").description("Create a fresh Arquebus config.").addArgument(new Argument("[type]", "Type of config to generate.").choices(["js", "ts"]).default("js", "generates a js config")).action(async (type) => {
5466
- if (!this.modulePath) this.output.error(["ERROR: No local arquebus install found", " Try running: npm install arquebus --save"]);
5467
- if (this.configPath) this.output.error(`ERROR: ${this.configPath} already exists`);
5468
- try {
5469
- const stubPath = `./arquebus.config.${type}`;
5470
- const code = await readFile(path.join(this.modulePath, `/src/stubs/arquebus.config-${type}.stub`), { encoding: "utf8" });
5471
- await writeFile(path.join(this.cwd, stubPath), code);
5472
- this.output.success(`Initialized: Arquebus has been initialized as ${stubPath}`);
5473
- } catch (e) {
5474
- this.output.error("ERROR: " + e);
5475
- }
5476
- });
5477
- program.command("make:migration <name>").description("Create a new migration file.").addOption(new Option("-l, --type [string]", "Type of migration file to generate.").choices(["js", "ts"]).default("js", "generates a js migration file")).option("-t, --table [string]", "The table to migrate").option("-c, --create [string]", "The table to be created").option("-p, --path [path]", "The path to the migrations directory.").action(async (name, opts) => {
5478
- if (!this.configPath) this.terminateNotFound();
5479
- try {
5480
- var _this$config$migratio3;
5481
- name = snake(name);
5482
- const migrationPath = path.join(this.cwd, opts.path ?? ((_this$config$migratio3 = this.config.migrations) === null || _this$config$migratio3 === void 0 ? void 0 : _this$config$migratio3.path) ?? "./migrations");
5483
- let table = opts.table;
5484
- let create = Boolean(opts.create) && opts.create !== "";
5485
- if (!table && typeof opts.create === "string") {
5486
- table = opts.create;
5487
- create = true;
5488
- }
5489
- if (!table) {
5490
- const guessed = TableGuesser.guess(name);
5491
- table = guessed[0];
5492
- create = !!guessed[1];
5493
- }
5494
- this.output.info("INFO: Creating Migration");
5495
- const fileName = await new MigrationCreator(void 0, opts.type).create(name, migrationPath, table, create);
5496
- this.output.success(`INFO: Migration Created \n ${Logger.log(path.basename(fileName), "gray", false)}`, true);
5497
- } catch (e) {
5498
- this.output.error("ERROR: " + e);
5499
- }
5500
- });
5501
- /**
5502
- * Publish migrations from third party vendors
5503
- */
5504
- program.command("migrate:publish <package>").description("Publish any migration files from packages.").option("-p, --path [path]", "The path to the migrations directory.").action(async (pkg, opts) => {
5505
- if (!this.configPath) this.terminateNotFound();
5506
- try {
5507
- var _this$config$migratio4;
5508
- const packagePath = Utils.findModulePkg(pkg) ?? "";
5509
- const basePath = path.join(this.cwd, opts.path ?? ((_this$config$migratio4 = this.config.migrations) === null || _this$config$migratio4 === void 0 ? void 0 : _this$config$migratio4.path) ?? "./migrations");
5510
- const pkgJson = await import(path.join(packagePath, "package.json"));
5511
- if (!packagePath) this.output.error(`ERROR: package ${pkg} not found`);
5512
- const creator = new MigrationCreator(path.join(packagePath, pkgJson.migrations ?? "migrations"));
5513
- const pkgInf = Logger.log(path.basename(pkgJson.name + "@" + pkgJson.version), ["italic", "gray"], false);
5514
- this.output.info(`INFO: Publishing migrations from ${pkgInf}`);
5515
- await creator.publish(basePath, (fileName) => {
5516
- this.output.split("INFO: Migration Published", fileName, "success");
5517
- });
5518
- } catch (e) {
5519
- this.output.error("ERROR: " + e);
5520
- }
5521
- });
5522
- /**
5523
- * Run all pending migrations
5524
- */
5525
- program.command("migrate").description("Run all pending migrations.").option("-s, --step [number]", "Force the migrations to be run so they can be rolled back individually.").option("-p, --path [path]", "The path to the migrations directory.").action(async (opts) => {
5526
- if (!this.configPath) this.terminateNotFound();
5527
- const basePath = opts.path ? path.join(this.cwd, opts.path) : this.cwd;
5528
- try {
5529
- const step = typeof opts.step === "string" ? parseInt(opts.step) : opts.step;
5530
- await new Migrate(basePath).run(this.config, {
5531
- ...opts,
5532
- step
5533
- }, true);
5534
- } catch (e) {
5535
- this.output.error("ERROR: " + e);
5536
- }
5537
- });
5538
- /**
5539
- * Rollaback the last migration
5540
- */
5541
- program.command("migrate:rollback").description("Rollback the last database migration.").option("-s, --step [number]", "The number of migrations to be reverted.").option("-p, --path [path]", "The path to the migrations directory.").action(async (opts) => {
5542
- if (!this.configPath) this.terminateNotFound();
5543
- const basePath = opts.path ? path.join(this.cwd, opts.path) : this.cwd;
5544
- try {
5545
- await new Migrate(basePath, void 0, (msg, sts) => {
5546
- if (sts) this.output[sts](msg);
5547
- }).rollback(this.config, {
5548
- ...opts,
5549
- step: typeof opts.step === "string" ? parseInt(opts.step) : opts.step
5550
- }, true);
5551
- } catch (e) {
5552
- this.output.error("ERROR: " + e);
5553
- }
5554
- });
5555
- /**
5556
- * Rollback all database migrations
5557
- */
5558
- program.command("migrate:reset").description("Rollback all database migrations.").option("-p, --path [path]", "The path to the migrations directory.").action(async (opts) => {
5559
- if (!this.configPath) this.terminateNotFound();
5560
- const basePath = opts.path ? path.join(this.cwd, opts.path) : this.cwd;
5561
- try {
5562
- await new Migrate(basePath, void 0, (msg, sts) => {
5563
- if (sts) this.output[sts](msg);
5564
- }).reset(this.config, opts, true);
5565
- } catch (e) {
5566
- this.output.error("ERROR: " + e);
5567
- }
5568
- });
5569
- /**
5570
- * Reset and re-run all migrations
5571
- */
5572
- program.command("migrate:refresh").description("Reset and re-run all migrations.").option("-p, --path [path]", "The path to the migrations directory.").action(async (opts) => {
5573
- if (!this.configPath) this.terminateNotFound();
5574
- const basePath = opts.path ? path.join(this.cwd, opts.path) : this.cwd;
5575
- try {
5576
- await new Migrate(basePath, void 0, (msg, sts) => {
5577
- if (sts) this.output[sts](msg);
5578
- }).refresh(this.config, opts, true);
5579
- } catch (e) {
5580
- this.output.error("ERROR: " + e);
5581
- }
5582
- });
5583
- /**
5584
- * Drop all tables and re-run all migrations
5585
- */
5586
- program.command("migrate:fresh").description("Drop all tables and re-run all migrations.").option("-p, --path [path]", "The path to the migrations directory.").action(async (opts) => {
5587
- if (!this.configPath) this.terminateNotFound();
5588
- const basePath = opts.path ? path.join(this.cwd, opts.path) : this.cwd;
5589
- try {
5590
- await new Migrate(basePath, void 0, (msg, sts) => {
5591
- if (sts) this.output[sts](msg);
5592
- }).fresh(this.config, opts, true);
5593
- } catch (e) {
5594
- this.output.error("ERROR: " + e);
5595
- }
5596
- });
5597
- /**
5598
- * Check the migration status
5599
- */
5600
- program.command("migrate:status").description("Show the status of each migration.").option("-p, --path [path]", "The path to the migrations directory.").action(async (opts) => {
5601
- if (!this.configPath) this.terminateNotFound();
5602
- const basePath = opts.path ? path.join(this.cwd, opts.path) : this.cwd;
5603
- try {
5604
- const migrations = await new Migrate(basePath, void 0, (msg, sts) => {
5605
- if (sts) this.output[sts](msg);
5606
- }).status(this.config, opts, true);
5607
- if (migrations.length > 0) {
5608
- Logger.twoColumnDetail(Logger.log("Migration name", "gray", false), Logger.log("Batch / Status", "gray", false));
5609
- migrations.forEach((migration) => {
5610
- const status = migration.ran ? `[${migration.batch}] ${Logger.log("Ran", "green", false)}` : Logger.log("Pending", "yellow", false);
5611
- Logger.twoColumnDetail(migration.name, status);
5612
- });
5613
- } else console.log("No migrations found");
5614
- } catch (e) {
5615
- this.output.error("ERROR: " + e);
5616
- }
5617
- });
5618
- /**
5619
- * Run database seeders
5620
- */
5621
- program.command("db:seed").description("Run database seeders.").option("-p, --path [path]", "The path to the seeders directory.").action(async (opts) => {
5622
- if (!this.configPath) this.terminateNotFound();
5623
- const basePath = opts.path ? path.join(this.cwd, opts.path) : this.cwd;
5624
- try {
5625
- var _this$config$seeders;
5626
- const { arquebus } = await new Migrate(basePath).setupConnection({
5627
- ...this.config,
5628
- skipConnection: false
5629
- });
5630
- const { SeederRunner } = await Promise.resolve().then(() => seeders_exports);
5631
- const runner = new SeederRunner(arquebus);
5632
- const seederPath = path.join(basePath, ((_this$config$seeders = this.config.seeders) === null || _this$config$seeders === void 0 ? void 0 : _this$config$seeders.path) ?? "./seeders");
5633
- await runner.setConnection(this.config.client).run([seederPath]);
5634
- this.output.success("Seeders executed successfully.");
5635
- } catch (e) {
5636
- this.output.error("ERROR: " + e);
5641
+ return await new Kernel(this).setCwd(this.cwd).setConfig({
5642
+ baseCommands: ArquebusCommands,
5643
+ name: "arquebus",
5644
+ hideMusketInfo: true,
5645
+ versionSeparator: "\n"
5646
+ }).setPackages([{
5647
+ name: "@h3ravel/arquebus",
5648
+ label: "Arquebus CLI",
5649
+ version,
5650
+ base: true
5651
+ }, {
5652
+ name: "@h3ravel/arquebus",
5653
+ label: "Arquebus ORM",
5654
+ version: this.modulePackage.version || "N/A"
5655
+ }]).bootstrap().run();
5656
+ }
5657
+ async initialize(type = "js") {
5658
+ if (!this.modulePath) this.output.error(["ERROR: No local arquebus install found", " Try running: pnpm add @h3ravel/arquebus"]);
5659
+ if (this.configPath) this.output.error(`ERROR: ${this.configPath} already exists`);
5660
+ try {
5661
+ const stubPath = `./arquebus.config.${type}`;
5662
+ const code = await readFile(await this.resolveStub(`arquebus.config-${type}.stub`), "utf8");
5663
+ await writeFile(path$1.join(this.cwd, stubPath), code);
5664
+ this.output.success(`Initialized: Arquebus has been initialized as ${stubPath}`);
5665
+ } catch (error) {
5666
+ this.output.error("ERROR: " + error);
5667
+ }
5668
+ }
5669
+ async makeMigration(rawName, options) {
5670
+ this.ensureConfigured();
5671
+ try {
5672
+ const name = Str.snake(rawName);
5673
+ const migrationPath = path$1.join(this.cwd, options.path ?? this.config.migrations?.path ?? "./migrations");
5674
+ let table = options.table;
5675
+ let create = Boolean(options.create) && options.create !== "";
5676
+ if (!table && typeof options.create === "string") {
5677
+ table = options.create;
5678
+ create = true;
5637
5679
  }
5638
- });
5639
- /**
5640
- * Create a new seeder file
5641
- */
5642
- program.command("make:seeder <name>").description("Create a new Seeder file.").addOption(new Option("-l, --type [string]", "Type of seeder file to generate.").choices(["js", "ts"]).default("js", "generates a js seeder file")).option("--force", "Force creation if seeder already exists.", false).option("-p, --path [path]", "The path to the seeders directory.").action(async (name, opts) => {
5643
- var _this$config$seeders2;
5644
- if (!this.configPath) this.terminateNotFound();
5645
- const seederPath = path.join(this.cwd, opts.path ?? ((_this$config$seeders2 = this.config.seeders) === null || _this$config$seeders2 === void 0 ? void 0 : _this$config$seeders2.path) ?? "./seeders", Str.of(name).snake("-") + "." + opts.type);
5646
- try {
5647
- if (!opts.force && await FileSystem.fileExists(seederPath)) this.output.error("ERROR: Seeder already exists.");
5648
- await mkdir(path.dirname(seederPath), { recursive: true });
5649
- let stub = await readFile(path.join(this.modulePath, `src/stubs/seeder-${opts.type}.stub`), "utf-8");
5650
- stub = stub.replace(/{{ name }}/g, name);
5651
- await writeFile(seederPath, stub);
5652
- this.output.split("INFO: Created Seeder", path.relative(this.cwd, seederPath));
5653
- } catch (e) {
5654
- this.output.error("ERROR: " + e);
5680
+ if (!table) {
5681
+ const guessed = TableGuesser.guess(name);
5682
+ table = guessed[0];
5683
+ create = Boolean(guessed[1]);
5655
5684
  }
5656
- });
5657
- /**
5658
- * Create a new model file
5659
- */
5660
- program.command("make:model <name>").description("Create a new Model file.").addOption(new Option("-l, --type [string]", "Type of migration file to generate.").choices(["js", "ts"]).default("js", "generates a js migration file")).option("--force", "Force creation if model already exists.", false).option("-p, --path [path]", "The path to the models directory.").action(async (name, opts) => {
5661
- var _this$config$models;
5662
- if (!this.configPath) this.terminateNotFound();
5663
- const modelPath = path.join(this.cwd, opts.path ?? ((_this$config$models = this.config.models) === null || _this$config$models === void 0 ? void 0 : _this$config$models.path) ?? "./models", name.toLowerCase() + "." + opts.type);
5664
- try {
5665
- if (!opts.force && await FileSystem.fileExists(modelPath)) this.output.error("ERROR: Model already exists.");
5666
- await mkdir(path.dirname(modelPath), { recursive: true });
5667
- let stub = await readFile(path.join(this.modulePath, `src/stubs/model-${opts.type}.stub`), "utf-8");
5668
- stub = stub.replace(/{{ name }}/g, name);
5669
- await writeFile(modelPath, stub);
5670
- this.output.success(`Created Model: ${modelPath}`);
5671
- } catch (e) {
5672
- this.output.error("ERROR: " + e);
5685
+ this.output.info("INFO: Creating Migration");
5686
+ const fileName = await new MigrationCreator(void 0, options.type ?? "js").create(name, migrationPath, table, create);
5687
+ this.output.success(`INFO: Migration Created \n ${Logger.log(path$1.basename(fileName), "gray", false)}`, true);
5688
+ } catch (error) {
5689
+ this.output.error("ERROR: " + error);
5690
+ }
5691
+ }
5692
+ async publishMigrations(pkg, options) {
5693
+ this.ensureConfigured();
5694
+ try {
5695
+ const packagePath = Utils.findModulePkg(pkg) ?? "";
5696
+ if (!packagePath) this.output.error(`ERROR: package ${pkg} not found`);
5697
+ const basePath = path$1.join(this.cwd, options.path ?? this.config.migrations?.path ?? "./migrations");
5698
+ const pkgJson = JSON.parse(await readFile(path$1.join(packagePath, "package.json"), "utf8"));
5699
+ const creator = new MigrationCreator(path$1.join(packagePath, pkgJson.migrations ?? "migrations"));
5700
+ const pkgInfo = Logger.log(path$1.basename(pkgJson.name + "@" + pkgJson.version), ["italic", "gray"], false);
5701
+ this.output.info(`INFO: Publishing migrations from ${pkgInfo}`);
5702
+ await creator.publish(basePath, (fileName) => {
5703
+ this.output.split("INFO: Migration Published", fileName, "success");
5704
+ });
5705
+ } catch (error) {
5706
+ this.output.error("ERROR: " + error);
5707
+ }
5708
+ }
5709
+ async migrate(options) {
5710
+ this.ensureConfigured();
5711
+ const basePath = this.resolveBasePath(options.path);
5712
+ try {
5713
+ const step = typeof options.step === "string" ? Number.parseInt(options.step) : options.step;
5714
+ await new Migrate(basePath).run(this.config, {
5715
+ ...options,
5716
+ step
5717
+ }, true);
5718
+ } catch (error) {
5719
+ this.output.error("ERROR: " + error);
5720
+ }
5721
+ }
5722
+ async rollback(options) {
5723
+ this.ensureConfigured();
5724
+ const basePath = this.resolveBasePath(options.path);
5725
+ try {
5726
+ const step = typeof options.step === "string" ? Number.parseInt(options.step) : options.step;
5727
+ await new Migrate(basePath, void 0, this.migrationReporter()).rollback(this.config, {
5728
+ ...options,
5729
+ step
5730
+ }, true);
5731
+ } catch (error) {
5732
+ this.output.error("ERROR: " + error);
5733
+ }
5734
+ }
5735
+ async reset(options) {
5736
+ await this.runMigrationOperation("reset", options);
5737
+ }
5738
+ async refresh(options) {
5739
+ await this.runMigrationOperation("refresh", options);
5740
+ }
5741
+ async fresh(options) {
5742
+ await this.runMigrationOperation("fresh", options);
5743
+ }
5744
+ async runMigrationOperation(operation, options) {
5745
+ this.ensureConfigured();
5746
+ const basePath = this.resolveBasePath(options.path);
5747
+ try {
5748
+ await new Migrate(basePath, void 0, this.migrationReporter())[operation](this.config, options, true);
5749
+ } catch (error) {
5750
+ this.output.error("ERROR: " + error);
5751
+ }
5752
+ }
5753
+ async status(options) {
5754
+ this.ensureConfigured();
5755
+ const basePath = this.resolveBasePath(options.path);
5756
+ try {
5757
+ const migrations = await new Migrate(basePath, void 0, this.migrationReporter()).status(this.config, options, true);
5758
+ if (migrations.length === 0) {
5759
+ this.output.info("No migrations found");
5760
+ return;
5673
5761
  }
5674
- });
5675
- await program.parseAsync(process.argv);
5676
- process.exit(0);
5762
+ Logger.twoColumnDetail(Logger.log("Migration name", "gray", false), Logger.log("Batch / Status", "gray", false));
5763
+ migrations.forEach((migration) => {
5764
+ const status = migration.ran ? `[${migration.batch}] ${Logger.log("Ran", "green", false)}` : Logger.log("Pending", "yellow", false);
5765
+ Logger.twoColumnDetail(migration.name, status);
5766
+ });
5767
+ } catch (error) {
5768
+ this.output.error("ERROR: " + error);
5769
+ }
5770
+ }
5771
+ async seed(options) {
5772
+ this.ensureConfigured();
5773
+ const basePath = this.resolveBasePath(options.path);
5774
+ try {
5775
+ const { arquebus } = await new Migrate(basePath).setupConnection({
5776
+ ...this.config,
5777
+ skipConnection: false
5778
+ });
5779
+ const seederPath = path$1.join(basePath, this.config.seeders?.path ?? "./seeders");
5780
+ await new SeederRunner(arquebus).setConnection(this.config.client).run([seederPath]);
5781
+ this.output.success("Seeders executed successfully.");
5782
+ } catch (error) {
5783
+ this.output.error("ERROR: " + error);
5784
+ }
5785
+ }
5786
+ async makeSeeder(name, options) {
5787
+ this.ensureConfigured();
5788
+ const type = options.type ?? "js";
5789
+ const seederPath = path$1.join(this.cwd, options.path ?? this.config.seeders?.path ?? "./seeders", `${Str.of(name).snake("-")}.${type}`);
5790
+ try {
5791
+ if (!options.force && await FileSystem.fileExists(seederPath)) this.output.error("ERROR: Seeder already exists.");
5792
+ await mkdir(path$1.dirname(seederPath), { recursive: true });
5793
+ await writeFile(seederPath, (await readFile(await this.resolveStub(`seeder-${type}.stub`), "utf8")).replace(/{{ name }}/g, name));
5794
+ this.output.split("INFO: Created Seeder", path$1.relative(this.cwd, seederPath));
5795
+ } catch (error) {
5796
+ this.output.error("ERROR: " + error);
5797
+ }
5798
+ }
5799
+ async makeModel(name, options) {
5800
+ this.ensureConfigured();
5801
+ const type = options.type ?? "js";
5802
+ const modelPath = path$1.join(this.cwd, options.path ?? this.config.models?.path ?? "./models", `${name.toLowerCase()}.${type}`);
5803
+ try {
5804
+ if (!options.force && await FileSystem.fileExists(modelPath)) this.output.error("ERROR: Model already exists.");
5805
+ await mkdir(path$1.dirname(modelPath), { recursive: true });
5806
+ await writeFile(modelPath, (await readFile(await this.resolveStub(`model-${type}.stub`), "utf8")).replace(/{{ name }}/g, name));
5807
+ this.output.success(`Created Model: ${modelPath}`);
5808
+ } catch (error) {
5809
+ this.output.error("ERROR: " + error);
5810
+ }
5677
5811
  }
5678
5812
  }).init();
5679
5813
  //#endregion