arkormx 0.2.8 → 0.2.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -281,8 +281,14 @@ var TableBuilder = class {
281
281
  * @returns
282
282
  */
283
283
  timestamps() {
284
- this.timestamp("createdAt", { nullable: false });
285
- this.timestamp("updatedAt", { nullable: false });
284
+ this.timestamp("createdAt", {
285
+ nullable: false,
286
+ default: "now()"
287
+ });
288
+ this.timestamp("updatedAt", {
289
+ nullable: false,
290
+ updatedAt: true
291
+ });
286
292
  return this;
287
293
  }
288
294
  /**
@@ -317,6 +323,18 @@ var TableBuilder = class {
317
323
  return this;
318
324
  }
319
325
  /**
326
+ * Sets a default value for a column.
327
+ *
328
+ * @param value The default scalar value or Prisma expression (e.g. 'now()').
329
+ * @param columnName Optional explicit column name. When omitted, applies to the latest defined column.
330
+ * @returns The current TableBuilder instance for chaining.
331
+ */
332
+ default(value, columnName) {
333
+ const column = this.resolveColumn(columnName);
334
+ column.default = value;
335
+ return this;
336
+ }
337
+ /**
320
338
  * Sets the column position to appear after another column when possible.
321
339
  *
322
340
  * @param referenceColumn The column that the target column should be placed after.
@@ -434,7 +452,8 @@ var TableBuilder = class {
434
452
  primary: options.primary,
435
453
  autoIncrement: options.autoIncrement,
436
454
  after: options.after,
437
- default: options.default
455
+ default: options.default,
456
+ updatedAt: options.updatedAt
438
457
  });
439
458
  this.latestColumnName = name;
440
459
  return this;
@@ -595,6 +614,7 @@ const resolvePrismaType = (column) => {
595
614
  */
596
615
  const formatDefaultValue = (value) => {
597
616
  if (value == null) return void 0;
617
+ if (value === "now()") return "@default(now())";
598
618
  if (typeof value === "string") return `@default("${value.replace(/"/g, "\\\"")}")`;
599
619
  if (typeof value === "number" || typeof value === "bigint") return `@default(${value})`;
600
620
  if (typeof value === "boolean") return `@default(${value ? "true" : "false"})`;
@@ -619,9 +639,10 @@ const buildFieldLine = (column) => {
619
639
  const unique = column.unique ? " @unique" : "";
620
640
  const primary = column.primary ? " @id" : "";
621
641
  const mapped = typeof column.map === "string" && column.map.trim().length > 0 ? ` @map("${column.map.replace(/"/g, "\\\"")}")` : "";
642
+ const updatedAt = column.updatedAt ? " @updatedAt" : "";
622
643
  const defaultValue = formatDefaultValue(column.default) ?? (column.type === "uuid" && column.primary ? "@default(uuid())" : void 0);
623
644
  const defaultSuffix = defaultValue ? ` ${defaultValue}` : "";
624
- return ` ${column.name} ${scalar}${nullable}${primary}${unique}${defaultSuffix}${mapped}`;
645
+ return ` ${column.name} ${scalar}${nullable}${primary}${unique}${defaultSuffix}${updatedAt}${mapped}`;
625
646
  };
626
647
  /**
627
648
  * Build a Prisma model-level @@index definition line.
package/dist/index.cjs CHANGED
@@ -41,6 +41,24 @@ let node_crypto = require("node:crypto");
41
41
  let node_url = require("node:url");
42
42
  let _h3ravel_collect_js = require("@h3ravel/collect.js");
43
43
 
44
+ //#region src/Attribute.ts
45
+ var Attribute = class Attribute {
46
+ get;
47
+ set;
48
+ constructor(options = {}) {
49
+ this.get = options.get;
50
+ this.set = options.set;
51
+ }
52
+ static make(options) {
53
+ return new Attribute(options);
54
+ }
55
+ static isAttribute(value) {
56
+ if (!value || typeof value !== "object") return false;
57
+ return value instanceof Attribute;
58
+ }
59
+ };
60
+
61
+ //#endregion
44
62
  //#region src/casts.ts
45
63
  const builtinCasts = {
46
64
  string: {
@@ -372,8 +390,14 @@ var TableBuilder = class {
372
390
  * @returns
373
391
  */
374
392
  timestamps() {
375
- this.timestamp("createdAt", { nullable: false });
376
- this.timestamp("updatedAt", { nullable: false });
393
+ this.timestamp("createdAt", {
394
+ nullable: false,
395
+ default: "now()"
396
+ });
397
+ this.timestamp("updatedAt", {
398
+ nullable: false,
399
+ updatedAt: true
400
+ });
377
401
  return this;
378
402
  }
379
403
  /**
@@ -408,6 +432,18 @@ var TableBuilder = class {
408
432
  return this;
409
433
  }
410
434
  /**
435
+ * Sets a default value for a column.
436
+ *
437
+ * @param value The default scalar value or Prisma expression (e.g. 'now()').
438
+ * @param columnName Optional explicit column name. When omitted, applies to the latest defined column.
439
+ * @returns The current TableBuilder instance for chaining.
440
+ */
441
+ default(value, columnName) {
442
+ const column = this.resolveColumn(columnName);
443
+ column.default = value;
444
+ return this;
445
+ }
446
+ /**
411
447
  * Sets the column position to appear after another column when possible.
412
448
  *
413
449
  * @param referenceColumn The column that the target column should be placed after.
@@ -525,7 +561,8 @@ var TableBuilder = class {
525
561
  primary: options.primary,
526
562
  autoIncrement: options.autoIncrement,
527
563
  after: options.after,
528
- default: options.default
564
+ default: options.default,
565
+ updatedAt: options.updatedAt
529
566
  });
530
567
  this.latestColumnName = name;
531
568
  return this;
@@ -686,6 +723,7 @@ const resolvePrismaType = (column) => {
686
723
  */
687
724
  const formatDefaultValue = (value) => {
688
725
  if (value == null) return void 0;
726
+ if (value === "now()") return "@default(now())";
689
727
  if (typeof value === "string") return `@default("${value.replace(/"/g, "\\\"")}")`;
690
728
  if (typeof value === "number" || typeof value === "bigint") return `@default(${value})`;
691
729
  if (typeof value === "boolean") return `@default(${value ? "true" : "false"})`;
@@ -710,9 +748,10 @@ const buildFieldLine = (column) => {
710
748
  const unique = column.unique ? " @unique" : "";
711
749
  const primary = column.primary ? " @id" : "";
712
750
  const mapped = typeof column.map === "string" && column.map.trim().length > 0 ? ` @map("${column.map.replace(/"/g, "\\\"")}")` : "";
751
+ const updatedAt = column.updatedAt ? " @updatedAt" : "";
713
752
  const defaultValue = formatDefaultValue(column.default) ?? (column.type === "uuid" && column.primary ? "@default(uuid())" : void 0);
714
753
  const defaultSuffix = defaultValue ? ` ${defaultValue}` : "";
715
- return ` ${column.name} ${scalar}${nullable}${primary}${unique}${defaultSuffix}${mapped}`;
754
+ return ` ${column.name} ${scalar}${nullable}${primary}${unique}${defaultSuffix}${updatedAt}${mapped}`;
716
755
  };
717
756
  /**
718
757
  * Build a Prisma model-level @@index definition line.
@@ -4893,11 +4932,15 @@ var Model = class Model {
4893
4932
  this.fill(attributes);
4894
4933
  return new Proxy(this, {
4895
4934
  get: (target, key, receiver) => {
4896
- if (typeof key !== "string" || key in target) return Reflect.get(target, key, receiver);
4935
+ if (typeof key !== "string") return Reflect.get(target, key, receiver);
4936
+ const attributeMutator = target.resolveAttributeMutator(key);
4937
+ if (key in target && !attributeMutator) return Reflect.get(target, key, receiver);
4897
4938
  return target.getAttribute(key);
4898
4939
  },
4899
4940
  set: (target, key, value, receiver) => {
4900
- if (typeof key !== "string" || key in target) return Reflect.set(target, key, value, receiver);
4941
+ if (typeof key !== "string") return Reflect.set(target, key, value, receiver);
4942
+ const attributeMutator = target.resolveAttributeMutator(key);
4943
+ if (key in target && !attributeMutator) return Reflect.set(target, key, value, receiver);
4901
4944
  target.setAttribute(key, value);
4902
4945
  return true;
4903
4946
  }
@@ -5086,18 +5129,22 @@ var Model = class Model {
5086
5129
  return this;
5087
5130
  }
5088
5131
  getAttribute(key) {
5132
+ const attributeMutator = this.resolveAttributeMutator(key);
5089
5133
  const mutator = this.resolveGetMutator(key);
5090
5134
  const cast = this.casts[key];
5091
5135
  let value = this.attributes[key];
5092
5136
  if (cast) value = resolveCast(cast).get(value);
5137
+ if (attributeMutator?.get) return attributeMutator.get.call(this, value);
5093
5138
  if (mutator) return mutator.call(this, value);
5094
5139
  return value;
5095
5140
  }
5096
5141
  setAttribute(key, value) {
5142
+ const attributeMutator = this.resolveAttributeMutator(key);
5097
5143
  const mutator = this.resolveSetMutator(key);
5098
5144
  const cast = this.casts[key];
5099
5145
  let resolved = value;
5100
- if (mutator) resolved = mutator.call(this, resolved);
5146
+ if (attributeMutator?.set) resolved = attributeMutator.set.call(this, resolved);
5147
+ else if (mutator) resolved = mutator.call(this, resolved);
5101
5148
  if (cast) resolved = resolveCast(cast).set(resolved);
5102
5149
  this.attributes[key] = resolved;
5103
5150
  return this;
@@ -5365,6 +5412,24 @@ var Model = class Model {
5365
5412
  return typeof method === "function" ? method : null;
5366
5413
  }
5367
5414
  /**
5415
+ * Resolve an Attribute object mutator method for a given key, if it exists.
5416
+ *
5417
+ * @param key
5418
+ * @returns
5419
+ */
5420
+ resolveAttributeMutator(key) {
5421
+ if (key === "constructor") return null;
5422
+ const methodName = `${(0, _h3ravel_support.str)(key).camel()}`;
5423
+ const prototype = Object.getPrototypeOf(this);
5424
+ if (!prototype) return null;
5425
+ const method = prototype[methodName];
5426
+ if (typeof method !== "function") return null;
5427
+ if (method === Model.prototype[methodName]) return null;
5428
+ const resolved = method.call(this);
5429
+ if (Attribute.isAttribute(resolved)) return resolved;
5430
+ return null;
5431
+ }
5432
+ /**
5368
5433
  * Resolve a set mutator method for a given attribute key, if it exists.
5369
5434
  *
5370
5435
  * @param key
@@ -5418,6 +5483,7 @@ var Model = class Model {
5418
5483
  //#endregion
5419
5484
  exports.ArkormCollection = ArkormCollection;
5420
5485
  exports.ArkormException = ArkormException;
5486
+ exports.Attribute = Attribute;
5421
5487
  exports.CliApp = CliApp;
5422
5488
  exports.ForeignKeyBuilder = ForeignKeyBuilder;
5423
5489
  exports.InitCommand = InitCommand;
package/dist/index.d.cts CHANGED
@@ -2,6 +2,19 @@ import { PrismaClient } from "@prisma/client";
2
2
  import { Collection } from "@h3ravel/collect.js";
3
3
  import { Command } from "@h3ravel/musket";
4
4
 
5
+ //#region src/Attribute.d.ts
6
+ interface AttributeOptions<TGet = unknown, TSet = unknown> {
7
+ get?: (value: unknown) => TGet;
8
+ set?: (value: TSet) => unknown;
9
+ }
10
+ declare class Attribute<TGet = unknown, TSet = unknown> {
11
+ readonly get?: (value: unknown) => TGet;
12
+ readonly set?: (value: TSet) => unknown;
13
+ constructor(options?: AttributeOptions<TGet, TSet>);
14
+ static make<TGet = unknown, TSet = unknown>(options: AttributeOptions<TGet, TSet>): Attribute<TGet, TSet>;
15
+ static isAttribute(value: unknown): value is Attribute;
16
+ }
17
+ //#endregion
5
18
  //#region src/types/factories.d.ts
6
19
  type FactoryAttributes = Record<string, unknown>;
7
20
  interface FactoryModelConstructor<TModel> {
@@ -22,6 +35,7 @@ interface SchemaColumn {
22
35
  autoIncrement?: boolean;
23
36
  after?: string;
24
37
  default?: unknown;
38
+ updatedAt?: boolean;
25
39
  }
26
40
  interface SchemaIndex {
27
41
  columns: string[];
@@ -872,6 +886,13 @@ declare abstract class Model<TSchema extends PrismaDelegateLike | Record<string,
872
886
  * @returns
873
887
  */
874
888
  private resolveGetMutator;
889
+ /**
890
+ * Resolve an Attribute object mutator method for a given key, if it exists.
891
+ *
892
+ * @param key
893
+ * @returns
894
+ */
895
+ private resolveAttributeMutator;
875
896
  /**
876
897
  * Resolve a set mutator method for a given attribute key, if it exists.
877
898
  *
@@ -2564,6 +2585,14 @@ declare class TableBuilder {
2564
2585
  * @returns The current TableBuilder instance for chaining.
2565
2586
  */
2566
2587
  nullable(columnName?: string): this;
2588
+ /**
2589
+ * Sets a default value for a column.
2590
+ *
2591
+ * @param value The default scalar value or Prisma expression (e.g. 'now()').
2592
+ * @param columnName Optional explicit column name. When omitted, applies to the latest defined column.
2593
+ * @returns The current TableBuilder instance for chaining.
2594
+ */
2595
+ default(value: unknown, columnName?: string): this;
2567
2596
  /**
2568
2597
  * Sets the column position to appear after another column when possible.
2569
2598
  *
@@ -3153,4 +3182,4 @@ declare class URLDriver {
3153
3182
  url(page: number): string;
3154
3183
  }
3155
3184
  //#endregion
3156
- export { ArkormCollection, ArkormException, CliApp, ForeignKeyBuilder, InitCommand, InlineFactory, LengthAwarePaginator, MIGRATION_BRAND, MakeFactoryCommand, MakeMigrationCommand, MakeModelCommand, MakeSeederCommand, MigrateCommand, MigrateRollbackCommand, Migration, MigrationHistoryCommand, Model, ModelFactory, ModelNotFoundException, ModelsSyncCommand, PRISMA_MODEL_REGEX, Paginator, PrismaDelegateMap, QueryBuilder, SEEDER_BRAND, SchemaBuilder, SeedCommand, Seeder, SeederCallArgument, SeederConstructor, SeederInput, TableBuilder, URLDriver, applyAlterTableOperation, applyCreateTableOperation, applyDropTableOperation, applyMigrationRollbackToPrismaSchema, applyMigrationToPrismaSchema, applyOperationsToPrismaSchema, buildFieldLine, buildIndexLine, buildInverseRelationLine, buildMigrationIdentity, buildMigrationRunId, buildMigrationSource, buildModelBlock, buildRelationLine, computeMigrationChecksum, configureArkormRuntime, createMigrationTimestamp, createPrismaAdapter, createPrismaDelegateMap, defineConfig, defineFactory, deriveCollectionFieldName, deriveInverseRelationAlias, deriveRelationFieldName, ensureArkormConfigLoading, escapeRegex, findAppliedMigration, findModelBlock, formatDefaultValue, formatRelationAction, generateMigrationFile, getDefaultStubsPath, getLastMigrationRun, getLatestAppliedMigrations, getMigrationPlan, getRuntimePaginationURLDriverFactory, getRuntimePrismaClient, getUserConfig, inferDelegateName, isDelegateLike, isMigrationApplied, loadArkormConfig, markMigrationApplied, markMigrationRun, pad, readAppliedMigrationsState, removeAppliedMigration, resetArkormRuntimeForTests, resolveCast, resolveMigrationClassName, resolveMigrationStateFilePath, resolvePrismaType, runMigrationWithPrisma, runPrismaCommand, toMigrationFileSlug, toModelName, writeAppliedMigrationsState };
3185
+ export { ArkormCollection, ArkormException, Attribute, AttributeOptions, CliApp, ForeignKeyBuilder, InitCommand, InlineFactory, LengthAwarePaginator, MIGRATION_BRAND, MakeFactoryCommand, MakeMigrationCommand, MakeModelCommand, MakeSeederCommand, MigrateCommand, MigrateRollbackCommand, Migration, MigrationHistoryCommand, Model, ModelFactory, ModelNotFoundException, ModelsSyncCommand, PRISMA_MODEL_REGEX, Paginator, PrismaDelegateMap, QueryBuilder, SEEDER_BRAND, SchemaBuilder, SeedCommand, Seeder, SeederCallArgument, SeederConstructor, SeederInput, TableBuilder, URLDriver, applyAlterTableOperation, applyCreateTableOperation, applyDropTableOperation, applyMigrationRollbackToPrismaSchema, applyMigrationToPrismaSchema, applyOperationsToPrismaSchema, buildFieldLine, buildIndexLine, buildInverseRelationLine, buildMigrationIdentity, buildMigrationRunId, buildMigrationSource, buildModelBlock, buildRelationLine, computeMigrationChecksum, configureArkormRuntime, createMigrationTimestamp, createPrismaAdapter, createPrismaDelegateMap, defineConfig, defineFactory, deriveCollectionFieldName, deriveInverseRelationAlias, deriveRelationFieldName, ensureArkormConfigLoading, escapeRegex, findAppliedMigration, findModelBlock, formatDefaultValue, formatRelationAction, generateMigrationFile, getDefaultStubsPath, getLastMigrationRun, getLatestAppliedMigrations, getMigrationPlan, getRuntimePaginationURLDriverFactory, getRuntimePrismaClient, getUserConfig, inferDelegateName, isDelegateLike, isMigrationApplied, loadArkormConfig, markMigrationApplied, markMigrationRun, pad, readAppliedMigrationsState, removeAppliedMigration, resetArkormRuntimeForTests, resolveCast, resolveMigrationClassName, resolveMigrationStateFilePath, resolvePrismaType, runMigrationWithPrisma, runPrismaCommand, toMigrationFileSlug, toModelName, writeAppliedMigrationsState };
package/dist/index.d.mts CHANGED
@@ -2,6 +2,19 @@ import { Command } from "@h3ravel/musket";
2
2
  import { Collection } from "@h3ravel/collect.js";
3
3
  import { PrismaClient } from "@prisma/client";
4
4
 
5
+ //#region src/Attribute.d.ts
6
+ interface AttributeOptions<TGet = unknown, TSet = unknown> {
7
+ get?: (value: unknown) => TGet;
8
+ set?: (value: TSet) => unknown;
9
+ }
10
+ declare class Attribute<TGet = unknown, TSet = unknown> {
11
+ readonly get?: (value: unknown) => TGet;
12
+ readonly set?: (value: TSet) => unknown;
13
+ constructor(options?: AttributeOptions<TGet, TSet>);
14
+ static make<TGet = unknown, TSet = unknown>(options: AttributeOptions<TGet, TSet>): Attribute<TGet, TSet>;
15
+ static isAttribute(value: unknown): value is Attribute;
16
+ }
17
+ //#endregion
5
18
  //#region src/types/factories.d.ts
6
19
  type FactoryAttributes = Record<string, unknown>;
7
20
  interface FactoryModelConstructor<TModel> {
@@ -22,6 +35,7 @@ interface SchemaColumn {
22
35
  autoIncrement?: boolean;
23
36
  after?: string;
24
37
  default?: unknown;
38
+ updatedAt?: boolean;
25
39
  }
26
40
  interface SchemaIndex {
27
41
  columns: string[];
@@ -872,6 +886,13 @@ declare abstract class Model<TSchema extends PrismaDelegateLike | Record<string,
872
886
  * @returns
873
887
  */
874
888
  private resolveGetMutator;
889
+ /**
890
+ * Resolve an Attribute object mutator method for a given key, if it exists.
891
+ *
892
+ * @param key
893
+ * @returns
894
+ */
895
+ private resolveAttributeMutator;
875
896
  /**
876
897
  * Resolve a set mutator method for a given attribute key, if it exists.
877
898
  *
@@ -2564,6 +2585,14 @@ declare class TableBuilder {
2564
2585
  * @returns The current TableBuilder instance for chaining.
2565
2586
  */
2566
2587
  nullable(columnName?: string): this;
2588
+ /**
2589
+ * Sets a default value for a column.
2590
+ *
2591
+ * @param value The default scalar value or Prisma expression (e.g. 'now()').
2592
+ * @param columnName Optional explicit column name. When omitted, applies to the latest defined column.
2593
+ * @returns The current TableBuilder instance for chaining.
2594
+ */
2595
+ default(value: unknown, columnName?: string): this;
2567
2596
  /**
2568
2597
  * Sets the column position to appear after another column when possible.
2569
2598
  *
@@ -3153,4 +3182,4 @@ declare class URLDriver {
3153
3182
  url(page: number): string;
3154
3183
  }
3155
3184
  //#endregion
3156
- export { ArkormCollection, ArkormException, CliApp, ForeignKeyBuilder, InitCommand, InlineFactory, LengthAwarePaginator, MIGRATION_BRAND, MakeFactoryCommand, MakeMigrationCommand, MakeModelCommand, MakeSeederCommand, MigrateCommand, MigrateRollbackCommand, Migration, MigrationHistoryCommand, Model, ModelFactory, ModelNotFoundException, ModelsSyncCommand, PRISMA_MODEL_REGEX, Paginator, PrismaDelegateMap, QueryBuilder, SEEDER_BRAND, SchemaBuilder, SeedCommand, Seeder, SeederCallArgument, SeederConstructor, SeederInput, TableBuilder, URLDriver, applyAlterTableOperation, applyCreateTableOperation, applyDropTableOperation, applyMigrationRollbackToPrismaSchema, applyMigrationToPrismaSchema, applyOperationsToPrismaSchema, buildFieldLine, buildIndexLine, buildInverseRelationLine, buildMigrationIdentity, buildMigrationRunId, buildMigrationSource, buildModelBlock, buildRelationLine, computeMigrationChecksum, configureArkormRuntime, createMigrationTimestamp, createPrismaAdapter, createPrismaDelegateMap, defineConfig, defineFactory, deriveCollectionFieldName, deriveInverseRelationAlias, deriveRelationFieldName, ensureArkormConfigLoading, escapeRegex, findAppliedMigration, findModelBlock, formatDefaultValue, formatRelationAction, generateMigrationFile, getDefaultStubsPath, getLastMigrationRun, getLatestAppliedMigrations, getMigrationPlan, getRuntimePaginationURLDriverFactory, getRuntimePrismaClient, getUserConfig, inferDelegateName, isDelegateLike, isMigrationApplied, loadArkormConfig, markMigrationApplied, markMigrationRun, pad, readAppliedMigrationsState, removeAppliedMigration, resetArkormRuntimeForTests, resolveCast, resolveMigrationClassName, resolveMigrationStateFilePath, resolvePrismaType, runMigrationWithPrisma, runPrismaCommand, toMigrationFileSlug, toModelName, writeAppliedMigrationsState };
3185
+ export { ArkormCollection, ArkormException, Attribute, AttributeOptions, CliApp, ForeignKeyBuilder, InitCommand, InlineFactory, LengthAwarePaginator, MIGRATION_BRAND, MakeFactoryCommand, MakeMigrationCommand, MakeModelCommand, MakeSeederCommand, MigrateCommand, MigrateRollbackCommand, Migration, MigrationHistoryCommand, Model, ModelFactory, ModelNotFoundException, ModelsSyncCommand, PRISMA_MODEL_REGEX, Paginator, PrismaDelegateMap, QueryBuilder, SEEDER_BRAND, SchemaBuilder, SeedCommand, Seeder, SeederCallArgument, SeederConstructor, SeederInput, TableBuilder, URLDriver, applyAlterTableOperation, applyCreateTableOperation, applyDropTableOperation, applyMigrationRollbackToPrismaSchema, applyMigrationToPrismaSchema, applyOperationsToPrismaSchema, buildFieldLine, buildIndexLine, buildInverseRelationLine, buildMigrationIdentity, buildMigrationRunId, buildMigrationSource, buildModelBlock, buildRelationLine, computeMigrationChecksum, configureArkormRuntime, createMigrationTimestamp, createPrismaAdapter, createPrismaDelegateMap, defineConfig, defineFactory, deriveCollectionFieldName, deriveInverseRelationAlias, deriveRelationFieldName, ensureArkormConfigLoading, escapeRegex, findAppliedMigration, findModelBlock, formatDefaultValue, formatRelationAction, generateMigrationFile, getDefaultStubsPath, getLastMigrationRun, getLatestAppliedMigrations, getMigrationPlan, getRuntimePaginationURLDriverFactory, getRuntimePrismaClient, getUserConfig, inferDelegateName, isDelegateLike, isMigrationApplied, loadArkormConfig, markMigrationApplied, markMigrationRun, pad, readAppliedMigrationsState, removeAppliedMigration, resetArkormRuntimeForTests, resolveCast, resolveMigrationClassName, resolveMigrationStateFilePath, resolvePrismaType, runMigrationWithPrisma, runPrismaCommand, toMigrationFileSlug, toModelName, writeAppliedMigrationsState };
package/dist/index.mjs CHANGED
@@ -12,6 +12,24 @@ import { createHash } from "node:crypto";
12
12
  import { pathToFileURL as pathToFileURL$1 } from "node:url";
13
13
  import { Collection } from "@h3ravel/collect.js";
14
14
 
15
+ //#region src/Attribute.ts
16
+ var Attribute = class Attribute {
17
+ get;
18
+ set;
19
+ constructor(options = {}) {
20
+ this.get = options.get;
21
+ this.set = options.set;
22
+ }
23
+ static make(options) {
24
+ return new Attribute(options);
25
+ }
26
+ static isAttribute(value) {
27
+ if (!value || typeof value !== "object") return false;
28
+ return value instanceof Attribute;
29
+ }
30
+ };
31
+
32
+ //#endregion
15
33
  //#region src/casts.ts
16
34
  const builtinCasts = {
17
35
  string: {
@@ -343,8 +361,14 @@ var TableBuilder = class {
343
361
  * @returns
344
362
  */
345
363
  timestamps() {
346
- this.timestamp("createdAt", { nullable: false });
347
- this.timestamp("updatedAt", { nullable: false });
364
+ this.timestamp("createdAt", {
365
+ nullable: false,
366
+ default: "now()"
367
+ });
368
+ this.timestamp("updatedAt", {
369
+ nullable: false,
370
+ updatedAt: true
371
+ });
348
372
  return this;
349
373
  }
350
374
  /**
@@ -379,6 +403,18 @@ var TableBuilder = class {
379
403
  return this;
380
404
  }
381
405
  /**
406
+ * Sets a default value for a column.
407
+ *
408
+ * @param value The default scalar value or Prisma expression (e.g. 'now()').
409
+ * @param columnName Optional explicit column name. When omitted, applies to the latest defined column.
410
+ * @returns The current TableBuilder instance for chaining.
411
+ */
412
+ default(value, columnName) {
413
+ const column = this.resolveColumn(columnName);
414
+ column.default = value;
415
+ return this;
416
+ }
417
+ /**
382
418
  * Sets the column position to appear after another column when possible.
383
419
  *
384
420
  * @param referenceColumn The column that the target column should be placed after.
@@ -496,7 +532,8 @@ var TableBuilder = class {
496
532
  primary: options.primary,
497
533
  autoIncrement: options.autoIncrement,
498
534
  after: options.after,
499
- default: options.default
535
+ default: options.default,
536
+ updatedAt: options.updatedAt
500
537
  });
501
538
  this.latestColumnName = name;
502
539
  return this;
@@ -657,6 +694,7 @@ const resolvePrismaType = (column) => {
657
694
  */
658
695
  const formatDefaultValue = (value) => {
659
696
  if (value == null) return void 0;
697
+ if (value === "now()") return "@default(now())";
660
698
  if (typeof value === "string") return `@default("${value.replace(/"/g, "\\\"")}")`;
661
699
  if (typeof value === "number" || typeof value === "bigint") return `@default(${value})`;
662
700
  if (typeof value === "boolean") return `@default(${value ? "true" : "false"})`;
@@ -681,9 +719,10 @@ const buildFieldLine = (column) => {
681
719
  const unique = column.unique ? " @unique" : "";
682
720
  const primary = column.primary ? " @id" : "";
683
721
  const mapped = typeof column.map === "string" && column.map.trim().length > 0 ? ` @map("${column.map.replace(/"/g, "\\\"")}")` : "";
722
+ const updatedAt = column.updatedAt ? " @updatedAt" : "";
684
723
  const defaultValue = formatDefaultValue(column.default) ?? (column.type === "uuid" && column.primary ? "@default(uuid())" : void 0);
685
724
  const defaultSuffix = defaultValue ? ` ${defaultValue}` : "";
686
- return ` ${column.name} ${scalar}${nullable}${primary}${unique}${defaultSuffix}${mapped}`;
725
+ return ` ${column.name} ${scalar}${nullable}${primary}${unique}${defaultSuffix}${updatedAt}${mapped}`;
687
726
  };
688
727
  /**
689
728
  * Build a Prisma model-level @@index definition line.
@@ -4864,11 +4903,15 @@ var Model = class Model {
4864
4903
  this.fill(attributes);
4865
4904
  return new Proxy(this, {
4866
4905
  get: (target, key, receiver) => {
4867
- if (typeof key !== "string" || key in target) return Reflect.get(target, key, receiver);
4906
+ if (typeof key !== "string") return Reflect.get(target, key, receiver);
4907
+ const attributeMutator = target.resolveAttributeMutator(key);
4908
+ if (key in target && !attributeMutator) return Reflect.get(target, key, receiver);
4868
4909
  return target.getAttribute(key);
4869
4910
  },
4870
4911
  set: (target, key, value, receiver) => {
4871
- if (typeof key !== "string" || key in target) return Reflect.set(target, key, value, receiver);
4912
+ if (typeof key !== "string") return Reflect.set(target, key, value, receiver);
4913
+ const attributeMutator = target.resolveAttributeMutator(key);
4914
+ if (key in target && !attributeMutator) return Reflect.set(target, key, value, receiver);
4872
4915
  target.setAttribute(key, value);
4873
4916
  return true;
4874
4917
  }
@@ -5057,18 +5100,22 @@ var Model = class Model {
5057
5100
  return this;
5058
5101
  }
5059
5102
  getAttribute(key) {
5103
+ const attributeMutator = this.resolveAttributeMutator(key);
5060
5104
  const mutator = this.resolveGetMutator(key);
5061
5105
  const cast = this.casts[key];
5062
5106
  let value = this.attributes[key];
5063
5107
  if (cast) value = resolveCast(cast).get(value);
5108
+ if (attributeMutator?.get) return attributeMutator.get.call(this, value);
5064
5109
  if (mutator) return mutator.call(this, value);
5065
5110
  return value;
5066
5111
  }
5067
5112
  setAttribute(key, value) {
5113
+ const attributeMutator = this.resolveAttributeMutator(key);
5068
5114
  const mutator = this.resolveSetMutator(key);
5069
5115
  const cast = this.casts[key];
5070
5116
  let resolved = value;
5071
- if (mutator) resolved = mutator.call(this, resolved);
5117
+ if (attributeMutator?.set) resolved = attributeMutator.set.call(this, resolved);
5118
+ else if (mutator) resolved = mutator.call(this, resolved);
5072
5119
  if (cast) resolved = resolveCast(cast).set(resolved);
5073
5120
  this.attributes[key] = resolved;
5074
5121
  return this;
@@ -5336,6 +5383,24 @@ var Model = class Model {
5336
5383
  return typeof method === "function" ? method : null;
5337
5384
  }
5338
5385
  /**
5386
+ * Resolve an Attribute object mutator method for a given key, if it exists.
5387
+ *
5388
+ * @param key
5389
+ * @returns
5390
+ */
5391
+ resolveAttributeMutator(key) {
5392
+ if (key === "constructor") return null;
5393
+ const methodName = `${str(key).camel()}`;
5394
+ const prototype = Object.getPrototypeOf(this);
5395
+ if (!prototype) return null;
5396
+ const method = prototype[methodName];
5397
+ if (typeof method !== "function") return null;
5398
+ if (method === Model.prototype[methodName]) return null;
5399
+ const resolved = method.call(this);
5400
+ if (Attribute.isAttribute(resolved)) return resolved;
5401
+ return null;
5402
+ }
5403
+ /**
5339
5404
  * Resolve a set mutator method for a given attribute key, if it exists.
5340
5405
  *
5341
5406
  * @param key
@@ -5387,4 +5452,4 @@ var Model = class Model {
5387
5452
  };
5388
5453
 
5389
5454
  //#endregion
5390
- export { ArkormCollection, ArkormException, CliApp, ForeignKeyBuilder, InitCommand, InlineFactory, LengthAwarePaginator, MIGRATION_BRAND, MakeFactoryCommand, MakeMigrationCommand, MakeModelCommand, MakeSeederCommand, MigrateCommand, MigrateRollbackCommand, Migration, MigrationHistoryCommand, Model, ModelFactory, ModelNotFoundException, ModelsSyncCommand, PRISMA_MODEL_REGEX, Paginator, QueryBuilder, SEEDER_BRAND, SchemaBuilder, SeedCommand, Seeder, TableBuilder, URLDriver, applyAlterTableOperation, applyCreateTableOperation, applyDropTableOperation, applyMigrationRollbackToPrismaSchema, applyMigrationToPrismaSchema, applyOperationsToPrismaSchema, buildFieldLine, buildIndexLine, buildInverseRelationLine, buildMigrationIdentity, buildMigrationRunId, buildMigrationSource, buildModelBlock, buildRelationLine, computeMigrationChecksum, configureArkormRuntime, createMigrationTimestamp, createPrismaAdapter, createPrismaDelegateMap, defineConfig, defineFactory, deriveCollectionFieldName, deriveInverseRelationAlias, deriveRelationFieldName, ensureArkormConfigLoading, escapeRegex, findAppliedMigration, findModelBlock, formatDefaultValue, formatRelationAction, generateMigrationFile, getDefaultStubsPath, getLastMigrationRun, getLatestAppliedMigrations, getMigrationPlan, getRuntimePaginationURLDriverFactory, getRuntimePrismaClient, getUserConfig, inferDelegateName, isDelegateLike, isMigrationApplied, loadArkormConfig, markMigrationApplied, markMigrationRun, pad, readAppliedMigrationsState, removeAppliedMigration, resetArkormRuntimeForTests, resolveCast, resolveMigrationClassName, resolveMigrationStateFilePath, resolvePrismaType, runMigrationWithPrisma, runPrismaCommand, toMigrationFileSlug, toModelName, writeAppliedMigrationsState };
5455
+ export { ArkormCollection, ArkormException, Attribute, CliApp, ForeignKeyBuilder, InitCommand, InlineFactory, LengthAwarePaginator, MIGRATION_BRAND, MakeFactoryCommand, MakeMigrationCommand, MakeModelCommand, MakeSeederCommand, MigrateCommand, MigrateRollbackCommand, Migration, MigrationHistoryCommand, Model, ModelFactory, ModelNotFoundException, ModelsSyncCommand, PRISMA_MODEL_REGEX, Paginator, QueryBuilder, SEEDER_BRAND, SchemaBuilder, SeedCommand, Seeder, TableBuilder, URLDriver, applyAlterTableOperation, applyCreateTableOperation, applyDropTableOperation, applyMigrationRollbackToPrismaSchema, applyMigrationToPrismaSchema, applyOperationsToPrismaSchema, buildFieldLine, buildIndexLine, buildInverseRelationLine, buildMigrationIdentity, buildMigrationRunId, buildMigrationSource, buildModelBlock, buildRelationLine, computeMigrationChecksum, configureArkormRuntime, createMigrationTimestamp, createPrismaAdapter, createPrismaDelegateMap, defineConfig, defineFactory, deriveCollectionFieldName, deriveInverseRelationAlias, deriveRelationFieldName, ensureArkormConfigLoading, escapeRegex, findAppliedMigration, findModelBlock, formatDefaultValue, formatRelationAction, generateMigrationFile, getDefaultStubsPath, getLastMigrationRun, getLatestAppliedMigrations, getMigrationPlan, getRuntimePaginationURLDriverFactory, getRuntimePrismaClient, getUserConfig, inferDelegateName, isDelegateLike, isMigrationApplied, loadArkormConfig, markMigrationApplied, markMigrationRun, pad, readAppliedMigrationsState, removeAppliedMigration, resetArkormRuntimeForTests, resolveCast, resolveMigrationClassName, resolveMigrationStateFilePath, resolvePrismaType, runMigrationWithPrisma, runPrismaCommand, toMigrationFileSlug, toModelName, writeAppliedMigrationsState };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arkormx",
3
- "version": "0.2.8",
3
+ "version": "0.2.10",
4
4
  "description": "Modern TypeScript-first ORM for Node.js.",
5
5
  "keywords": [
6
6
  "orm",