@afora/core 0.0.5 → 0.0.6

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 (33) hide show
  1. package/README.md +2 -0
  2. package/dist/core/application/types/application.interface.d.ts +45 -11
  3. package/dist/core/blueprint/types/slice.interface.d.ts +5 -2
  4. package/dist/core/entity/abstract-entity.d.ts +1 -1
  5. package/dist/core/entity/types/entity.interface.d.ts +13 -7
  6. package/dist/core/exception/exception.d.ts +10 -1
  7. package/dist/core/output/status.d.ts +2 -2
  8. package/dist/core/property/property.d.ts +4 -4
  9. package/dist/core/property/types/optional-property.type.d.ts +2 -2
  10. package/dist/core/property/types/property-type.interface.d.ts +17 -0
  11. package/dist/core/record/abstract-record.d.ts +4 -4
  12. package/dist/core/record/exceptions.d.ts +2 -0
  13. package/dist/core/record/name.d.ts +16 -0
  14. package/dist/core/record/record.d.ts +4 -3
  15. package/dist/core/record/types/plugin.interface.d.ts +11 -0
  16. package/dist/core/record/types/record.interface.d.ts +71 -10
  17. package/dist/core/repository/cursor.d.ts +13 -0
  18. package/dist/core/repository/exceptions.d.ts +10 -0
  19. package/dist/core/repository/query.d.ts +4 -4
  20. package/dist/core/repository/repository.d.ts +1 -1
  21. package/dist/core/repository/types/query.interface.d.ts +37 -0
  22. package/dist/core/repository/types/repository.interface.d.ts +10 -6
  23. package/dist/core/use-case/steps/types/steps.interface.d.ts +1 -1
  24. package/dist/experimental.js +3 -2
  25. package/dist/{index-hn82hm31.js → index-3nd9bjnc.js} +69 -10
  26. package/dist/{index-8m80wjzf.js → index-gbgc40xe.js} +188 -39
  27. package/dist/index.d.ts +7 -6
  28. package/dist/index.js +8 -2
  29. package/dist/std/properties/password.d.ts +5 -1
  30. package/dist/std/record-plugins.d.ts +5 -5
  31. package/dist/testing/index.js +91 -2
  32. package/dist/testing/provider-contract.d.ts +5 -0
  33. package/package.json +1 -1
@@ -9,6 +9,8 @@ import {
9
9
  isBlueprint2,
10
10
  isRecordClass2,
11
11
  recordFieldOf2,
12
+ recordNameOf2,
13
+ declaredRecordNameOf,
12
14
  isBlueprintList2,
13
15
  UNEXPECTED_ERROR2,
14
16
  Exception2,
@@ -40,7 +42,7 @@ import {
40
42
  exports_exceptions3,
41
43
  propertyOf2,
42
44
  blueprintBuilderOf2
43
- } from "./index-hn82hm31.js";
45
+ } from "./index-3nd9bjnc.js";
44
46
 
45
47
  // src/core/environment/environment.ts
46
48
  var exports_environment = {};
@@ -83,6 +85,7 @@ __export(exports_exceptions6, {
83
85
  // src/core/repository/exceptions.ts
84
86
  var exports_exceptions7 = {};
85
87
  __export(exports_exceptions7, {
88
+ InvalidRepositoryCursor: () => InvalidRepositoryCursor2,
86
89
  InvalidRepositoryData: () => InvalidRepositoryData2,
87
90
  InvalidRepositoryDeclaration: () => InvalidRepositoryDeclaration2,
88
91
  InvalidRepositoryEntity: () => InvalidRepositoryEntity2,
@@ -640,7 +643,7 @@ function clockOf(entity) {
640
643
  function assertAlive(entity) {
641
644
  if (entity.isDeleted) {
642
645
  throw new DeletedEntity2({
643
- source: entity.constructor.name,
646
+ source: recordNameOf2(entity.constructor),
644
647
  details: { id: identityOf(entity).id }
645
648
  });
646
649
  }
@@ -690,7 +693,7 @@ class AbstractEntity2 extends AbstractRecord2 {
690
693
  const name = String(key);
691
694
  if (ENTITY_IDENTITY_KEYS2.includes(name)) {
692
695
  throw new ImmutableEntityKey2({
693
- source: this.constructor.name,
696
+ source: recordNameOf2(this.constructor),
694
697
  details: { key: name }
695
698
  });
696
699
  }
@@ -715,6 +718,13 @@ var InvalidRepositoryQuery2 = exceptionOf2({
715
718
  name: "InvalidRepositoryQuery",
716
719
  message: ({ reason }) => reason
717
720
  });
721
+ var InvalidRepositoryCursor2 = exceptionOf2({
722
+ layer: "repository" /* Repository */,
723
+ name: "InvalidRepositoryCursor",
724
+ message: ({
725
+ reason
726
+ }) => reason
727
+ });
718
728
  var InvalidRepositoryDeclaration2 = exceptionOf2({
719
729
  layer: "repository" /* Repository */,
720
730
  name: "InvalidRepositoryDeclaration",
@@ -741,6 +751,90 @@ var RepositoryEntityNotFound2 = exceptionOf2({
741
751
  message: ({ id }, source) => `"${source}" holds no entity of id "${id}".`
742
752
  });
743
753
 
754
+ // src/core/repository/cursor.ts
755
+ var VERSION = 1;
756
+ var signatureOf = (orders) => orders.map(({ key, direction = "asc" }) => `${key}:${direction}`);
757
+ function pack(value) {
758
+ if (value === undefined || value === null)
759
+ return null;
760
+ if (value instanceof Date)
761
+ return { d: value.toISOString() };
762
+ if (typeof value === "bigint")
763
+ return { b: value.toString() };
764
+ return value;
765
+ }
766
+ function unpack(value) {
767
+ if (value === null)
768
+ return;
769
+ if (["string", "number", "boolean"].includes(typeof value))
770
+ return value;
771
+ if (typeof value === "object") {
772
+ const { d, b } = value;
773
+ const keys = Object.keys(value);
774
+ if (keys.length === 1 && typeof d === "string") {
775
+ const date = new Date(d);
776
+ if (!Number.isNaN(date.getTime()))
777
+ return date;
778
+ }
779
+ if (keys.length === 1 && typeof b === "string" && /^-?\d+$/.test(b))
780
+ return BigInt(b);
781
+ }
782
+ throw new SyntaxError("value");
783
+ }
784
+ function encodeText(text) {
785
+ let binary = "";
786
+ for (const byte of new TextEncoder().encode(text))
787
+ binary += String.fromCharCode(byte);
788
+ return btoa(binary).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/, "");
789
+ }
790
+ function decodeText(encoded) {
791
+ if (!/^[A-Za-z0-9_-]+$/.test(encoded))
792
+ throw new SyntaxError("alphabet");
793
+ const binary = atob(encoded.replaceAll("-", "+").replaceAll("_", "/"));
794
+ return new TextDecoder("utf-8", { fatal: true }).decode(Uint8Array.from(binary, (char) => char.charCodeAt(0)));
795
+ }
796
+ function encodeCursor(orders, row) {
797
+ const payload = {
798
+ v: VERSION,
799
+ k: signatureOf(orders),
800
+ a: orders.map(({ key }) => pack(row[key]))
801
+ };
802
+ return encodeText(JSON.stringify(payload));
803
+ }
804
+ function decodeCursor(source, orders, cursor) {
805
+ const fail = (reason) => {
806
+ throw new InvalidRepositoryCursor2({
807
+ source,
808
+ details: {
809
+ reason,
810
+ issues: [
811
+ { code: "invalid_value", path: ["after"], message: reason, source }
812
+ ]
813
+ }
814
+ });
815
+ };
816
+ if (typeof cursor !== "string" || cursor === "")
817
+ return fail("Expected a cursor given by findCursor.");
818
+ let payload;
819
+ let values;
820
+ try {
821
+ payload = JSON.parse(decodeText(cursor));
822
+ if (typeof payload !== "object" || payload === null)
823
+ throw new SyntaxError;
824
+ if (!Array.isArray(payload.k) || !Array.isArray(payload.a))
825
+ throw new SyntaxError;
826
+ values = payload.a.map(unpack);
827
+ } catch {
828
+ return fail("The cursor is not one given by findCursor.");
829
+ }
830
+ if (payload.v !== VERSION)
831
+ return fail("The cursor was made by another version.");
832
+ const expected = signatureOf(orders);
833
+ if (payload.k?.length !== expected.length || values.length !== expected.length || expected.some((key, index) => payload.k?.[index] !== key))
834
+ return fail("The cursor was made for another orderBy.");
835
+ return values;
836
+ }
837
+
744
838
  // src/core/json.ts
745
839
  function frozenJson(value, subject, fail, seen = new Set) {
746
840
  if (value === null || typeof value === "string" || typeof value === "boolean")
@@ -798,7 +892,8 @@ function plain(value) {
798
892
  function isMembership(value) {
799
893
  return plain(value) && Object.keys(value).length === 1 && Array.isArray(value.in);
800
894
  }
801
- function prepareQuery(context, input = {}, map = (_key, value) => value) {
895
+ var QUERY_OPTIONS = ["where", "orderBy", "limit", "offset", "withDeleted"];
896
+ function prepareQuery(context, input = {}, map = (_key, value) => value, options = QUERY_OPTIONS) {
802
897
  const fail = (reason) => {
803
898
  throw new InvalidRepositoryQuery2({
804
899
  source: context.name,
@@ -808,7 +903,7 @@ function prepareQuery(context, input = {}, map = (_key, value) => value) {
808
903
  if (!plain(input))
809
904
  return fail("Expected a query object.");
810
905
  for (const key of Object.keys(input))
811
- if (!["where", "orderBy", "limit", "offset", "withDeleted"].includes(key))
906
+ if (!options.includes(key))
812
907
  fail(`Unknown query option "${key}".`);
813
908
  const properties = context.entity.blueprint.properties;
814
909
  const keyOf = (key) => {
@@ -890,26 +985,32 @@ function compareScalars(a, b) {
890
985
  ];
891
986
  return x < y ? -1 : x > y ? 1 : 0;
892
987
  }
988
+ function compareRows(orders, a, b) {
989
+ for (const { key, direction } of orders) {
990
+ const [x, y] = [a[key], b[key]];
991
+ const [missingX, missingY] = [
992
+ x === undefined || x === null,
993
+ y === undefined || y === null
994
+ ];
995
+ let result = missingX || missingY ? Number(!missingX) - Number(!missingY) : compareScalars(x, y);
996
+ if (direction === "desc")
997
+ result = -result;
998
+ if (result !== 0)
999
+ return result;
1000
+ }
1001
+ return 0;
1002
+ }
893
1003
  function orderRows(rows, query) {
894
1004
  const orders = query.orderBy ?? [];
895
- return [...rows].sort((a, b) => {
896
- for (const { key, direction } of orders) {
897
- const [x, y] = [a[key], b[key]];
898
- const [missingX, missingY] = [
899
- x === undefined || x === null,
900
- y === undefined || y === null
901
- ];
902
- let result = missingX || missingY ? Number(!missingX) - Number(!missingY) : compareScalars(x, y);
903
- if (direction === "desc")
904
- result = -result;
905
- if (result !== 0)
906
- return result;
907
- }
908
- return 0;
909
- });
1005
+ return [...rows].sort((a, b) => compareRows(orders, a, b));
1006
+ }
1007
+ function rowsAfter(rows, orders, after) {
1008
+ const position = Object.fromEntries(orders.map(({ key }, index) => [key, after[index]]));
1009
+ return rows.filter((row) => compareRows(orders, row, position) > 0);
910
1010
  }
911
1011
  function selectRows(rows, query) {
912
- const matched = orderRows([...rows].filter((data) => matchesQuery(data, query)), query);
1012
+ const ordered = orderRows([...rows].filter((data) => matchesQuery(data, query)), query);
1013
+ const matched = query.after === undefined ? ordered : rowsAfter(ordered, query.orderBy ?? [], query.after);
913
1014
  const start = query.offset ?? 0;
914
1015
  return matched.slice(start, query.limit === undefined ? undefined : start + query.limit);
915
1016
  }
@@ -961,7 +1062,7 @@ function scopeOf(initial, root) {
961
1062
  }
962
1063
  };
963
1064
  const provider = {
964
- capabilities: Object.freeze({ transactions: true }),
1065
+ capabilities: Object.freeze({ transactions: true, keyset: true }),
965
1066
  findOne: (context, query = {}) => whenIdle(() => {
966
1067
  const [first] = selectRows(tableOf(context).values(), {
967
1068
  ...query,
@@ -1193,7 +1294,7 @@ function relationsOf(name, entity, relations) {
1193
1294
  if (!state)
1194
1295
  return invalid("Expected relations made by repositoryOf.");
1195
1296
  if (related.some((other) => other.entity === state.entity)) {
1196
- return invalid(`Relation "${state.entity.name}" is duplicated.`);
1297
+ return invalid(`Relation "${recordNameOf2(state.entity)}" is duplicated.`);
1197
1298
  }
1198
1299
  if (typeof state.provider.findMany !== "function") {
1199
1300
  return invalid(`The provider of "${state.name}" has no "findMany" to load it.`);
@@ -1206,10 +1307,10 @@ function relationsOf(name, entity, relations) {
1206
1307
  const matches = related.filter((state) => state.entity === target || state.entity.prototype instanceof target);
1207
1308
  const exact = matches.find((state) => state.entity === target);
1208
1309
  if (!exact && matches.length === 0) {
1209
- return invalid(`Missing relation: no repository of "${target.name}".`);
1310
+ return invalid(`Missing relation: no repository of "${recordNameOf2(target)}".`);
1210
1311
  }
1211
1312
  if (!exact && matches.length > 1) {
1212
- return invalid(`Relation "${target.name}" matches more than one repository.`);
1313
+ return invalid(`Relation "${recordNameOf2(target)}" matches more than one repository.`);
1213
1314
  }
1214
1315
  const state = exact ?? matches[0];
1215
1316
  map.set(target, state);
@@ -1217,7 +1318,7 @@ function relationsOf(name, entity, relations) {
1217
1318
  }
1218
1319
  for (const state of related) {
1219
1320
  if (!used.has(state)) {
1220
- return invalid(`Relation "${state.entity.name}" is not held by ${entity.name}.`);
1321
+ return invalid(`Relation "${recordNameOf2(state.entity)}" is not held by ${recordNameOf2(entity)}.`);
1221
1322
  }
1222
1323
  }
1223
1324
  return map;
@@ -1368,6 +1469,44 @@ var findPage = action(async (self, query) => {
1368
1469
  ]);
1369
1470
  return { items: await self.hydrateMany(rows), total, limit, offset };
1370
1471
  });
1472
+ var CURSOR_OPTIONS = ["where", "orderBy", "limit", "withDeleted", "after"];
1473
+ var findCursor = action(async (self, query = {}) => {
1474
+ const { context } = self;
1475
+ const fail = (reason) => {
1476
+ throw new InvalidRepositoryQuery2({
1477
+ source: context.name,
1478
+ details: { reason }
1479
+ });
1480
+ };
1481
+ const prepared = prepareQuery(context, query, (key, value) => queryValueOf(context, key, value), CURSOR_OPTIONS);
1482
+ const { after } = query;
1483
+ const { where, limit = 20 } = prepared;
1484
+ if (limit < 1)
1485
+ fail("Expected a positive integer for limit.");
1486
+ const withDeleted = prepared.withDeleted ?? stateOf(self).deletion === "hard";
1487
+ const declared = prepared.orderBy ?? [];
1488
+ const orderBy = declared.some(({ key }) => key === "id") ? declared : [...declared, { key: "id", direction: "asc" }];
1489
+ for (const { key } of orderBy) {
1490
+ if (context.entity.options.sensitive.includes(key))
1491
+ fail(`"${key}" is sensitive and cannot order a cursor.`);
1492
+ }
1493
+ if (self.provider.capabilities?.keyset !== true)
1494
+ fail("The provider does not read by cursor (capabilities.keyset).");
1495
+ const rows = await self.provider.findMany(context, {
1496
+ where,
1497
+ orderBy,
1498
+ withDeleted,
1499
+ limit: limit + 1,
1500
+ ...after === undefined ? {} : { after: decodeCursor(context.name, orderBy, after) }
1501
+ });
1502
+ const page = rows.slice(0, limit);
1503
+ const last = page.at(-1);
1504
+ return {
1505
+ items: await self.hydrateMany(page),
1506
+ limit,
1507
+ next: rows.length > limit && last !== undefined ? encodeCursor(orderBy, last) : undefined
1508
+ };
1509
+ });
1371
1510
  var create = action(async (self, input) => {
1372
1511
  const { entity: Entity } = self.context;
1373
1512
  const entity = input instanceof Entity ? input : new Entity(input);
@@ -1412,7 +1551,8 @@ var NEEDS = {
1412
1551
  count: ["count"],
1413
1552
  findMany: ["findMany"],
1414
1553
  exists: ["findOne"],
1415
- findPage: ["findMany", "count"]
1554
+ findPage: ["findMany", "count"],
1555
+ findCursor: ["findMany"]
1416
1556
  };
1417
1557
  function capitalize(key) {
1418
1558
  return `${key.charAt(0).toUpperCase()}${key.slice(1)}`;
@@ -1438,7 +1578,7 @@ function repositoryOf2(settings) {
1438
1578
  if (!isEntityClass2(entity) || !(EntityUniqueKeys2 in entity)) {
1439
1579
  invalid3("repositoryOf", "Expected an entity class made by entityOf.");
1440
1580
  }
1441
- const name = `${entity.name}Repository`;
1581
+ const name = `${recordNameOf2(entity)}Repository`;
1442
1582
  const deletion = settings.deletion ?? "hard";
1443
1583
  if (deletion !== "hard" && deletion !== "soft") {
1444
1584
  invalid3(name, 'Expected deletion to be "hard" or "soft".');
@@ -1468,13 +1608,14 @@ function repositoryOf2(settings) {
1468
1608
  methods.set("findMany", ["findMany", findMany]);
1469
1609
  methods.set("exists", ["exists", exists]);
1470
1610
  methods.set("findPage", ["findPage", findPage]);
1611
+ methods.set("findCursor", ["findCursor", findCursor]);
1471
1612
 
1472
1613
  class DeclaredRepository extends AbstractRepository2 {
1473
1614
  }
1474
1615
  for (const name_ of new Set(actions)) {
1475
1616
  const method = typeof name_ === "string" ? methods.get(name_) : undefined;
1476
1617
  if (!method)
1477
- invalid3(name, unknownAction(entity.name, String(name_), methods));
1618
+ invalid3(name, unknownAction(recordNameOf2(entity), String(name_), methods));
1478
1619
  const [kind, implementation] = method;
1479
1620
  const needs = deletion === "soft" && kind === "delete" ? ["findOne", "update"] : NEEDS[kind] ?? [];
1480
1621
  for (const need of needs) {
@@ -1766,7 +1907,7 @@ var ENSURE_KINDS = new Set([
1766
1907
  "true",
1767
1908
  "false"
1768
1909
  ]);
1769
- var READ_ACTION = /^(?:findBy.+|findManyBy.+|findMany|exists|findPage|count)$/;
1910
+ var READ_ACTION = /^(?:findBy.+|findManyBy.+|findMany|exists|findPage|findCursor|count)$/;
1770
1911
  var WRITE_ACTIONS = new Set(["create", "update", "delete"]);
1771
1912
  function validateSteps(declaration, steps) {
1772
1913
  const { name } = declaration;
@@ -2068,7 +2209,7 @@ function methodNamesOf(repository) {
2068
2209
  }
2069
2210
  function bindRepository2(repository, overrides, state, source) {
2070
2211
  const Entity = repository.entity;
2071
- const repositoryName = Entity.name;
2212
+ const repositoryName = recordNameOf2(Entity);
2072
2213
  const bound = Object.create(null);
2073
2214
  const view = new Proxy(Object.create(repository), {
2074
2215
  get: (_target, key, receiver) => {
@@ -3597,7 +3738,7 @@ function resolve(settings) {
3597
3738
  if (!isOfKind(collection, value)) {
3598
3739
  invalid7(source, `${collection}.${name} is not a ${KIND_OF[collection]} (${collection} takes ${KIND_OF[collection]} declarations).`);
3599
3740
  }
3600
- const declaredName = collection === "useCases" ? value.useCaseName : collection === "commands" ? value.commandName : collection === "outputs" ? value.outputName : collection === "exceptions" ? value.name : name;
3741
+ const declaredName = collection === "useCases" ? value.useCaseName : collection === "commands" ? value.commandName : collection === "outputs" ? value.outputName : collection === "exceptions" ? value.name : collection === "records" || collection === "entities" ? declaredRecordNameOf(value) ?? name : name;
3601
3742
  if (declaredName !== name) {
3602
3743
  invalid7(source, `${collection}.${name} must be keyed by its name, "${declaredName}".`);
3603
3744
  }
@@ -3652,7 +3793,7 @@ function validate(source, registry) {
3652
3793
  source,
3653
3794
  details: {
3654
3795
  holder: `${KIND_OF[collection]} "${entry.name}"`,
3655
- reference: `${isEntityClass2(record) ? "entity" : "record"} "${record.name}"`
3796
+ reference: `${isEntityClass2(record) ? "entity" : "record"} "${recordNameOf2(record)}"`
3656
3797
  }
3657
3798
  });
3658
3799
  }
@@ -3673,7 +3814,7 @@ function validate(source, registry) {
3673
3814
  }
3674
3815
  for (const relation of info.relations) {
3675
3816
  if (!repositories.has(relation)) {
3676
- unregistered(entry.name, `the repository of "${relation.entity.name}"`);
3817
+ unregistered(entry.name, `the repository of "${recordNameOf2(relation.entity)}"`);
3677
3818
  }
3678
3819
  }
3679
3820
  for (const environment of info.environments) {
@@ -3772,7 +3913,7 @@ function validateUseCases(source, registry) {
3772
3913
  source,
3773
3914
  details: {
3774
3915
  holder: `the ${part} of use case "${entry.name}"`,
3775
- reference: `${isEntityClass2(record) ? "entity" : "record"} "${record.name}"`
3916
+ reference: `${isEntityClass2(record) ? "entity" : "record"} "${recordNameOf2(record)}"`
3776
3917
  }
3777
3918
  });
3778
3919
  }
@@ -3795,7 +3936,7 @@ function validateUseCases(source, registry) {
3795
3936
  source,
3796
3937
  details: {
3797
3938
  holder,
3798
- reference: `${isEntityClass2(step.build) ? "entity" : "record"} "${step.build.name}"`
3939
+ reference: `${isEntityClass2(step.build) ? "entity" : "record"} "${recordNameOf2(step.build)}"`
3799
3940
  }
3800
3941
  });
3801
3942
  }
@@ -3881,7 +4022,7 @@ function fieldDescriptionOf(field, scope) {
3881
4022
  const ref = entity ?? scope.records.get(record.record);
3882
4023
  return {
3883
4024
  kind: entity === undefined ? "record" : "entity",
3884
- ref: ref ?? record.record.name,
4025
+ ref: ref ?? recordNameOf2(record.record),
3885
4026
  optional: record.optional
3886
4027
  };
3887
4028
  }
@@ -4353,6 +4494,14 @@ function applicationOf2(settings) {
4353
4494
  }
4354
4495
  return boundUseCaseOf.get(useCase);
4355
4496
  },
4497
+ async run(useCase, input = {}, options) {
4498
+ if (!boundUseCaseOf.has(useCase)) {
4499
+ invalid7(name, "Expected a use case registered in the application.");
4500
+ }
4501
+ const Bound = boundUseCaseOf.get(useCase);
4502
+ const instance = options?.context === undefined ? new Bound(input) : new Bound(input, { context: options.context });
4503
+ return instance.execute(options?.dependencies);
4504
+ },
4356
4505
  command(command) {
4357
4506
  if (!boundCommandOf.has(command)) {
4358
4507
  invalid7(name, "Expected a command registered in the application.");
@@ -4763,7 +4912,7 @@ var openapi2 = sinkOf2({
4763
4912
  const models = {};
4764
4913
  const classes = new Map;
4765
4914
  for (const record of records) {
4766
- const name = record.name;
4915
+ const name = recordNameOf2(record);
4767
4916
  if (!/^[A-Za-z0-9._-]+$/.test(name) || name === "Problem") {
4768
4917
  invalid8(`The record class "${name}" cannot be a component name; give the class a name that is not "Problem".`);
4769
4918
  }
@@ -5539,4 +5688,4 @@ var entityOf2 = entityBuilderOf2({
5539
5688
  var recordOf2 = recordBuilderOf2(StdRecordPlugins2);
5540
5689
  // src/std/stages.ts
5541
5690
  var StdStages2 = stageCatalogOf2(select2, openapi2);
5542
- export { InvalidEnvironment2, environmentOf2, isEnvironment2, guard2, InvalidApplicationDeclaration2, DuplicateApplicationDeclaration2, ApplicationConflict2, UnregisteredApplicationReference2, UnregisteredRepositoryDependency2, UnregisteredUseCaseDependency2, ApplicationNotStarted2, ProviderNotBound2, ApplicationAlreadyStarted2, InvalidApplicationEnvironment2, useApplication2, resetApplication2, InvalidLogDeclaration2, LogLevels2, logProviderOf2, consoleLogProvider2, jsonLogProvider2, memoryLogProvider2, Logger2, ReservedEntityKey2, ImmutableEntityKey2, DeletedEntity2, entityBuilderOf2, isEntityClass2, isEntity2, eventOf2, ENTITY_IDENTITY_KEYS2, RESERVED_ENTITY_KEYS2, EntityUniqueKeys2, AbstractEntity2, InvalidRepositoryQuery2, InvalidRepositoryDeclaration2, InvalidRepositoryEntity2, InvalidRepositoryData2, RepositoryUniqueViolation2, RepositoryEntityNotFound2, providerOf2, providerDescriptionOf2, inMemoryProvider2, AbstractRepository2, repositoryOf2, RepositoryOf2, isRepository2, InvalidUseCaseStep2, InvalidUseCaseDeclaration2, UseCaseAlreadyExecuted2, InvalidUseCaseDependencies2, AbstractUseCase2, useCaseOf2, isUseCaseClass2, isUseCase2, InvalidCommandDeclaration2, UnknownCommandOperation2, InvalidCommandContext2, InvalidCommandEnvironment2, CommandEventFailed2, commandOf2, isCommand2, InvalidOpenAPIModel2, InvalidOutputStage2, DuplicateOperation2, toOpenAPI2, transformOf2, sinkOf2, stageDescriptionOf2, stageKindOf2, stageCatalogOf2, operationOf2, outputOf2, isOutput2, providerFrom2, logFrom2, isLogFactory2, isProviderFactory2, providersOf2, isProviderSlot2, isProviderStorage2, isApplication2, applicationOf2, blueprintPluginOf2, statusOf2, PROBLEM_MEDIA_TYPE2, problemOf2, outputValueOf2, routeOptionsIssue2, operationRoutes2, openapi2, select2, recordPluginCatalogOf2, Email2, Phone2, Url2, Ip2, enumOf2, SchemaProperty2, PasswordHasherRequired2, SyncVerifyUnsupported2, configure2, resetRuntime2, Id2, Slug2, PASSWORD_MIN_LENGTH2, PASSWORD_MAX_LENGTH2, PASSWORD_SPECIAL_CHARACTERS2, isPasswordHash2, passwordIssues2, Password2, StringProperty2, Text2, NumberProperty2, Integer2, BooleanProperty2, DateTime2, DateProperty2, CreatedAt2, UpdatedAt2, DeletedAt2, Std2, blueprintOf2, Publishable2, Archivable2, Taggable2, Ownable2, Authenticatable2, StdRecordPlugins2, entityOf2, recordOf2, StdStages2 };
5691
+ export { InvalidEnvironment2, environmentOf2, isEnvironment2, guard2, InvalidApplicationDeclaration2, DuplicateApplicationDeclaration2, ApplicationConflict2, UnregisteredApplicationReference2, UnregisteredRepositoryDependency2, UnregisteredUseCaseDependency2, ApplicationNotStarted2, ProviderNotBound2, ApplicationAlreadyStarted2, InvalidApplicationEnvironment2, useApplication2, resetApplication2, InvalidLogDeclaration2, LogLevels2, logProviderOf2, consoleLogProvider2, jsonLogProvider2, memoryLogProvider2, Logger2, ReservedEntityKey2, ImmutableEntityKey2, DeletedEntity2, entityBuilderOf2, isEntityClass2, isEntity2, eventOf2, ENTITY_IDENTITY_KEYS2, RESERVED_ENTITY_KEYS2, EntityUniqueKeys2, AbstractEntity2, InvalidRepositoryQuery2, InvalidRepositoryCursor2, InvalidRepositoryDeclaration2, InvalidRepositoryEntity2, InvalidRepositoryData2, RepositoryUniqueViolation2, RepositoryEntityNotFound2, providerOf2, providerDescriptionOf2, inMemoryProvider2, AbstractRepository2, repositoryOf2, RepositoryOf2, isRepository2, InvalidUseCaseStep2, InvalidUseCaseDeclaration2, UseCaseAlreadyExecuted2, InvalidUseCaseDependencies2, AbstractUseCase2, useCaseOf2, isUseCaseClass2, isUseCase2, InvalidCommandDeclaration2, UnknownCommandOperation2, InvalidCommandContext2, InvalidCommandEnvironment2, CommandEventFailed2, commandOf2, isCommand2, InvalidOpenAPIModel2, InvalidOutputStage2, DuplicateOperation2, toOpenAPI2, transformOf2, sinkOf2, stageDescriptionOf2, stageKindOf2, stageCatalogOf2, operationOf2, outputOf2, isOutput2, providerFrom2, logFrom2, isLogFactory2, isProviderFactory2, providersOf2, isProviderSlot2, isProviderStorage2, isApplication2, applicationOf2, blueprintPluginOf2, statusOf2, PROBLEM_MEDIA_TYPE2, problemOf2, outputValueOf2, routeOptionsIssue2, operationRoutes2, openapi2, select2, recordPluginCatalogOf2, Email2, Phone2, Url2, Ip2, enumOf2, SchemaProperty2, PasswordHasherRequired2, SyncVerifyUnsupported2, configure2, resetRuntime2, Id2, Slug2, PASSWORD_MIN_LENGTH2, PASSWORD_MAX_LENGTH2, PASSWORD_SPECIAL_CHARACTERS2, isPasswordHash2, passwordIssues2, Password2, StringProperty2, Text2, NumberProperty2, Integer2, BooleanProperty2, DateTime2, DateProperty2, CreatedAt2, UpdatedAt2, DeletedAt2, Std2, blueprintOf2, Publishable2, Archivable2, Taggable2, Ownable2, Authenticatable2, StdRecordPlugins2, entityOf2, recordOf2, StdStages2 };
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ export { ApplicationAlreadyStarted, ApplicationConflict, ApplicationNotStarted,
3
3
  export { isProviderSlot, isProviderStorage, type ProviderSlot, type ProviderStorage, providersOf, } from "./core/application/providers.js";
4
4
  export { type Register, type RegisteredApplication, resetApplication, useApplication, } from "./core/application/registry.js";
5
5
  export { isLogFactory, isProviderFactory, type LogFactory, logFrom, type ProviderFactory, providerFrom, } from "./core/application/start.js";
6
- export type { AnyApplication, ApplicationCollections, ApplicationContext, ApplicationDescription, ApplicationSettings, ApplicationStartOptions, CommandDescription, ExceptionDescription, FieldDescription, FieldsDescription, IApplication, LogDescription, OutputDescription, PropertyDescription, PropertyLineageDescription, PropertyReference, ProviderReference, RecordDescription, UseCaseDependencyDescription, UseCaseDescription, } from "./core/application/types/application.interface.js";
6
+ export type { AnyApplication, ApplicationCollections, ApplicationContext, ApplicationDescription, ApplicationRunArgs, ApplicationRunOptions, ApplicationSettings, ApplicationStartOptions, CommandDescription, ExceptionDescription, FieldDescription, FieldsDescription, IApplication, LogDescription, OutputDescription, PropertyDescription, PropertyLineageDescription, PropertyReference, ProviderReference, RecordDescription, UseCaseDependencyDescription, UseCaseDescription, } from "./core/application/types/application.interface.js";
7
7
  export { blueprintBuilderOf } from "./core/blueprint/blueprint.js";
8
8
  export { blueprintPluginOf } from "./core/blueprint/blueprint-plugin.js";
9
9
  export { ReservedBlueprintKey, UndeclaredBlueprintProperty, } from "./core/blueprint/exceptions.js";
@@ -62,22 +62,23 @@ export type { IProperty } from "./core/property/types/property.interface.js";
62
62
  export type { AnyPropertyConstructor, IPropertyCollection, } from "./core/property/types/property-collection.type.js";
63
63
  export type { PropertyValue } from "./core/property/types/property-constructor.type.js";
64
64
  export type { CallableProperty, NumberConstraints, PropertyMetadata, PropertyOptions, StringConstraints, } from "./core/property/types/property-options.interface.js";
65
- export type { IPropertyType, UniqueMark, } from "./core/property/types/property-type.interface.js";
65
+ export type { IPropertyType, SensitiveMark, UniqueMark, } from "./core/property/types/property-type.interface.js";
66
66
  export { AbstractRecord, RESERVED_RECORD_KEYS, } from "./core/record/abstract-record.js";
67
- export { IncompatibleRecordPlugin, InvalidRecordPlugin, InvalidRecordValue, RecordPluginConflict, ReservedRecordKey, UndeclaredRecordProperty, UnknownRecordPlugin, } from "./core/record/exceptions.js";
67
+ export { IncompatibleRecordPlugin, InvalidRecordDeclaration, InvalidRecordPlugin, InvalidRecordValue, RecordPluginConflict, ReservedRecordKey, UndeclaredRecordProperty, UnknownRecordPlugin, } from "./core/record/exceptions.js";
68
68
  export { MASK } from "./core/record/mask.js";
69
+ export { recordNameOf } from "./core/record/name.js";
69
70
  export { hasPlugin, isRecordPlugin, pluginsOf, recordPluginOf, } from "./core/record/plugin.js";
70
71
  export { recordPluginCatalogOf } from "./core/record/plugin-catalog.js";
71
72
  export type { RecordBuilder } from "./core/record/record.js";
72
73
  export { recordBuilderOf } from "./core/record/record.js";
73
74
  export type { AnyRecordPlugin, IRecordPlugin, IRecordPluginCatalog, PluginUniqueKey, RecordPluginDescriptor, RecordPluginOptions, RecordPluginReference, RecordPluginRequirement, RecordPluginsOption, } from "./core/record/types/plugin.interface.js";
74
- export type { DeclaredRecordInstance, IRecord, MarkedUniqueKey, RecordChange, RecordChanges, RecordConstructor, RecordEffect, RecordEffects, RecordKey, RecordOptions, RecordSettings, RecordValue, } from "./core/record/types/record.interface.js";
75
- export { InvalidRepositoryData, InvalidRepositoryDeclaration, InvalidRepositoryEntity, InvalidRepositoryQuery, RepositoryEntityNotFound, RepositoryUniqueViolation, } from "./core/repository/exceptions.js";
75
+ export type { DeclaredRecordInstance, IRecord, MarkedUniqueKey, Masked, RecordChange, RecordChanges, RecordConstructor, RecordEffect, RecordEffects, RecordJson, RecordKey, RecordOptions, RecordSettings, RecordValue, } from "./core/record/types/record.interface.js";
76
+ export { InvalidRepositoryCursor, InvalidRepositoryData, InvalidRepositoryDeclaration, InvalidRepositoryEntity, InvalidRepositoryQuery, RepositoryEntityNotFound, RepositoryUniqueViolation, } from "./core/repository/exceptions.js";
76
77
  export { inMemoryProvider } from "./core/repository/in-memory.js";
77
78
  export { providerDescriptionOf, providerOf } from "./core/repository/provider.js";
78
79
  export type { RepositorySettings } from "./core/repository/repository.js";
79
80
  export { AbstractRepository, isRepository, RepositoryOf, repositoryOf, } from "./core/repository/repository.js";
80
- export type { ProviderCapabilities, ProviderDescription, ProviderOption, ProviderOptions, ProviderSettings, RepositoryExists, RepositoryFindMany, RepositoryFindPage, RepositoryOrder, RepositoryPage, RepositoryQuery, RepositoryWhere, } from "./core/repository/types/query.interface.js";
81
+ export type { ProviderCapabilities, ProviderDescription, ProviderOption, ProviderOptions, ProviderQuery, ProviderSettings, RepositoryCursorPage, RepositoryCursorQuery, RepositoryExists, RepositoryFindCursor, RepositoryFindMany, RepositoryFindPage, RepositoryOrder, RepositoryPage, RepositoryQuery, RepositoryWhere, } from "./core/repository/types/query.interface.js";
81
82
  export type { AnyRepository, AnyRepositoryEntity, EntityInstanceOf, EntityKeyOf, EntityNonUniqueKeyOf, EntityUniqueKeyOf, EntityValueOf, IRepositoryProvider, QueryValueOf, RepositoryAction, RepositoryContext, RepositoryCount, RepositoryCreate, RepositoryCreateInput, RepositoryData, RepositoryDelete, RepositoryFindBy, RepositoryFindManyBy, RepositoryUpdate, } from "./core/repository/types/repository.interface.js";
82
83
  export type { SchemaClass } from "./core/schema/schema.js";
83
84
  export { schemaOf } from "./core/schema/schema.js";
package/dist/index.js CHANGED
@@ -34,6 +34,7 @@ import {
34
34
  EntityUniqueKeys2,
35
35
  AbstractEntity2,
36
36
  InvalidRepositoryQuery2,
37
+ InvalidRepositoryCursor2,
37
38
  InvalidRepositoryDeclaration2,
38
39
  InvalidRepositoryEntity2,
39
40
  InvalidRepositoryData2,
@@ -131,7 +132,7 @@ import {
131
132
  entityOf2,
132
133
  recordOf2,
133
134
  StdStages2
134
- } from "./index-8m80wjzf.js";
135
+ } from "./index-gbgc40xe.js";
135
136
  import {
136
137
  isProperty2,
137
138
  schemaOf2,
@@ -142,6 +143,7 @@ import {
142
143
  isRecordClass2,
143
144
  isOptionalRecord2,
144
145
  recordFieldOf2,
146
+ recordNameOf2,
145
147
  listOf2,
146
148
  isBlueprintList2,
147
149
  ExceptionLayers2,
@@ -150,6 +152,7 @@ import {
150
152
  exceptionOf2,
151
153
  Meta2,
152
154
  InvalidRecordValue2,
155
+ InvalidRecordDeclaration2,
153
156
  UndeclaredRecordProperty2,
154
157
  ReservedRecordKey2,
155
158
  InvalidRecordPlugin2,
@@ -175,7 +178,7 @@ import {
175
178
  propertyOf2,
176
179
  optionalOf2,
177
180
  blueprintBuilderOf2
178
- } from "./index-hn82hm31.js";
181
+ } from "./index-3nd9bjnc.js";
179
182
  export {
180
183
  AbstractDefineProperty2 as AbstractDefineProperty,
181
184
  AbstractEntity2 as AbstractEntity,
@@ -217,8 +220,10 @@ export {
217
220
  InvalidOpenAPIModel2 as InvalidOpenAPIModel,
218
221
  InvalidOutputStage2 as InvalidOutputStage,
219
222
  InvalidPropertyValue2 as InvalidPropertyValue,
223
+ InvalidRecordDeclaration2 as InvalidRecordDeclaration,
220
224
  InvalidRecordPlugin2 as InvalidRecordPlugin,
221
225
  InvalidRecordValue2 as InvalidRecordValue,
226
+ InvalidRepositoryCursor2 as InvalidRepositoryCursor,
222
227
  InvalidRepositoryData2 as InvalidRepositoryData,
223
228
  InvalidRepositoryDeclaration2 as InvalidRepositoryDeclaration,
224
229
  InvalidRepositoryEntity2 as InvalidRepositoryEntity,
@@ -333,6 +338,7 @@ export {
333
338
  providersOf2 as providersOf,
334
339
  recordBuilderOf2 as recordBuilderOf,
335
340
  recordFieldOf2 as recordFieldOf,
341
+ recordNameOf2 as recordNameOf,
336
342
  recordOf2 as recordOf,
337
343
  recordPluginCatalogOf2 as recordPluginCatalogOf,
338
344
  recordPluginOf2 as recordPluginOf,
@@ -5,7 +5,11 @@ export declare const PASSWORD_SPECIAL_CHARACTERS = "!@#$%^&*()-_=+[]{}|\\;:'\",.
5
5
  export declare function isPasswordHash(value: string): boolean;
6
6
  /** The rules a plain password breaks; empty when it is strong enough. */
7
7
  export declare function passwordIssues(value: string): string[];
8
- declare const Password_base: import("../../index.js").PropertyClass<Type.TString, string>;
8
+ declare const Password_base: import("../../index.js").PropertyClass<Type.TString, string> & {
9
+ readonly type: {
10
+ readonly sensitive: true;
11
+ };
12
+ };
9
13
  /**
10
14
  * A password stored as an Argon2 hash. The constructor only accepts a hash,
11
15
  * e.g. one read from the database; `Password.hash` turns a plain password
@@ -6,7 +6,7 @@ declare const PublishableRecord_base: import("../index.js").RecordConstructor<im
6
6
  safeParse(value: unknown): import("../index.js").ParseResult<string | undefined>;
7
7
  readonly "~standard": import("../index.js").StandardSchemaV1.Props<string | undefined, string | undefined>;
8
8
  }>;
9
- }>, [], never, unknown>;
9
+ }>, [], never, unknown, never, never>;
10
10
  /**
11
11
  * A `publishedAt` absent while the record is a draft; `publish(at?)` sets it
12
12
  * (to now by default), `unpublish()` clears it, `isPublished` tells.
@@ -30,7 +30,7 @@ declare const ArchivableRecord_base: import("../index.js").RecordConstructor<imp
30
30
  safeParse(value: unknown): import("../index.js").ParseResult<string | undefined>;
31
31
  readonly "~standard": import("../index.js").StandardSchemaV1.Props<string | undefined, string | undefined>;
32
32
  }>;
33
- }>, [], never, unknown>;
33
+ }>, [], never, unknown, never, never>;
34
34
  /**
35
35
  * An `archivedAt` absent while the record is active; `archive(at?)` sets it,
36
36
  * `restore()` clears it, `isArchived` tells.
@@ -49,7 +49,7 @@ export declare class ArchivableRecord extends ArchivableRecord_base {
49
49
  export declare const Archivable: import("../index.js").IRecordPlugin<typeof ArchivableRecord, "archivable">;
50
50
  declare const TaggableRecord_base: import("../index.js").RecordConstructor<import("../core/property/types/property-options.interface.js").StoredFields<{
51
51
  tags: import("../index.js").IBlueprintList<import("../index.js").PropertyClass<import("typebox").TString, string>, true>;
52
- }>, [], never, unknown>;
52
+ }>, [], never, unknown, never, never>;
53
53
  /**
54
54
  * `tags`, a list of strings, each once; `tag`, `untag` and `hasTag` change and read it.
55
55
  *
@@ -67,7 +67,7 @@ export declare class TaggableRecord extends TaggableRecord_base {
67
67
  export declare const Taggable: import("../index.js").IRecordPlugin<typeof TaggableRecord, "taggable">;
68
68
  declare const OwnableRecord_base: import("../index.js").RecordConstructor<import("../core/property/types/property-options.interface.js").StoredFields<{
69
69
  ownerId: import("../index.js").CallableProperty<typeof import("../index.js").Id>;
70
- }>, [], never, unknown>;
70
+ }>, [], never, unknown, never, never>;
71
71
  /**
72
72
  * An `ownerId`, the id of who owns the record, with `isOwnedBy` and `transferTo`.
73
73
  *
@@ -84,7 +84,7 @@ export declare const Ownable: import("../index.js").IRecordPlugin<typeof Ownable
84
84
  declare const AuthenticatableRecord_base: import("../index.js").RecordConstructor<import("../core/property/types/property-options.interface.js").StoredFields<{
85
85
  email: import("../index.js").CallableProperty<import("../index.js").PropertyClass<import("typebox").TString, string>>;
86
86
  password: import("../index.js").CallableProperty<typeof Password>;
87
- }>, readonly ["password"], "email", unknown>;
87
+ }>, readonly ["password"], "email", unknown, never, never>;
88
88
  /**
89
89
  * An `email`, unique, and a `password` hash, sensitive, changed by
90
90
  * `change.password` and checked by `verifyPassword`.