joist-codegen 2.4.0-next.5 → 2.4.0-next.50
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/build/EntityDbMetadata.cjs +21 -3
- package/build/EntityDbMetadata.cjs.map +1 -1
- package/build/EntityDbMetadata.d.cts +28 -25
- package/build/EntityDbMetadata.d.cts.map +1 -1
- package/build/EntityDbMetadata.d.mts +28 -25
- package/build/EntityDbMetadata.d.mts.map +1 -1
- package/build/EntityDbMetadata.js +21 -3
- package/build/EntityDbMetadata.js.map +1 -1
- package/build/assignTags.d.cts +1 -2
- package/build/assignTags.d.cts.map +1 -1
- package/build/assignTags.d.mts +1 -2
- package/build/assignTags.d.mts.map +1 -1
- package/build/codemods/Codemod.d.cts +1 -2
- package/build/codemods/Codemod.d.cts.map +1 -1
- package/build/codemods/Codemod.d.mts +1 -2
- package/build/codemods/Codemod.d.mts.map +1 -1
- package/build/codemods/JscodeshiftMod.d.cts +1 -2
- package/build/codemods/JscodeshiftMod.d.cts.map +1 -1
- package/build/codemods/JscodeshiftMod.d.mts +1 -2
- package/build/codemods/JscodeshiftMod.d.mts.map +1 -1
- package/build/codemods/codemod_0001-rename_has_async_property.d.cts +2 -2
- package/build/codemods/codemod_0001-rename_has_async_property.d.cts.map +1 -1
- package/build/codemods/codemod_0001-rename_has_async_property.d.mts +2 -2
- package/build/codemods/codemod_0001-rename_has_async_property.d.mts.map +1 -1
- package/build/codemods/codemod_0002-rename_async_query_fields.d.cts +2 -2
- package/build/codemods/codemod_0002-rename_async_query_fields.d.cts.map +1 -1
- package/build/codemods/codemod_0002-rename_async_query_fields.d.mts +2 -2
- package/build/codemods/codemod_0002-rename_async_query_fields.d.mts.map +1 -1
- package/build/codemods/codemod_0003-rename_find_paginated.d.cts +2 -2
- package/build/codemods/codemod_0003-rename_find_paginated.d.cts.map +1 -1
- package/build/codemods/codemod_0003-rename_find_paginated.d.mts +2 -2
- package/build/codemods/codemod_0003-rename_find_paginated.d.mts.map +1 -1
- package/build/codemods/index.d.cts +3 -4
- package/build/codemods/index.d.cts.map +1 -1
- package/build/codemods/index.d.mts +3 -4
- package/build/codemods/index.d.mts.map +1 -1
- package/build/config.cjs +8 -3
- package/build/config.cjs.map +1 -1
- package/build/config.d.cts +30 -27
- package/build/config.d.cts.map +1 -1
- package/build/config.d.mts +30 -27
- package/build/config.d.mts.map +1 -1
- package/build/config.js +8 -3
- package/build/config.js.map +1 -1
- package/build/docs/cache.cjs.map +1 -1
- package/build/docs/cache.d.cts +2 -3
- package/build/docs/cache.d.cts.map +1 -1
- package/build/docs/cache.d.mts +2 -3
- package/build/docs/cache.d.mts.map +1 -1
- package/build/docs/cache.js.map +1 -1
- package/build/docs/generate-metadata-docs.d.cts +1 -2
- package/build/docs/generate-metadata-docs.d.cts.map +1 -1
- package/build/docs/generate-metadata-docs.d.mts +1 -2
- package/build/docs/generate-metadata-docs.d.mts.map +1 -1
- package/build/docs/index.d.cts +3 -3
- package/build/docs/index.d.cts.map +1 -1
- package/build/docs/index.d.mts +3 -3
- package/build/docs/index.d.mts.map +1 -1
- package/build/docs/markdown.d.cts +8 -8
- package/build/docs/markdown.d.cts.map +1 -1
- package/build/docs/markdown.d.mts +8 -8
- package/build/docs/markdown.d.mts.map +1 -1
- package/build/docs/parsing.d.cts +9 -9
- package/build/docs/parsing.d.cts.map +1 -1
- package/build/docs/parsing.d.mts +9 -9
- package/build/docs/parsing.d.mts.map +1 -1
- package/build/findEntityScopes.d.cts +3 -4
- package/build/findEntityScopes.d.cts.map +1 -1
- package/build/findEntityScopes.d.mts +3 -4
- package/build/findEntityScopes.d.mts.map +1 -1
- package/build/foreignKeyOrdering.d.cts +1 -2
- package/build/foreignKeyOrdering.d.cts.map +1 -1
- package/build/foreignKeyOrdering.d.mts +1 -2
- package/build/foreignKeyOrdering.d.mts.map +1 -1
- package/build/generate.d.cts +3 -4
- package/build/generate.d.cts.map +1 -1
- package/build/generate.d.mts +3 -4
- package/build/generate.d.mts.map +1 -1
- package/build/generateEntitiesFile.d.cts +1 -2
- package/build/generateEntitiesFile.d.cts.map +1 -1
- package/build/generateEntitiesFile.d.mts +1 -2
- package/build/generateEntitiesFile.d.mts.map +1 -1
- package/build/generateEntityCodegenFile.cjs +5 -3
- package/build/generateEntityCodegenFile.cjs.map +1 -1
- package/build/generateEntityCodegenFile.d.cts +3 -4
- package/build/generateEntityCodegenFile.d.cts.map +1 -1
- package/build/generateEntityCodegenFile.d.mts +3 -4
- package/build/generateEntityCodegenFile.d.mts.map +1 -1
- package/build/generateEntityCodegenFile.js +5 -3
- package/build/generateEntityCodegenFile.js.map +1 -1
- package/build/generateEntityFile.d.cts +1 -2
- package/build/generateEntityFile.d.cts.map +1 -1
- package/build/generateEntityFile.d.mts +1 -2
- package/build/generateEntityFile.d.mts.map +1 -1
- package/build/generateEntityTestFile.d.cts +1 -2
- package/build/generateEntityTestFile.d.cts.map +1 -1
- package/build/generateEntityTestFile.d.mts +1 -2
- package/build/generateEntityTestFile.d.mts.map +1 -1
- package/build/generateEnumFile.d.cts +1 -2
- package/build/generateEnumFile.d.cts.map +1 -1
- package/build/generateEnumFile.d.mts +1 -2
- package/build/generateEnumFile.d.mts.map +1 -1
- package/build/generateFactoriesFiles.d.cts +1 -2
- package/build/generateFactoriesFiles.d.cts.map +1 -1
- package/build/generateFactoriesFiles.d.mts +1 -2
- package/build/generateFactoriesFiles.d.mts.map +1 -1
- package/build/generateFlushFunction.d.cts +3 -4
- package/build/generateFlushFunction.d.cts.map +1 -1
- package/build/generateFlushFunction.d.mts +3 -4
- package/build/generateFlushFunction.d.mts.map +1 -1
- package/build/generateMetadataFile.cjs +30 -1
- package/build/generateMetadataFile.cjs.map +1 -1
- package/build/generateMetadataFile.d.cts +2 -3
- package/build/generateMetadataFile.d.cts.map +1 -1
- package/build/generateMetadataFile.d.mts +2 -3
- package/build/generateMetadataFile.d.mts.map +1 -1
- package/build/generateMetadataFile.js +31 -2
- package/build/generateMetadataFile.js.map +1 -1
- package/build/generatePgEnumFile.d.cts +1 -2
- package/build/generatePgEnumFile.d.cts.map +1 -1
- package/build/generatePgEnumFile.d.mts +1 -2
- package/build/generatePgEnumFile.d.mts.map +1 -1
- package/build/index.d.cts +4 -4
- package/build/index.d.cts.map +1 -1
- package/build/index.d.mts +4 -4
- package/build/index.d.mts.map +1 -1
- package/build/inheritance.d.cts +3 -3
- package/build/inheritance.d.cts.map +1 -1
- package/build/inheritance.d.mts +3 -3
- package/build/inheritance.d.mts.map +1 -1
- package/build/installSkills.d.cts +1 -2
- package/build/installSkills.d.cts.map +1 -1
- package/build/installSkills.d.mts +1 -2
- package/build/installSkills.d.mts.map +1 -1
- package/build/keywords.d.cts +1 -2
- package/build/keywords.d.cts.map +1 -1
- package/build/keywords.d.mts +1 -2
- package/build/keywords.d.mts.map +1 -1
- package/build/loadMetadata.d.cts +7 -8
- package/build/loadMetadata.d.cts.map +1 -1
- package/build/loadMetadata.d.mts +7 -8
- package/build/loadMetadata.d.mts.map +1 -1
- package/build/logger.d.cts +3 -4
- package/build/logger.d.cts.map +1 -1
- package/build/logger.d.mts +3 -4
- package/build/logger.d.mts.map +1 -1
- package/build/pgMetadata.d.cts +13 -14
- package/build/pgMetadata.d.cts.map +1 -1
- package/build/pgMetadata.d.mts +13 -14
- package/build/pgMetadata.d.mts.map +1 -1
- package/build/scanEntityFiles.cjs +6 -1
- package/build/scanEntityFiles.cjs.map +1 -1
- package/build/scanEntityFiles.d.cts +2 -3
- package/build/scanEntityFiles.d.cts.map +1 -1
- package/build/scanEntityFiles.d.mts +2 -3
- package/build/scanEntityFiles.d.mts.map +1 -1
- package/build/scanEntityFiles.js +6 -1
- package/build/scanEntityFiles.js.map +1 -1
- package/build/sortForeignKeys.d.cts +1 -2
- package/build/sortForeignKeys.d.cts.map +1 -1
- package/build/sortForeignKeys.d.mts +1 -2
- package/build/sortForeignKeys.d.mts.map +1 -1
- package/build/symbols.cjs +2 -0
- package/build/symbols.cjs.map +1 -1
- package/build/symbols.d.cts +117 -117
- package/build/symbols.d.cts.map +1 -1
- package/build/symbols.d.mts +117 -117
- package/build/symbols.d.mts.map +1 -1
- package/build/symbols.js +2 -1
- package/build/symbols.js.map +1 -1
- package/build/tsdoc.d.cts +1 -2
- package/build/tsdoc.d.cts.map +1 -1
- package/build/tsdoc.d.mts +1 -2
- package/build/tsdoc.d.mts.map +1 -1
- package/build/utils.cjs +1 -0
- package/build/utils.cjs.map +1 -1
- package/build/utils.d.cts +21 -22
- package/build/utils.d.cts.map +1 -1
- package/build/utils.d.mts +21 -22
- package/build/utils.d.mts.map +1 -1
- package/build/utils.js +1 -0
- package/build/utils.js.map +1 -1
- package/package.json +10 -10
- package/skills/joist-test-factories/SKILL.md +93 -6
package/build/symbols.js
CHANGED
|
@@ -42,6 +42,7 @@ const PlainTimeSerde = imp("PlainTimeSerde@joist-orm");
|
|
|
42
42
|
const PlainDateTimeSerde = imp("PlainDateTimeSerde@joist-orm");
|
|
43
43
|
const ZonedDateTimeSerde = imp("ZonedDateTimeSerde@joist-orm");
|
|
44
44
|
const JsonSerde = imp("JsonSerde@joist-orm");
|
|
45
|
+
const VectorSerde = imp("VectorSerde@joist-orm");
|
|
45
46
|
const SuperstructSerde = imp("SuperstructSerde@joist-orm");
|
|
46
47
|
const TaggedId = imp("t:TaggedId@joist-orm");
|
|
47
48
|
const ZodSerde = imp("ZodSerde@joist-orm");
|
|
@@ -117,6 +118,6 @@ const hasReactiveManyToManyOtherSide = imp("hasReactiveManyToManyOtherSide@joist
|
|
|
117
118
|
const updatePartial = imp("updatePartial@joist-orm");
|
|
118
119
|
const setRuntimeConfig = imp("setRuntimeConfig@joist-orm");
|
|
119
120
|
//#endregion
|
|
120
|
-
export { BaseEntity, BigIntSerde, BooleanFilter, BooleanGraphQLFilter, Changes, Collection, Column, ColumnDescriptors, ConfigApi, CustomSerdeAdapter, DateSerde, DecimalToNumberSerde, DeepNew, DeepPartialOrNull, Entity, EntityConstructor, EntityFilter, EntityGraphQLFilter, EntityManager, EntityMetadata, EnumArrayFieldSerde, EnumCollection, EnumFieldSerde, EnumGraphQLFilter, EnumMetadata, FactoryOpts, FieldStatus, FieldsOf, FilterOf, Flavor, GraphQLFilterOf, IdOf, JoistEntityManager, JsonHint, JsonPayload, JsonSerde, KeySerde, LargeCollection, LazyField, Lens, LoadHint, Loaded, ManyToManyCollection, ManyToOneReference, MaybeAbstractEntityConstructor, New, OneToManyCollection, OneToOneReference, OptsOf, OrderBy, PartialOrNull, PlainDateSerde, PlainDateTimeSerde, PlainTimeSerde, PolyComponent, PolymorphicKeySerde, PolymorphicReference, PrimitiveSerde, ProjectEntity, ReactiveField, ReactiveManyToMany, ReactiveManyToManyOtherSide, ReactiveReference, ReadOnlyCollection, Reference, RelationsOf, SSAssert, Scope, SimpleFieldSerde, SuperstructSerde, TaggedId, ToJsonHint, ValueFilter, ValueGraphQLFilter, Zod, ZodSerde, ZonedDateTimeSerde, cannotBeUpdated, cleanStringValue, configureMetadata, deTagId, fail, failNoIdYet, getField, getInstanceData, hasEnumCollection, hasLargeMany, hasLargeManyToMany, hasLazyField, hasMany, hasManyToMany, hasOne, hasOnePolymorphic, hasOneThrough, hasOneToOne, hasReactiveManyToManyOtherSide, hasRecursiveChildren, hasRecursiveM2m, hasRecursiveParents, isEntity, isLoaded, loadLens, mustBeSubType, newChangesProxy, newRequiredLazyFieldRule, newRequiredRule, newScopeFn, newTestInstance, nowUTC, polymorphicField, setField, setOpts, setRuntimeConfig, toIdOf, toJSON, updatePartial };
|
|
121
|
+
export { BaseEntity, BigIntSerde, BooleanFilter, BooleanGraphQLFilter, Changes, Collection, Column, ColumnDescriptors, ConfigApi, CustomSerdeAdapter, DateSerde, DecimalToNumberSerde, DeepNew, DeepPartialOrNull, Entity, EntityConstructor, EntityFilter, EntityGraphQLFilter, EntityManager, EntityMetadata, EnumArrayFieldSerde, EnumCollection, EnumFieldSerde, EnumGraphQLFilter, EnumMetadata, FactoryOpts, FieldStatus, FieldsOf, FilterOf, Flavor, GraphQLFilterOf, IdOf, JoistEntityManager, JsonHint, JsonPayload, JsonSerde, KeySerde, LargeCollection, LazyField, Lens, LoadHint, Loaded, ManyToManyCollection, ManyToOneReference, MaybeAbstractEntityConstructor, New, OneToManyCollection, OneToOneReference, OptsOf, OrderBy, PartialOrNull, PlainDateSerde, PlainDateTimeSerde, PlainTimeSerde, PolyComponent, PolymorphicKeySerde, PolymorphicReference, PrimitiveSerde, ProjectEntity, ReactiveField, ReactiveManyToMany, ReactiveManyToManyOtherSide, ReactiveReference, ReadOnlyCollection, Reference, RelationsOf, SSAssert, Scope, SimpleFieldSerde, SuperstructSerde, TaggedId, ToJsonHint, ValueFilter, ValueGraphQLFilter, VectorSerde, Zod, ZodSerde, ZonedDateTimeSerde, cannotBeUpdated, cleanStringValue, configureMetadata, deTagId, fail, failNoIdYet, getField, getInstanceData, hasEnumCollection, hasLargeMany, hasLargeManyToMany, hasLazyField, hasMany, hasManyToMany, hasOne, hasOnePolymorphic, hasOneThrough, hasOneToOne, hasReactiveManyToManyOtherSide, hasRecursiveChildren, hasRecursiveM2m, hasRecursiveParents, isEntity, isLoaded, loadLens, mustBeSubType, newChangesProxy, newRequiredLazyFieldRule, newRequiredRule, newScopeFn, newTestInstance, nowUTC, polymorphicField, setField, setOpts, setRuntimeConfig, toIdOf, toJSON, updatePartial };
|
|
121
122
|
|
|
122
123
|
//# sourceMappingURL=symbols.js.map
|
package/build/symbols.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"symbols.js","names":[],"sources":["../src/symbols.ts"],"sourcesContent":["import { imp } from \"ts-poet\";\n\nexport const ProjectEntity = imp(`t:Entity@./entities.ts`);\nexport const EntityManager = imp(\"EntityManager@./entities.ts\");\n\nexport const ConfigApi = imp(\"ConfigApi@joist-orm\");\nexport const newScopeFn = imp(\"newScopeFn@joist-orm\");\nexport const Scope = imp(\"t:Scope@joist-orm\");\nexport const FieldStatus = imp(\"t:FieldStatus@joist-orm\");\nexport const Entity = imp(\"t:Entity@joist-orm\");\nexport const BaseEntity = imp(\"BaseEntity@joist-orm\");\nexport const Flavor = imp(\"t:Flavor@joist-orm\");\nexport const Reference = imp(\"t:Reference@joist-orm\");\nexport const Collection = imp(\"t:Collection@joist-orm\");\nexport const EnumCollection = imp(\"t:EnumCollection@joist-orm\");\nexport const LargeCollection = imp(\"t:LargeCollection@joist-orm\");\nexport const OneToManyCollection = imp(\"OneToManyCollection@joist-orm\");\nexport const JoistEntityManager = imp(\"EntityManager@joist-orm\");\nexport const EntityMetadata = imp(\"t:EntityMetadata@joist-orm\");\nexport const EnumMetadata = imp(\"t:EnumMetadata@joist-orm\");\nexport const Lens = imp(\"t:Lens@joist-orm\");\nexport const KeySerde = imp(\"KeySerde@joist-orm\");\nexport const Column = imp(\"Column@joist-orm\");\nexport const ColumnDescriptors = imp(\"t:ColumnDescriptors@joist-orm\");\nexport const SimpleFieldSerde = imp(\"SimpleFieldSerde@joist-orm\");\nexport const PolyComponent = imp(\"PolyComponent@joist-orm\");\nexport const polymorphicField = imp(\"polymorphicField@joist-orm\");\nexport const ManyToOneReference = imp(\"t:ManyToOneReference@joist-orm\");\nexport const LazyField = imp(\"t:LazyField@joist-orm\");\nexport const hasLazyField = imp(\"hasLazyField@joist-orm\");\nexport const ReadOnlyCollection = imp(\"t:ReadOnlyCollection@joist-orm\");\nexport const PolymorphicReference = imp(\"t:PolymorphicReference@joist-orm\");\nexport const OneToOneReference = imp(\"t:OneToOneReference@joist-orm\");\nexport const ManyToManyCollection = imp(\"ManyToManyCollection@joist-orm\");\nexport const EnumFieldSerde = imp(\"EnumFieldSerde@joist-orm\");\nexport const EnumArrayFieldSerde = imp(\"EnumArrayFieldSerde@joist-orm\");\nexport const PolymorphicKeySerde = imp(\"PolymorphicKeySerde@joist-orm\");\nexport const PrimitiveSerde = imp(\"PrimitiveSerde@joist-orm\");\nexport const BigIntSerde = imp(\"BigIntSerde@joist-orm\");\nexport const DateSerde = imp(\"DateSerde@joist-orm\");\nexport const PlainDateSerde = imp(\"PlainDateSerde@joist-orm\");\nexport const PlainTimeSerde = imp(\"PlainTimeSerde@joist-orm\");\nexport const PlainDateTimeSerde = imp(\"PlainDateTimeSerde@joist-orm\");\nexport const ZonedDateTimeSerde = imp(\"ZonedDateTimeSerde@joist-orm\");\nexport const JsonSerde = imp(\"JsonSerde@joist-orm\");\nexport const SuperstructSerde = imp(\"SuperstructSerde@joist-orm\");\nexport const TaggedId = imp(\"t:TaggedId@joist-orm\");\nexport const ZodSerde = imp(\"ZodSerde@joist-orm\");\nexport const CustomSerdeAdapter = imp(\"CustomSerdeAdapter@joist-orm\");\nexport const DecimalToNumberSerde = imp(\"DecimalToNumberSerde@joist-orm\");\nexport const fail = imp(\"fail@joist-orm\");\nexport const failNoIdYet = imp(\"failNoIdYet@joist-orm\");\nexport const setOpts = imp(\"setOpts@joist-orm\");\nexport const getField = imp(\"getField@joist-orm\");\nexport const setField = imp(\"setField@joist-orm\");\nexport const OrderBy = imp(\"t:OrderBy@joist-orm\");\nexport const OptsOf = imp(\"t:OptsOf@joist-orm\");\nexport const FieldsOf = imp(\"t:FieldsOf@joist-orm\");\nexport const RelationsOf = imp(\"t:RelationsOf@joist-orm\");\nexport const IdOf = imp(\"t:IdOf@joist-orm\");\nexport const PartialOrNull = imp(\"t:PartialOrNull@joist-orm\");\nexport const DeepPartialOrNull = imp(\"t:DeepPartialOrNull@joist-orm\");\nexport const BooleanFilter = imp(\"t:BooleanFilter@joist-orm\");\nexport const ValueFilter = imp(\"t:ValueFilter@joist-orm\");\nexport const EntityFilter = imp(\"t:EntityFilter@joist-orm\");\nexport const BooleanGraphQLFilter = imp(\"t:BooleanGraphQLFilter@joist-orm\");\nexport const EntityGraphQLFilter = imp(\"t:EntityGraphQLFilter@joist-orm\");\nexport const EnumGraphQLFilter = imp(\"t:EnumGraphQLFilter@joist-orm\");\nexport const ValueGraphQLFilter = imp(\"t:ValueGraphQLFilter@joist-orm\");\nexport const FilterOf = imp(\"t:FilterOf@joist-orm\");\nexport const GraphQLFilterOf = imp(\"t:GraphQLFilterOf@joist-orm\");\nexport const JsonHint = imp(\"t:JsonHint@joist-orm\");\nexport const ToJsonHint = imp(\"t:ToJsonHint@joist-orm\");\nexport const JsonPayload = imp(\"t:JsonPayload@joist-orm\");\nexport const configureMetadata = imp(\"configureMetadata@joist-orm\");\nexport const newRequiredRule = imp(\"newRequiredRule@joist-orm\");\nexport const newRequiredLazyFieldRule = imp(\"newRequiredLazyFieldRule@joist-orm\");\nexport const cannotBeUpdated = imp(\"cannotBeUpdated@joist-orm\");\nexport const mustBeSubType = imp(\"mustBeSubType@joist-orm\");\nexport const cleanStringValue = imp(\"cleanStringValue@joist-orm\");\nexport const Changes = imp(\"t:Changes@joist-orm\");\nexport const newChangesProxy = imp(\"newChangesProxy@joist-orm\");\nexport const nowUTC = imp(\"nowUTC@joist-orm\");\nexport const LoadHint = imp(\"t:LoadHint@joist-orm\");\nexport const Loaded = imp(\"t:Loaded@joist-orm\");\nexport const isLoaded = imp(\"isLoaded@joist-orm\");\nexport const getInstanceData = imp(\"getInstanceData@joist-orm\");\nexport const isEntity = imp(\"isEntity@joist-orm\");\nexport const loadLens = imp(\"loadLens@joist-orm\");\nexport const hasOneThrough = imp(\"hasOneThrough@joist-orm\");\nexport const hasMany = imp(\"hasMany@joist-orm\");\nexport const hasLargeMany = imp(\"hasLargeMany@joist-orm\");\nexport const hasOne = imp(\"hasOne@joist-orm\");\nexport const hasRecursiveChildren = imp(\"hasRecursiveChildren@joist-orm\");\nexport const hasRecursiveM2m = imp(\"hasRecursiveM2m@joist-orm\");\nexport const hasRecursiveParents = imp(\"hasRecursiveParents@joist-orm\");\nexport const hasOnePolymorphic = imp(\"hasOnePolymorphic@joist-orm\");\nexport const hasOneToOne = imp(\"hasOneToOne@joist-orm\");\nexport const hasManyToMany = imp(\"hasManyToMany@joist-orm\");\nexport const hasEnumCollection = imp(\"hasEnumCollection@joist-orm\");\nexport const hasLargeManyToMany = imp(\"hasLargeManyToMany@joist-orm\");\nexport const newTestInstance = imp(\"newTestInstance@joist-orm\");\nexport const New = imp(\"t:New@joist-orm\");\nexport const DeepNew = imp(\"t:DeepNew@joist-orm\");\nexport const FactoryOpts = imp(\"t:FactoryOpts@joist-orm\");\nexport const SSAssert = imp(\"assert@superstruct\");\nexport const Zod = imp(\"z@zod\");\nexport const EntityConstructor = imp(\"t:EntityConstructor@joist-orm\");\nexport const MaybeAbstractEntityConstructor = imp(\"t:MaybeAbstractEntityConstructor@joist-orm\");\nexport const deTagId = imp(\"deTagId@joist-orm\");\nexport const toIdOf = imp(\"toIdOf@joist-orm\");\nexport const toJSON = imp(\"toJSON@joist-orm\");\nexport const ReactiveField = imp(\"t:ReactiveField@joist-orm\");\nexport const ReactiveReference = imp(\"t:ReactiveReference@joist-orm\");\nexport const ReactiveManyToMany = imp(\"t:ReactiveManyToMany@joist-orm\");\nexport const ReactiveManyToManyOtherSide = imp(\"t:ReactiveManyToManyOtherSide@joist-orm\");\nexport const hasReactiveManyToManyOtherSide = imp(\"hasReactiveManyToManyOtherSide@joist-orm\");\nexport const updatePartial = imp(\"updatePartial@joist-orm\");\nexport const setRuntimeConfig = imp(\"setRuntimeConfig@joist-orm\");\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"symbols.js","names":[],"sources":["../src/symbols.ts"],"sourcesContent":["import { imp } from \"ts-poet\";\n\nexport const ProjectEntity = imp(`t:Entity@./entities.ts`);\nexport const EntityManager = imp(\"EntityManager@./entities.ts\");\n\nexport const ConfigApi = imp(\"ConfigApi@joist-orm\");\nexport const newScopeFn = imp(\"newScopeFn@joist-orm\");\nexport const Scope = imp(\"t:Scope@joist-orm\");\nexport const FieldStatus = imp(\"t:FieldStatus@joist-orm\");\nexport const Entity = imp(\"t:Entity@joist-orm\");\nexport const BaseEntity = imp(\"BaseEntity@joist-orm\");\nexport const Flavor = imp(\"t:Flavor@joist-orm\");\nexport const Reference = imp(\"t:Reference@joist-orm\");\nexport const Collection = imp(\"t:Collection@joist-orm\");\nexport const EnumCollection = imp(\"t:EnumCollection@joist-orm\");\nexport const LargeCollection = imp(\"t:LargeCollection@joist-orm\");\nexport const OneToManyCollection = imp(\"OneToManyCollection@joist-orm\");\nexport const JoistEntityManager = imp(\"EntityManager@joist-orm\");\nexport const EntityMetadata = imp(\"t:EntityMetadata@joist-orm\");\nexport const EnumMetadata = imp(\"t:EnumMetadata@joist-orm\");\nexport const Lens = imp(\"t:Lens@joist-orm\");\nexport const KeySerde = imp(\"KeySerde@joist-orm\");\nexport const Column = imp(\"Column@joist-orm\");\nexport const ColumnDescriptors = imp(\"t:ColumnDescriptors@joist-orm\");\nexport const SimpleFieldSerde = imp(\"SimpleFieldSerde@joist-orm\");\nexport const PolyComponent = imp(\"PolyComponent@joist-orm\");\nexport const polymorphicField = imp(\"polymorphicField@joist-orm\");\nexport const ManyToOneReference = imp(\"t:ManyToOneReference@joist-orm\");\nexport const LazyField = imp(\"t:LazyField@joist-orm\");\nexport const hasLazyField = imp(\"hasLazyField@joist-orm\");\nexport const ReadOnlyCollection = imp(\"t:ReadOnlyCollection@joist-orm\");\nexport const PolymorphicReference = imp(\"t:PolymorphicReference@joist-orm\");\nexport const OneToOneReference = imp(\"t:OneToOneReference@joist-orm\");\nexport const ManyToManyCollection = imp(\"ManyToManyCollection@joist-orm\");\nexport const EnumFieldSerde = imp(\"EnumFieldSerde@joist-orm\");\nexport const EnumArrayFieldSerde = imp(\"EnumArrayFieldSerde@joist-orm\");\nexport const PolymorphicKeySerde = imp(\"PolymorphicKeySerde@joist-orm\");\nexport const PrimitiveSerde = imp(\"PrimitiveSerde@joist-orm\");\nexport const BigIntSerde = imp(\"BigIntSerde@joist-orm\");\nexport const DateSerde = imp(\"DateSerde@joist-orm\");\nexport const PlainDateSerde = imp(\"PlainDateSerde@joist-orm\");\nexport const PlainTimeSerde = imp(\"PlainTimeSerde@joist-orm\");\nexport const PlainDateTimeSerde = imp(\"PlainDateTimeSerde@joist-orm\");\nexport const ZonedDateTimeSerde = imp(\"ZonedDateTimeSerde@joist-orm\");\nexport const JsonSerde = imp(\"JsonSerde@joist-orm\");\nexport const VectorSerde = imp(\"VectorSerde@joist-orm\");\nexport const SuperstructSerde = imp(\"SuperstructSerde@joist-orm\");\nexport const TaggedId = imp(\"t:TaggedId@joist-orm\");\nexport const ZodSerde = imp(\"ZodSerde@joist-orm\");\nexport const CustomSerdeAdapter = imp(\"CustomSerdeAdapter@joist-orm\");\nexport const DecimalToNumberSerde = imp(\"DecimalToNumberSerde@joist-orm\");\nexport const fail = imp(\"fail@joist-orm\");\nexport const failNoIdYet = imp(\"failNoIdYet@joist-orm\");\nexport const setOpts = imp(\"setOpts@joist-orm\");\nexport const getField = imp(\"getField@joist-orm\");\nexport const setField = imp(\"setField@joist-orm\");\nexport const OrderBy = imp(\"t:OrderBy@joist-orm\");\nexport const OptsOf = imp(\"t:OptsOf@joist-orm\");\nexport const FieldsOf = imp(\"t:FieldsOf@joist-orm\");\nexport const RelationsOf = imp(\"t:RelationsOf@joist-orm\");\nexport const IdOf = imp(\"t:IdOf@joist-orm\");\nexport const PartialOrNull = imp(\"t:PartialOrNull@joist-orm\");\nexport const DeepPartialOrNull = imp(\"t:DeepPartialOrNull@joist-orm\");\nexport const BooleanFilter = imp(\"t:BooleanFilter@joist-orm\");\nexport const ValueFilter = imp(\"t:ValueFilter@joist-orm\");\nexport const EntityFilter = imp(\"t:EntityFilter@joist-orm\");\nexport const BooleanGraphQLFilter = imp(\"t:BooleanGraphQLFilter@joist-orm\");\nexport const EntityGraphQLFilter = imp(\"t:EntityGraphQLFilter@joist-orm\");\nexport const EnumGraphQLFilter = imp(\"t:EnumGraphQLFilter@joist-orm\");\nexport const ValueGraphQLFilter = imp(\"t:ValueGraphQLFilter@joist-orm\");\nexport const FilterOf = imp(\"t:FilterOf@joist-orm\");\nexport const GraphQLFilterOf = imp(\"t:GraphQLFilterOf@joist-orm\");\nexport const JsonHint = imp(\"t:JsonHint@joist-orm\");\nexport const ToJsonHint = imp(\"t:ToJsonHint@joist-orm\");\nexport const JsonPayload = imp(\"t:JsonPayload@joist-orm\");\nexport const configureMetadata = imp(\"configureMetadata@joist-orm\");\nexport const newRequiredRule = imp(\"newRequiredRule@joist-orm\");\nexport const newRequiredLazyFieldRule = imp(\"newRequiredLazyFieldRule@joist-orm\");\nexport const cannotBeUpdated = imp(\"cannotBeUpdated@joist-orm\");\nexport const mustBeSubType = imp(\"mustBeSubType@joist-orm\");\nexport const cleanStringValue = imp(\"cleanStringValue@joist-orm\");\nexport const Changes = imp(\"t:Changes@joist-orm\");\nexport const newChangesProxy = imp(\"newChangesProxy@joist-orm\");\nexport const nowUTC = imp(\"nowUTC@joist-orm\");\nexport const LoadHint = imp(\"t:LoadHint@joist-orm\");\nexport const Loaded = imp(\"t:Loaded@joist-orm\");\nexport const isLoaded = imp(\"isLoaded@joist-orm\");\nexport const getInstanceData = imp(\"getInstanceData@joist-orm\");\nexport const isEntity = imp(\"isEntity@joist-orm\");\nexport const loadLens = imp(\"loadLens@joist-orm\");\nexport const hasOneThrough = imp(\"hasOneThrough@joist-orm\");\nexport const hasMany = imp(\"hasMany@joist-orm\");\nexport const hasLargeMany = imp(\"hasLargeMany@joist-orm\");\nexport const hasOne = imp(\"hasOne@joist-orm\");\nexport const hasRecursiveChildren = imp(\"hasRecursiveChildren@joist-orm\");\nexport const hasRecursiveM2m = imp(\"hasRecursiveM2m@joist-orm\");\nexport const hasRecursiveParents = imp(\"hasRecursiveParents@joist-orm\");\nexport const hasOnePolymorphic = imp(\"hasOnePolymorphic@joist-orm\");\nexport const hasOneToOne = imp(\"hasOneToOne@joist-orm\");\nexport const hasManyToMany = imp(\"hasManyToMany@joist-orm\");\nexport const hasEnumCollection = imp(\"hasEnumCollection@joist-orm\");\nexport const hasLargeManyToMany = imp(\"hasLargeManyToMany@joist-orm\");\nexport const newTestInstance = imp(\"newTestInstance@joist-orm\");\nexport const New = imp(\"t:New@joist-orm\");\nexport const DeepNew = imp(\"t:DeepNew@joist-orm\");\nexport const FactoryOpts = imp(\"t:FactoryOpts@joist-orm\");\nexport const SSAssert = imp(\"assert@superstruct\");\nexport const Zod = imp(\"z@zod\");\nexport const EntityConstructor = imp(\"t:EntityConstructor@joist-orm\");\nexport const MaybeAbstractEntityConstructor = imp(\"t:MaybeAbstractEntityConstructor@joist-orm\");\nexport const deTagId = imp(\"deTagId@joist-orm\");\nexport const toIdOf = imp(\"toIdOf@joist-orm\");\nexport const toJSON = imp(\"toJSON@joist-orm\");\nexport const ReactiveField = imp(\"t:ReactiveField@joist-orm\");\nexport const ReactiveReference = imp(\"t:ReactiveReference@joist-orm\");\nexport const ReactiveManyToMany = imp(\"t:ReactiveManyToMany@joist-orm\");\nexport const ReactiveManyToManyOtherSide = imp(\"t:ReactiveManyToManyOtherSide@joist-orm\");\nexport const hasReactiveManyToManyOtherSide = imp(\"hasReactiveManyToManyOtherSide@joist-orm\");\nexport const updatePartial = imp(\"updatePartial@joist-orm\");\nexport const setRuntimeConfig = imp(\"setRuntimeConfig@joist-orm\");\n"],"mappings":"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"}
|
package/build/tsdoc.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/tsdoc.d.ts
|
|
2
|
-
declare const tsdocComments: {
|
|
2
|
+
export declare const tsdocComments: {
|
|
3
3
|
entity: {
|
|
4
4
|
setPartial: string;
|
|
5
5
|
setDeepPartial: string;
|
|
@@ -11,5 +11,4 @@ declare const tsdocComments: {
|
|
|
11
11
|
};
|
|
12
12
|
};
|
|
13
13
|
//#endregion
|
|
14
|
-
export { tsdocComments };
|
|
15
14
|
//# sourceMappingURL=tsdoc.d.cts.map
|
package/build/tsdoc.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tsdoc.d.cts","names":[],"sources":["../src/tsdoc.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"tsdoc.d.cts","names":[],"sources":["../src/tsdoc.ts"],"mappings":";qBAIa;EACX;IACE;IAmBA;IAoBA;IAKA;IAKA;IAKA;IAMA"}
|
package/build/tsdoc.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/tsdoc.d.ts
|
|
2
|
-
declare const tsdocComments: {
|
|
2
|
+
export declare const tsdocComments: {
|
|
3
3
|
entity: {
|
|
4
4
|
setPartial: string;
|
|
5
5
|
setDeepPartial: string;
|
|
@@ -11,5 +11,4 @@ declare const tsdocComments: {
|
|
|
11
11
|
};
|
|
12
12
|
};
|
|
13
13
|
//#endregion
|
|
14
|
-
export { tsdocComments };
|
|
15
14
|
//# sourceMappingURL=tsdoc.d.mts.map
|
package/build/tsdoc.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tsdoc.d.mts","names":[],"sources":["../src/tsdoc.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"tsdoc.d.mts","names":[],"sources":["../src/tsdoc.ts"],"mappings":";qBAIa;EACX;IACE;IAmBA;IAoBA;IAKA;IAKA;IAKA;IAMA"}
|
package/build/utils.cjs
CHANGED
|
@@ -107,6 +107,7 @@ function mapSimpleDbTypeToTypescriptType(config, dbType) {
|
|
|
107
107
|
case "date": return config.temporal ? plainDateCode : dateCode;
|
|
108
108
|
case "jsonb": return "Object";
|
|
109
109
|
case "bytea": return "Uint8Array";
|
|
110
|
+
case "vector": return "number[]";
|
|
110
111
|
default: assertNever(dbType);
|
|
111
112
|
}
|
|
112
113
|
}
|
package/build/utils.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.cjs","names":["getTimestampConfig","pascalCase","imp","isPlainObject"],"sources":["../src/utils.ts"],"sourcesContent":["import { pascalCase } from \"change-case\";\nimport { isPlainObject } from \"joist-utils\";\nimport pluralize from \"pluralize\";\nimport { code, imp } from \"ts-poet\";\n\nimport { type Config, getTimestampConfig } from \"./config.ts\";\nimport { type DatabaseColumnType, type PrimitiveTypescriptType } from \"./EntityDbMetadata.ts\";\nimport { type Table } from \"./pgMetadata.ts\";\n\nexport function assertNever(x: never): never {\n throw new Error(\"Unexpected object: \" + x);\n}\n\nexport function isEntityTable(config: Config, t: Table): boolean {\n if (isIgnored(config, t) || isJoinTable(config, t)) {\n return false;\n }\n\n // Depending on the config settings, we may/may not require the presence of timestamp\n // fields to determine whether a table is an entity.\n const columnNames = t.columns.map((c) => c.name);\n const { updatedAtConf, createdAtConf } = getTimestampConfig(config);\n const hasCreatedAt = createdAtConf.names.some((c) => columnNames.includes(c));\n const hasUpdatedAt = updatedAtConf.names.some((c) => columnNames.includes(c));\n\n // Entities always require an id column\n const hasIdColumn = columnNames.includes(\"id\");\n if (!hasIdColumn) return false;\n\n // If we have no timestamp columns, but do have `name` and `code`, we're probably an enum.\n if (hasIdColumn && !hasCreatedAt && !hasUpdatedAt) {\n if ([\"name\", \"code\"].every((c) => columnNames.includes(c))) {\n return false;\n }\n }\n\n // If the ID column is a FK then we're a subclass\n if (isSubClassTable(t)) return true;\n\n // Otherwise respect the created_at/updated_at required rules\n return hasIdColumn && (hasCreatedAt || !createdAtConf.required) && (hasUpdatedAt || !updatedAtConf.required);\n}\n\nexport function isSubClassTable(t: Table): boolean {\n // Note that `.get(\"id\")` will blow up if there is no id column\n return t.columns.get(\"id\").foreignKeys.length === 1;\n}\n\nexport function isEnumTable(config: Config, t: Table): boolean {\n if (isIgnored(config, t)) {\n return false;\n }\n const columnNames = t.columns.map((c) => c.name);\n return [\"id\", \"code\", \"name\"].every((c) => columnNames.includes(c)) && !isEntityTable(config, t);\n}\n\n// Oddly enough isJoinTable showed up as a hot spot, so cache its calculation.\nconst joinTables: Map<string, boolean> = new Map();\n\nexport function isJoinTable(config: Config, t: Table): boolean {\n if (isIgnored(config, t)) {\n return false;\n }\n return getOrElse(joinTables, t.name, () => {\n const { columns } = t;\n const fks = columns.filter((c) => c.isForeignKey);\n const pks = columns.filter((c) => c.isPrimaryKey);\n // Every join table is two FKs, plus either a surrogate `id` PK (\"id-ful\") or no surrogate\n // at all, in which case the two FKs are themselves the composite PK (\"id-less\").\n if (fks.length !== 2) return false;\n if (!joinTableHasId(t) && !(pks.length === 2 && pks.every((c) => c.isForeignKey))) return false;\n // Any column beyond the two FKs and the optional `id` PK must be a single created_at.\n const others = columns.length - fks.length - (joinTableHasId(t) ? 1 : 0);\n const createdAts = columns.filter((c) => c.name === \"created_at\" || c.name === \"createdAt\").length;\n return others === 0 || (others === 1 && createdAts === 1);\n });\n}\n\n/** Whether a join table has a surrogate `id` primary key (vs. an id-less FK-pair composite PK). */\nexport function joinTableHasId(t: Table): boolean {\n const pks = t.columns.filter((c) => c.isPrimaryKey);\n return pks.length === 1 && !pks[0].isForeignKey;\n}\n\nfunction getOrElse<K, V>(map: Map<K, V>, key: K, fn: () => V): V {\n let value = map.get(key);\n if (value === undefined) {\n value = fn();\n map.set(key, value);\n }\n return value;\n}\n\n/** Converts `projects` to `Project`. */\nexport function tableToEntityName(config: Config, table: Table): string {\n let entityName = config.__tableToEntityName?.[table.name];\n if (!entityName) {\n const configEntityName = Object.entries(config.entities)\n .filter(([, conf]) => conf.tableName === table.name)\n .map(([entityName]) => entityName)[0];\n entityName = configEntityName || pascalCase(pluralize.singular(table.name));\n (config.__tableToEntityName ??= {})[table.name] = entityName;\n }\n return entityName;\n}\n\nexport const dateCode = code`Date`;\nexport const plainDateCode = code`${imp(\"Temporal@joist-orm\")}.PlainDate`;\nexport const plainTimeCode = code`${imp(\"Temporal@joist-orm\")}.PlainTime`;\nexport const plainDateTimeCode = code`${imp(\"Temporal@joist-orm\")}.PlainDateTime`;\nexport const zonedDateTimeCode = code`${imp(\"Temporal@joist-orm\")}.ZonedDateTime`;\n\n/** Maps db types, i.e. `int`, to JS types, i.e. `number`. */\nexport function mapSimpleDbTypeToTypescriptType(config: Config, dbType: DatabaseColumnType): PrimitiveTypescriptType {\n switch (dbType) {\n case \"boolean\":\n return \"boolean\";\n case \"int\":\n case \"numeric\":\n case \"smallint\":\n case \"integer\":\n case \"decimal\":\n case \"real\":\n case \"smallserial\":\n case \"serial\":\n case \"double precision\":\n return \"number\";\n case \"bigserial\":\n case \"bigint\":\n return \"bigint\";\n case \"text\":\n case \"citext\":\n case \"character varying\":\n case \"varchar\":\n case \"uuid\":\n case \"tsvector\":\n case \"tstzrange\":\n return \"string\";\n case \"time without time zone\":\n return config.temporal\n ? plainTimeCode\n : fail(\"Joist doesn't support 'time without time zone' unless temporal is enabled\");\n case \"timestamp with time zone\":\n return config.temporal ? zonedDateTimeCode : dateCode;\n case \"timestamp without time zone\":\n return config.temporal ? plainDateTimeCode : dateCode;\n case \"date\":\n return config.temporal ? plainDateCode : dateCode;\n case \"jsonb\":\n return \"Object\";\n case \"bytea\":\n return \"Uint8Array\";\n default:\n assertNever(dbType);\n }\n}\n\nexport function merge<T>(a: T[], b: T[]): T[] {\n return [...a, ...b];\n}\n\n/** Returns true if `p` is resolved, otherwise false if it is rejected. */\nexport async function trueIfResolved(p: Promise<unknown>): Promise<boolean> {\n return p.then(\n () => true,\n () => false,\n );\n}\n\nexport function fail(message?: string): never {\n throw new Error(message || \"Failed\");\n}\n\nexport function sortKeys<T extends object>(o: T): T {\n return Object.keys(o)\n .sort()\n .reduce(\n (acc, key) => {\n const value = o[key as keyof T];\n const newValue = typeof value === \"object\" && isPlainObject(value) ? sortKeys(value as any as object) : value;\n acc[key as keyof T] = newValue as any;\n return acc;\n },\n {} as any as T,\n );\n}\n\nexport function parseOrder(order: string | undefined): { field: string; direction: \"ASC\" | \"DESC\" } | undefined {\n if (!order) {\n return undefined;\n }\n const [field, direction = \"ASC\"] = order.split(\" \");\n if (direction !== \"ASC\" && direction !== \"DESC\") {\n throw new Error(`Invalid direction: ${direction} (must be \"ASC\" or \"DESC\")`);\n }\n return { field, direction };\n}\n\nexport function q(s: string | undefined): string {\n return s === undefined ? \"undefined\" : `\"${s}\"`;\n}\n\nexport function uncapitalize(s: string): string {\n return s.charAt(0).toLowerCase() + s.slice(1);\n}\n\nfunction isIgnored(config: Config, t: Table): boolean {\n return (config.ignoredTables || [\"migrations\", \"pgmigrations\"]).includes(t.name) || !shouldIncludeSchema(config, t);\n}\n\n/** Uses the same schema selection for metadata and test database cleanup. */\nexport function shouldIncludeSchema(config: Config, t: Table): boolean {\n return config.schemas ? config.schemas.includes(t.schema.name) : t.schema.name === \"public\";\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utils.cjs","names":["getTimestampConfig","pascalCase","imp","isPlainObject"],"sources":["../src/utils.ts"],"sourcesContent":["import { pascalCase } from \"change-case\";\nimport { isPlainObject } from \"joist-utils\";\nimport pluralize from \"pluralize\";\nimport { code, imp } from \"ts-poet\";\n\nimport { type Config, getTimestampConfig } from \"./config.ts\";\nimport { type DatabaseColumnType, type PrimitiveTypescriptType } from \"./EntityDbMetadata.ts\";\nimport { type Table } from \"./pgMetadata.ts\";\n\nexport function assertNever(x: never): never {\n throw new Error(\"Unexpected object: \" + x);\n}\n\nexport function isEntityTable(config: Config, t: Table): boolean {\n if (isIgnored(config, t) || isJoinTable(config, t)) {\n return false;\n }\n\n // Depending on the config settings, we may/may not require the presence of timestamp\n // fields to determine whether a table is an entity.\n const columnNames = t.columns.map((c) => c.name);\n const { updatedAtConf, createdAtConf } = getTimestampConfig(config);\n const hasCreatedAt = createdAtConf.names.some((c) => columnNames.includes(c));\n const hasUpdatedAt = updatedAtConf.names.some((c) => columnNames.includes(c));\n\n // Entities always require an id column\n const hasIdColumn = columnNames.includes(\"id\");\n if (!hasIdColumn) return false;\n\n // If we have no timestamp columns, but do have `name` and `code`, we're probably an enum.\n if (hasIdColumn && !hasCreatedAt && !hasUpdatedAt) {\n if ([\"name\", \"code\"].every((c) => columnNames.includes(c))) {\n return false;\n }\n }\n\n // If the ID column is a FK then we're a subclass\n if (isSubClassTable(t)) return true;\n\n // Otherwise respect the created_at/updated_at required rules\n return hasIdColumn && (hasCreatedAt || !createdAtConf.required) && (hasUpdatedAt || !updatedAtConf.required);\n}\n\nexport function isSubClassTable(t: Table): boolean {\n // Note that `.get(\"id\")` will blow up if there is no id column\n return t.columns.get(\"id\").foreignKeys.length === 1;\n}\n\nexport function isEnumTable(config: Config, t: Table): boolean {\n if (isIgnored(config, t)) {\n return false;\n }\n const columnNames = t.columns.map((c) => c.name);\n return [\"id\", \"code\", \"name\"].every((c) => columnNames.includes(c)) && !isEntityTable(config, t);\n}\n\n// Oddly enough isJoinTable showed up as a hot spot, so cache its calculation.\nconst joinTables: Map<string, boolean> = new Map();\n\nexport function isJoinTable(config: Config, t: Table): boolean {\n if (isIgnored(config, t)) {\n return false;\n }\n return getOrElse(joinTables, t.name, () => {\n const { columns } = t;\n const fks = columns.filter((c) => c.isForeignKey);\n const pks = columns.filter((c) => c.isPrimaryKey);\n // Every join table is two FKs, plus either a surrogate `id` PK (\"id-ful\") or no surrogate\n // at all, in which case the two FKs are themselves the composite PK (\"id-less\").\n if (fks.length !== 2) return false;\n if (!joinTableHasId(t) && !(pks.length === 2 && pks.every((c) => c.isForeignKey))) return false;\n // Any column beyond the two FKs and the optional `id` PK must be a single created_at.\n const others = columns.length - fks.length - (joinTableHasId(t) ? 1 : 0);\n const createdAts = columns.filter((c) => c.name === \"created_at\" || c.name === \"createdAt\").length;\n return others === 0 || (others === 1 && createdAts === 1);\n });\n}\n\n/** Whether a join table has a surrogate `id` primary key (vs. an id-less FK-pair composite PK). */\nexport function joinTableHasId(t: Table): boolean {\n const pks = t.columns.filter((c) => c.isPrimaryKey);\n return pks.length === 1 && !pks[0].isForeignKey;\n}\n\nfunction getOrElse<K, V>(map: Map<K, V>, key: K, fn: () => V): V {\n let value = map.get(key);\n if (value === undefined) {\n value = fn();\n map.set(key, value);\n }\n return value;\n}\n\n/** Converts `projects` to `Project`. */\nexport function tableToEntityName(config: Config, table: Table): string {\n let entityName = config.__tableToEntityName?.[table.name];\n if (!entityName) {\n const configEntityName = Object.entries(config.entities)\n .filter(([, conf]) => conf.tableName === table.name)\n .map(([entityName]) => entityName)[0];\n entityName = configEntityName || pascalCase(pluralize.singular(table.name));\n (config.__tableToEntityName ??= {})[table.name] = entityName;\n }\n return entityName;\n}\n\nexport const dateCode = code`Date`;\nexport const plainDateCode = code`${imp(\"Temporal@joist-orm\")}.PlainDate`;\nexport const plainTimeCode = code`${imp(\"Temporal@joist-orm\")}.PlainTime`;\nexport const plainDateTimeCode = code`${imp(\"Temporal@joist-orm\")}.PlainDateTime`;\nexport const zonedDateTimeCode = code`${imp(\"Temporal@joist-orm\")}.ZonedDateTime`;\n\n/** Maps db types, i.e. `int`, to JS types, i.e. `number`. */\nexport function mapSimpleDbTypeToTypescriptType(config: Config, dbType: DatabaseColumnType): PrimitiveTypescriptType {\n switch (dbType) {\n case \"boolean\":\n return \"boolean\";\n case \"int\":\n case \"numeric\":\n case \"smallint\":\n case \"integer\":\n case \"decimal\":\n case \"real\":\n case \"smallserial\":\n case \"serial\":\n case \"double precision\":\n return \"number\";\n case \"bigserial\":\n case \"bigint\":\n return \"bigint\";\n case \"text\":\n case \"citext\":\n case \"character varying\":\n case \"varchar\":\n case \"uuid\":\n case \"tsvector\":\n case \"tstzrange\":\n return \"string\";\n case \"time without time zone\":\n return config.temporal\n ? plainTimeCode\n : fail(\"Joist doesn't support 'time without time zone' unless temporal is enabled\");\n case \"timestamp with time zone\":\n return config.temporal ? zonedDateTimeCode : dateCode;\n case \"timestamp without time zone\":\n return config.temporal ? plainDateTimeCode : dateCode;\n case \"date\":\n return config.temporal ? plainDateCode : dateCode;\n case \"jsonb\":\n return \"Object\";\n case \"bytea\":\n return \"Uint8Array\";\n case \"vector\":\n // pgvector columns are a single value (not a physical pg array), so `isArray` stays false\n return \"number[]\";\n default:\n assertNever(dbType);\n }\n}\n\nexport function merge<T>(a: T[], b: T[]): T[] {\n return [...a, ...b];\n}\n\n/** Returns true if `p` is resolved, otherwise false if it is rejected. */\nexport async function trueIfResolved(p: Promise<unknown>): Promise<boolean> {\n return p.then(\n () => true,\n () => false,\n );\n}\n\nexport function fail(message?: string): never {\n throw new Error(message || \"Failed\");\n}\n\nexport function sortKeys<T extends object>(o: T): T {\n return Object.keys(o)\n .sort()\n .reduce(\n (acc, key) => {\n const value = o[key as keyof T];\n const newValue = typeof value === \"object\" && isPlainObject(value) ? sortKeys(value as any as object) : value;\n acc[key as keyof T] = newValue as any;\n return acc;\n },\n {} as any as T,\n );\n}\n\nexport function parseOrder(order: string | undefined): { field: string; direction: \"ASC\" | \"DESC\" } | undefined {\n if (!order) {\n return undefined;\n }\n const [field, direction = \"ASC\"] = order.split(\" \");\n if (direction !== \"ASC\" && direction !== \"DESC\") {\n throw new Error(`Invalid direction: ${direction} (must be \"ASC\" or \"DESC\")`);\n }\n return { field, direction };\n}\n\nexport function q(s: string | undefined): string {\n return s === undefined ? \"undefined\" : `\"${s}\"`;\n}\n\nexport function uncapitalize(s: string): string {\n return s.charAt(0).toLowerCase() + s.slice(1);\n}\n\nfunction isIgnored(config: Config, t: Table): boolean {\n return (config.ignoredTables || [\"migrations\", \"pgmigrations\"]).includes(t.name) || !shouldIncludeSchema(config, t);\n}\n\n/** Uses the same schema selection for metadata and test database cleanup. */\nexport function shouldIncludeSchema(config: Config, t: Table): boolean {\n return config.schemas ? config.schemas.includes(t.schema.name) : t.schema.name === \"public\";\n}\n"],"mappings":"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"}
|
package/build/utils.d.cts
CHANGED
|
@@ -2,35 +2,34 @@ import { Config } from "./config.cjs";
|
|
|
2
2
|
import { Table } from "./pgMetadata.cjs";
|
|
3
3
|
import { DatabaseColumnType, PrimitiveTypescriptType } from "./EntityDbMetadata.cjs";
|
|
4
4
|
//#region src/utils.d.ts
|
|
5
|
-
declare function assertNever(x: never): never;
|
|
6
|
-
declare function isEntityTable(config: Config, t: Table): boolean;
|
|
7
|
-
declare function isSubClassTable(t: Table): boolean;
|
|
8
|
-
declare function isEnumTable(config: Config, t: Table): boolean;
|
|
9
|
-
declare function isJoinTable(config: Config, t: Table): boolean;
|
|
5
|
+
export declare function assertNever(x: never): never;
|
|
6
|
+
export declare function isEntityTable(config: Config, t: Table): boolean;
|
|
7
|
+
export declare function isSubClassTable(t: Table): boolean;
|
|
8
|
+
export declare function isEnumTable(config: Config, t: Table): boolean;
|
|
9
|
+
export declare function isJoinTable(config: Config, t: Table): boolean;
|
|
10
10
|
/** Whether a join table has a surrogate `id` primary key (vs. an id-less FK-pair composite PK). */
|
|
11
|
-
declare function joinTableHasId(t: Table): boolean;
|
|
11
|
+
export declare function joinTableHasId(t: Table): boolean;
|
|
12
12
|
/** Converts `projects` to `Project`. */
|
|
13
|
-
declare function tableToEntityName(config: Config, table: Table): string;
|
|
14
|
-
declare const dateCode: import("ts-poet").Code;
|
|
15
|
-
declare const plainDateCode: import("ts-poet").Code;
|
|
16
|
-
declare const plainTimeCode: import("ts-poet").Code;
|
|
17
|
-
declare const plainDateTimeCode: import("ts-poet").Code;
|
|
18
|
-
declare const zonedDateTimeCode: import("ts-poet").Code;
|
|
13
|
+
export declare function tableToEntityName(config: Config, table: Table): string;
|
|
14
|
+
export declare const dateCode: import("ts-poet").Code;
|
|
15
|
+
export declare const plainDateCode: import("ts-poet").Code;
|
|
16
|
+
export declare const plainTimeCode: import("ts-poet").Code;
|
|
17
|
+
export declare const plainDateTimeCode: import("ts-poet").Code;
|
|
18
|
+
export declare const zonedDateTimeCode: import("ts-poet").Code;
|
|
19
19
|
/** Maps db types, i.e. `int`, to JS types, i.e. `number`. */
|
|
20
|
-
declare function mapSimpleDbTypeToTypescriptType(config: Config, dbType: DatabaseColumnType): PrimitiveTypescriptType;
|
|
21
|
-
declare function merge<T>(a: T[], b: T[]): T[];
|
|
20
|
+
export declare function mapSimpleDbTypeToTypescriptType(config: Config, dbType: DatabaseColumnType): PrimitiveTypescriptType;
|
|
21
|
+
export declare function merge<T>(a: T[], b: T[]): T[];
|
|
22
22
|
/** Returns true if `p` is resolved, otherwise false if it is rejected. */
|
|
23
|
-
declare function trueIfResolved(p: Promise<unknown>): Promise<boolean>;
|
|
24
|
-
declare function fail(message?: string): never;
|
|
25
|
-
declare function sortKeys<T extends object>(o: T): T;
|
|
26
|
-
declare function parseOrder(order: string | undefined): {
|
|
23
|
+
export declare function trueIfResolved(p: Promise<unknown>): Promise<boolean>;
|
|
24
|
+
export declare function fail(message?: string): never;
|
|
25
|
+
export declare function sortKeys<T extends object>(o: T): T;
|
|
26
|
+
export declare function parseOrder(order: string | undefined): {
|
|
27
27
|
field: string;
|
|
28
28
|
direction: "ASC" | "DESC";
|
|
29
29
|
} | undefined;
|
|
30
|
-
declare function q(s: string | undefined): string;
|
|
31
|
-
declare function uncapitalize(s: string): string;
|
|
30
|
+
export declare function q(s: string | undefined): string;
|
|
31
|
+
export declare function uncapitalize(s: string): string;
|
|
32
32
|
/** Uses the same schema selection for metadata and test database cleanup. */
|
|
33
|
-
declare function shouldIncludeSchema(config: Config, t: Table): boolean;
|
|
33
|
+
export declare function shouldIncludeSchema(config: Config, t: Table): boolean;
|
|
34
34
|
//#endregion
|
|
35
|
-
export { assertNever, dateCode, fail, isEntityTable, isEnumTable, isJoinTable, isSubClassTable, joinTableHasId, mapSimpleDbTypeToTypescriptType, merge, parseOrder, plainDateCode, plainDateTimeCode, plainTimeCode, q, shouldIncludeSchema, sortKeys, tableToEntityName, trueIfResolved, uncapitalize, zonedDateTimeCode };
|
|
36
35
|
//# sourceMappingURL=utils.d.cts.map
|
package/build/utils.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.cts","names":[],"sources":["../src/utils.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"utils.d.cts","names":[],"sources":["../src/utils.ts"],"mappings":";;;;wBASgB,YAAY;wBAIZ,cAAc,QAAQ,QAAQ,GAAG;wBA8BjC,gBAAgB,GAAG;wBAKnB,YAAY,QAAQ,QAAQ,GAAG;wBAW/B,YAAY,QAAQ,QAAQ,GAAG;;wBAoB/B,eAAe,GAAG;;wBAelB,kBAAkB,QAAQ,QAAQ,OAAO;qBAY5C,4BAAQ;qBACR,iCAAa;qBACb,iCAAa;qBACb,qCAAiB;qBACjB,qCAAiB;;wBAGd,gCAAgC,QAAQ,QAAQ,QAAQ,qBAAqB;wBA+C7E,MAAM,GAAG,GAAG,KAAK,GAAG,MAAM;;wBAKpB,eAAe,GAAG,mBAAmB;wBAO3C,KAAK;wBAIL,SAAS,kBAAkB,GAAG,IAAI;wBAclC,WAAW;EAA8B;EAAe;;wBAWxD,EAAE;wBAIF,aAAa;;wBASb,oBAAoB,QAAQ,QAAQ,GAAG"}
|
package/build/utils.d.mts
CHANGED
|
@@ -2,35 +2,34 @@ import { Config } from "./config.mjs";
|
|
|
2
2
|
import { Table } from "./pgMetadata.mjs";
|
|
3
3
|
import { DatabaseColumnType, PrimitiveTypescriptType } from "./EntityDbMetadata.mjs";
|
|
4
4
|
//#region src/utils.d.ts
|
|
5
|
-
declare function assertNever(x: never): never;
|
|
6
|
-
declare function isEntityTable(config: Config, t: Table): boolean;
|
|
7
|
-
declare function isSubClassTable(t: Table): boolean;
|
|
8
|
-
declare function isEnumTable(config: Config, t: Table): boolean;
|
|
9
|
-
declare function isJoinTable(config: Config, t: Table): boolean;
|
|
5
|
+
export declare function assertNever(x: never): never;
|
|
6
|
+
export declare function isEntityTable(config: Config, t: Table): boolean;
|
|
7
|
+
export declare function isSubClassTable(t: Table): boolean;
|
|
8
|
+
export declare function isEnumTable(config: Config, t: Table): boolean;
|
|
9
|
+
export declare function isJoinTable(config: Config, t: Table): boolean;
|
|
10
10
|
/** Whether a join table has a surrogate `id` primary key (vs. an id-less FK-pair composite PK). */
|
|
11
|
-
declare function joinTableHasId(t: Table): boolean;
|
|
11
|
+
export declare function joinTableHasId(t: Table): boolean;
|
|
12
12
|
/** Converts `projects` to `Project`. */
|
|
13
|
-
declare function tableToEntityName(config: Config, table: Table): string;
|
|
14
|
-
declare const dateCode: import("ts-poet").Code;
|
|
15
|
-
declare const plainDateCode: import("ts-poet").Code;
|
|
16
|
-
declare const plainTimeCode: import("ts-poet").Code;
|
|
17
|
-
declare const plainDateTimeCode: import("ts-poet").Code;
|
|
18
|
-
declare const zonedDateTimeCode: import("ts-poet").Code;
|
|
13
|
+
export declare function tableToEntityName(config: Config, table: Table): string;
|
|
14
|
+
export declare const dateCode: import("ts-poet").Code;
|
|
15
|
+
export declare const plainDateCode: import("ts-poet").Code;
|
|
16
|
+
export declare const plainTimeCode: import("ts-poet").Code;
|
|
17
|
+
export declare const plainDateTimeCode: import("ts-poet").Code;
|
|
18
|
+
export declare const zonedDateTimeCode: import("ts-poet").Code;
|
|
19
19
|
/** Maps db types, i.e. `int`, to JS types, i.e. `number`. */
|
|
20
|
-
declare function mapSimpleDbTypeToTypescriptType(config: Config, dbType: DatabaseColumnType): PrimitiveTypescriptType;
|
|
21
|
-
declare function merge<T>(a: T[], b: T[]): T[];
|
|
20
|
+
export declare function mapSimpleDbTypeToTypescriptType(config: Config, dbType: DatabaseColumnType): PrimitiveTypescriptType;
|
|
21
|
+
export declare function merge<T>(a: T[], b: T[]): T[];
|
|
22
22
|
/** Returns true if `p` is resolved, otherwise false if it is rejected. */
|
|
23
|
-
declare function trueIfResolved(p: Promise<unknown>): Promise<boolean>;
|
|
24
|
-
declare function fail(message?: string): never;
|
|
25
|
-
declare function sortKeys<T extends object>(o: T): T;
|
|
26
|
-
declare function parseOrder(order: string | undefined): {
|
|
23
|
+
export declare function trueIfResolved(p: Promise<unknown>): Promise<boolean>;
|
|
24
|
+
export declare function fail(message?: string): never;
|
|
25
|
+
export declare function sortKeys<T extends object>(o: T): T;
|
|
26
|
+
export declare function parseOrder(order: string | undefined): {
|
|
27
27
|
field: string;
|
|
28
28
|
direction: "ASC" | "DESC";
|
|
29
29
|
} | undefined;
|
|
30
|
-
declare function q(s: string | undefined): string;
|
|
31
|
-
declare function uncapitalize(s: string): string;
|
|
30
|
+
export declare function q(s: string | undefined): string;
|
|
31
|
+
export declare function uncapitalize(s: string): string;
|
|
32
32
|
/** Uses the same schema selection for metadata and test database cleanup. */
|
|
33
|
-
declare function shouldIncludeSchema(config: Config, t: Table): boolean;
|
|
33
|
+
export declare function shouldIncludeSchema(config: Config, t: Table): boolean;
|
|
34
34
|
//#endregion
|
|
35
|
-
export { assertNever, dateCode, fail, isEntityTable, isEnumTable, isJoinTable, isSubClassTable, joinTableHasId, mapSimpleDbTypeToTypescriptType, merge, parseOrder, plainDateCode, plainDateTimeCode, plainTimeCode, q, shouldIncludeSchema, sortKeys, tableToEntityName, trueIfResolved, uncapitalize, zonedDateTimeCode };
|
|
36
35
|
//# sourceMappingURL=utils.d.mts.map
|
package/build/utils.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.mts","names":[],"sources":["../src/utils.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"utils.d.mts","names":[],"sources":["../src/utils.ts"],"mappings":";;;;wBASgB,YAAY;wBAIZ,cAAc,QAAQ,QAAQ,GAAG;wBA8BjC,gBAAgB,GAAG;wBAKnB,YAAY,QAAQ,QAAQ,GAAG;wBAW/B,YAAY,QAAQ,QAAQ,GAAG;;wBAoB/B,eAAe,GAAG;;wBAelB,kBAAkB,QAAQ,QAAQ,OAAO;qBAY5C,4BAAQ;qBACR,iCAAa;qBACb,iCAAa;qBACb,qCAAiB;qBACjB,qCAAiB;;wBAGd,gCAAgC,QAAQ,QAAQ,QAAQ,qBAAqB;wBA+C7E,MAAM,GAAG,GAAG,KAAK,GAAG,MAAM;;wBAKpB,eAAe,GAAG,mBAAmB;wBAO3C,KAAK;wBAIL,SAAS,kBAAkB,GAAG,IAAI;wBAclC,WAAW;EAA8B;EAAe;;wBAWxD,EAAE;wBAIF,aAAa;;wBASb,oBAAoB,QAAQ,QAAQ,GAAG"}
|
package/build/utils.js
CHANGED
|
@@ -104,6 +104,7 @@ function mapSimpleDbTypeToTypescriptType(config, dbType) {
|
|
|
104
104
|
case "date": return config.temporal ? plainDateCode : dateCode;
|
|
105
105
|
case "jsonb": return "Object";
|
|
106
106
|
case "bytea": return "Uint8Array";
|
|
107
|
+
case "vector": return "number[]";
|
|
107
108
|
default: assertNever(dbType);
|
|
108
109
|
}
|
|
109
110
|
}
|
package/build/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import { pascalCase } from \"change-case\";\nimport { isPlainObject } from \"joist-utils\";\nimport pluralize from \"pluralize\";\nimport { code, imp } from \"ts-poet\";\n\nimport { type Config, getTimestampConfig } from \"./config.ts\";\nimport { type DatabaseColumnType, type PrimitiveTypescriptType } from \"./EntityDbMetadata.ts\";\nimport { type Table } from \"./pgMetadata.ts\";\n\nexport function assertNever(x: never): never {\n throw new Error(\"Unexpected object: \" + x);\n}\n\nexport function isEntityTable(config: Config, t: Table): boolean {\n if (isIgnored(config, t) || isJoinTable(config, t)) {\n return false;\n }\n\n // Depending on the config settings, we may/may not require the presence of timestamp\n // fields to determine whether a table is an entity.\n const columnNames = t.columns.map((c) => c.name);\n const { updatedAtConf, createdAtConf } = getTimestampConfig(config);\n const hasCreatedAt = createdAtConf.names.some((c) => columnNames.includes(c));\n const hasUpdatedAt = updatedAtConf.names.some((c) => columnNames.includes(c));\n\n // Entities always require an id column\n const hasIdColumn = columnNames.includes(\"id\");\n if (!hasIdColumn) return false;\n\n // If we have no timestamp columns, but do have `name` and `code`, we're probably an enum.\n if (hasIdColumn && !hasCreatedAt && !hasUpdatedAt) {\n if ([\"name\", \"code\"].every((c) => columnNames.includes(c))) {\n return false;\n }\n }\n\n // If the ID column is a FK then we're a subclass\n if (isSubClassTable(t)) return true;\n\n // Otherwise respect the created_at/updated_at required rules\n return hasIdColumn && (hasCreatedAt || !createdAtConf.required) && (hasUpdatedAt || !updatedAtConf.required);\n}\n\nexport function isSubClassTable(t: Table): boolean {\n // Note that `.get(\"id\")` will blow up if there is no id column\n return t.columns.get(\"id\").foreignKeys.length === 1;\n}\n\nexport function isEnumTable(config: Config, t: Table): boolean {\n if (isIgnored(config, t)) {\n return false;\n }\n const columnNames = t.columns.map((c) => c.name);\n return [\"id\", \"code\", \"name\"].every((c) => columnNames.includes(c)) && !isEntityTable(config, t);\n}\n\n// Oddly enough isJoinTable showed up as a hot spot, so cache its calculation.\nconst joinTables: Map<string, boolean> = new Map();\n\nexport function isJoinTable(config: Config, t: Table): boolean {\n if (isIgnored(config, t)) {\n return false;\n }\n return getOrElse(joinTables, t.name, () => {\n const { columns } = t;\n const fks = columns.filter((c) => c.isForeignKey);\n const pks = columns.filter((c) => c.isPrimaryKey);\n // Every join table is two FKs, plus either a surrogate `id` PK (\"id-ful\") or no surrogate\n // at all, in which case the two FKs are themselves the composite PK (\"id-less\").\n if (fks.length !== 2) return false;\n if (!joinTableHasId(t) && !(pks.length === 2 && pks.every((c) => c.isForeignKey))) return false;\n // Any column beyond the two FKs and the optional `id` PK must be a single created_at.\n const others = columns.length - fks.length - (joinTableHasId(t) ? 1 : 0);\n const createdAts = columns.filter((c) => c.name === \"created_at\" || c.name === \"createdAt\").length;\n return others === 0 || (others === 1 && createdAts === 1);\n });\n}\n\n/** Whether a join table has a surrogate `id` primary key (vs. an id-less FK-pair composite PK). */\nexport function joinTableHasId(t: Table): boolean {\n const pks = t.columns.filter((c) => c.isPrimaryKey);\n return pks.length === 1 && !pks[0].isForeignKey;\n}\n\nfunction getOrElse<K, V>(map: Map<K, V>, key: K, fn: () => V): V {\n let value = map.get(key);\n if (value === undefined) {\n value = fn();\n map.set(key, value);\n }\n return value;\n}\n\n/** Converts `projects` to `Project`. */\nexport function tableToEntityName(config: Config, table: Table): string {\n let entityName = config.__tableToEntityName?.[table.name];\n if (!entityName) {\n const configEntityName = Object.entries(config.entities)\n .filter(([, conf]) => conf.tableName === table.name)\n .map(([entityName]) => entityName)[0];\n entityName = configEntityName || pascalCase(pluralize.singular(table.name));\n (config.__tableToEntityName ??= {})[table.name] = entityName;\n }\n return entityName;\n}\n\nexport const dateCode = code`Date`;\nexport const plainDateCode = code`${imp(\"Temporal@joist-orm\")}.PlainDate`;\nexport const plainTimeCode = code`${imp(\"Temporal@joist-orm\")}.PlainTime`;\nexport const plainDateTimeCode = code`${imp(\"Temporal@joist-orm\")}.PlainDateTime`;\nexport const zonedDateTimeCode = code`${imp(\"Temporal@joist-orm\")}.ZonedDateTime`;\n\n/** Maps db types, i.e. `int`, to JS types, i.e. `number`. */\nexport function mapSimpleDbTypeToTypescriptType(config: Config, dbType: DatabaseColumnType): PrimitiveTypescriptType {\n switch (dbType) {\n case \"boolean\":\n return \"boolean\";\n case \"int\":\n case \"numeric\":\n case \"smallint\":\n case \"integer\":\n case \"decimal\":\n case \"real\":\n case \"smallserial\":\n case \"serial\":\n case \"double precision\":\n return \"number\";\n case \"bigserial\":\n case \"bigint\":\n return \"bigint\";\n case \"text\":\n case \"citext\":\n case \"character varying\":\n case \"varchar\":\n case \"uuid\":\n case \"tsvector\":\n case \"tstzrange\":\n return \"string\";\n case \"time without time zone\":\n return config.temporal\n ? plainTimeCode\n : fail(\"Joist doesn't support 'time without time zone' unless temporal is enabled\");\n case \"timestamp with time zone\":\n return config.temporal ? zonedDateTimeCode : dateCode;\n case \"timestamp without time zone\":\n return config.temporal ? plainDateTimeCode : dateCode;\n case \"date\":\n return config.temporal ? plainDateCode : dateCode;\n case \"jsonb\":\n return \"Object\";\n case \"bytea\":\n return \"Uint8Array\";\n default:\n assertNever(dbType);\n }\n}\n\nexport function merge<T>(a: T[], b: T[]): T[] {\n return [...a, ...b];\n}\n\n/** Returns true if `p` is resolved, otherwise false if it is rejected. */\nexport async function trueIfResolved(p: Promise<unknown>): Promise<boolean> {\n return p.then(\n () => true,\n () => false,\n );\n}\n\nexport function fail(message?: string): never {\n throw new Error(message || \"Failed\");\n}\n\nexport function sortKeys<T extends object>(o: T): T {\n return Object.keys(o)\n .sort()\n .reduce(\n (acc, key) => {\n const value = o[key as keyof T];\n const newValue = typeof value === \"object\" && isPlainObject(value) ? sortKeys(value as any as object) : value;\n acc[key as keyof T] = newValue as any;\n return acc;\n },\n {} as any as T,\n );\n}\n\nexport function parseOrder(order: string | undefined): { field: string; direction: \"ASC\" | \"DESC\" } | undefined {\n if (!order) {\n return undefined;\n }\n const [field, direction = \"ASC\"] = order.split(\" \");\n if (direction !== \"ASC\" && direction !== \"DESC\") {\n throw new Error(`Invalid direction: ${direction} (must be \"ASC\" or \"DESC\")`);\n }\n return { field, direction };\n}\n\nexport function q(s: string | undefined): string {\n return s === undefined ? \"undefined\" : `\"${s}\"`;\n}\n\nexport function uncapitalize(s: string): string {\n return s.charAt(0).toLowerCase() + s.slice(1);\n}\n\nfunction isIgnored(config: Config, t: Table): boolean {\n return (config.ignoredTables || [\"migrations\", \"pgmigrations\"]).includes(t.name) || !shouldIncludeSchema(config, t);\n}\n\n/** Uses the same schema selection for metadata and test database cleanup. */\nexport function shouldIncludeSchema(config: Config, t: Table): boolean {\n return config.schemas ? config.schemas.includes(t.schema.name) : t.schema.name === \"public\";\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utils.js","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import { pascalCase } from \"change-case\";\nimport { isPlainObject } from \"joist-utils\";\nimport pluralize from \"pluralize\";\nimport { code, imp } from \"ts-poet\";\n\nimport { type Config, getTimestampConfig } from \"./config.ts\";\nimport { type DatabaseColumnType, type PrimitiveTypescriptType } from \"./EntityDbMetadata.ts\";\nimport { type Table } from \"./pgMetadata.ts\";\n\nexport function assertNever(x: never): never {\n throw new Error(\"Unexpected object: \" + x);\n}\n\nexport function isEntityTable(config: Config, t: Table): boolean {\n if (isIgnored(config, t) || isJoinTable(config, t)) {\n return false;\n }\n\n // Depending on the config settings, we may/may not require the presence of timestamp\n // fields to determine whether a table is an entity.\n const columnNames = t.columns.map((c) => c.name);\n const { updatedAtConf, createdAtConf } = getTimestampConfig(config);\n const hasCreatedAt = createdAtConf.names.some((c) => columnNames.includes(c));\n const hasUpdatedAt = updatedAtConf.names.some((c) => columnNames.includes(c));\n\n // Entities always require an id column\n const hasIdColumn = columnNames.includes(\"id\");\n if (!hasIdColumn) return false;\n\n // If we have no timestamp columns, but do have `name` and `code`, we're probably an enum.\n if (hasIdColumn && !hasCreatedAt && !hasUpdatedAt) {\n if ([\"name\", \"code\"].every((c) => columnNames.includes(c))) {\n return false;\n }\n }\n\n // If the ID column is a FK then we're a subclass\n if (isSubClassTable(t)) return true;\n\n // Otherwise respect the created_at/updated_at required rules\n return hasIdColumn && (hasCreatedAt || !createdAtConf.required) && (hasUpdatedAt || !updatedAtConf.required);\n}\n\nexport function isSubClassTable(t: Table): boolean {\n // Note that `.get(\"id\")` will blow up if there is no id column\n return t.columns.get(\"id\").foreignKeys.length === 1;\n}\n\nexport function isEnumTable(config: Config, t: Table): boolean {\n if (isIgnored(config, t)) {\n return false;\n }\n const columnNames = t.columns.map((c) => c.name);\n return [\"id\", \"code\", \"name\"].every((c) => columnNames.includes(c)) && !isEntityTable(config, t);\n}\n\n// Oddly enough isJoinTable showed up as a hot spot, so cache its calculation.\nconst joinTables: Map<string, boolean> = new Map();\n\nexport function isJoinTable(config: Config, t: Table): boolean {\n if (isIgnored(config, t)) {\n return false;\n }\n return getOrElse(joinTables, t.name, () => {\n const { columns } = t;\n const fks = columns.filter((c) => c.isForeignKey);\n const pks = columns.filter((c) => c.isPrimaryKey);\n // Every join table is two FKs, plus either a surrogate `id` PK (\"id-ful\") or no surrogate\n // at all, in which case the two FKs are themselves the composite PK (\"id-less\").\n if (fks.length !== 2) return false;\n if (!joinTableHasId(t) && !(pks.length === 2 && pks.every((c) => c.isForeignKey))) return false;\n // Any column beyond the two FKs and the optional `id` PK must be a single created_at.\n const others = columns.length - fks.length - (joinTableHasId(t) ? 1 : 0);\n const createdAts = columns.filter((c) => c.name === \"created_at\" || c.name === \"createdAt\").length;\n return others === 0 || (others === 1 && createdAts === 1);\n });\n}\n\n/** Whether a join table has a surrogate `id` primary key (vs. an id-less FK-pair composite PK). */\nexport function joinTableHasId(t: Table): boolean {\n const pks = t.columns.filter((c) => c.isPrimaryKey);\n return pks.length === 1 && !pks[0].isForeignKey;\n}\n\nfunction getOrElse<K, V>(map: Map<K, V>, key: K, fn: () => V): V {\n let value = map.get(key);\n if (value === undefined) {\n value = fn();\n map.set(key, value);\n }\n return value;\n}\n\n/** Converts `projects` to `Project`. */\nexport function tableToEntityName(config: Config, table: Table): string {\n let entityName = config.__tableToEntityName?.[table.name];\n if (!entityName) {\n const configEntityName = Object.entries(config.entities)\n .filter(([, conf]) => conf.tableName === table.name)\n .map(([entityName]) => entityName)[0];\n entityName = configEntityName || pascalCase(pluralize.singular(table.name));\n (config.__tableToEntityName ??= {})[table.name] = entityName;\n }\n return entityName;\n}\n\nexport const dateCode = code`Date`;\nexport const plainDateCode = code`${imp(\"Temporal@joist-orm\")}.PlainDate`;\nexport const plainTimeCode = code`${imp(\"Temporal@joist-orm\")}.PlainTime`;\nexport const plainDateTimeCode = code`${imp(\"Temporal@joist-orm\")}.PlainDateTime`;\nexport const zonedDateTimeCode = code`${imp(\"Temporal@joist-orm\")}.ZonedDateTime`;\n\n/** Maps db types, i.e. `int`, to JS types, i.e. `number`. */\nexport function mapSimpleDbTypeToTypescriptType(config: Config, dbType: DatabaseColumnType): PrimitiveTypescriptType {\n switch (dbType) {\n case \"boolean\":\n return \"boolean\";\n case \"int\":\n case \"numeric\":\n case \"smallint\":\n case \"integer\":\n case \"decimal\":\n case \"real\":\n case \"smallserial\":\n case \"serial\":\n case \"double precision\":\n return \"number\";\n case \"bigserial\":\n case \"bigint\":\n return \"bigint\";\n case \"text\":\n case \"citext\":\n case \"character varying\":\n case \"varchar\":\n case \"uuid\":\n case \"tsvector\":\n case \"tstzrange\":\n return \"string\";\n case \"time without time zone\":\n return config.temporal\n ? plainTimeCode\n : fail(\"Joist doesn't support 'time without time zone' unless temporal is enabled\");\n case \"timestamp with time zone\":\n return config.temporal ? zonedDateTimeCode : dateCode;\n case \"timestamp without time zone\":\n return config.temporal ? plainDateTimeCode : dateCode;\n case \"date\":\n return config.temporal ? plainDateCode : dateCode;\n case \"jsonb\":\n return \"Object\";\n case \"bytea\":\n return \"Uint8Array\";\n case \"vector\":\n // pgvector columns are a single value (not a physical pg array), so `isArray` stays false\n return \"number[]\";\n default:\n assertNever(dbType);\n }\n}\n\nexport function merge<T>(a: T[], b: T[]): T[] {\n return [...a, ...b];\n}\n\n/** Returns true if `p` is resolved, otherwise false if it is rejected. */\nexport async function trueIfResolved(p: Promise<unknown>): Promise<boolean> {\n return p.then(\n () => true,\n () => false,\n );\n}\n\nexport function fail(message?: string): never {\n throw new Error(message || \"Failed\");\n}\n\nexport function sortKeys<T extends object>(o: T): T {\n return Object.keys(o)\n .sort()\n .reduce(\n (acc, key) => {\n const value = o[key as keyof T];\n const newValue = typeof value === \"object\" && isPlainObject(value) ? sortKeys(value as any as object) : value;\n acc[key as keyof T] = newValue as any;\n return acc;\n },\n {} as any as T,\n );\n}\n\nexport function parseOrder(order: string | undefined): { field: string; direction: \"ASC\" | \"DESC\" } | undefined {\n if (!order) {\n return undefined;\n }\n const [field, direction = \"ASC\"] = order.split(\" \");\n if (direction !== \"ASC\" && direction !== \"DESC\") {\n throw new Error(`Invalid direction: ${direction} (must be \"ASC\" or \"DESC\")`);\n }\n return { field, direction };\n}\n\nexport function q(s: string | undefined): string {\n return s === undefined ? \"undefined\" : `\"${s}\"`;\n}\n\nexport function uncapitalize(s: string): string {\n return s.charAt(0).toLowerCase() + s.slice(1);\n}\n\nfunction isIgnored(config: Config, t: Table): boolean {\n return (config.ignoredTables || [\"migrations\", \"pgmigrations\"]).includes(t.name) || !shouldIncludeSchema(config, t);\n}\n\n/** Uses the same schema selection for metadata and test database cleanup. */\nexport function shouldIncludeSchema(config: Config, t: Table): boolean {\n return config.schemas ? config.schemas.includes(t.schema.name) : t.schema.name === \"public\";\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "joist-codegen",
|
|
3
|
-
"version": "2.4.0-next.
|
|
3
|
+
"version": "2.4.0-next.50",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -48,32 +48,32 @@
|
|
|
48
48
|
"skills"
|
|
49
49
|
],
|
|
50
50
|
"peerDependencies": {
|
|
51
|
-
"joist-utils": "2.4.0-next.
|
|
51
|
+
"joist-utils": "2.4.0-next.50",
|
|
52
52
|
"knex": "^3.1.0",
|
|
53
53
|
"pg": "^8.23.0"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@dprint/formatter": "^0.
|
|
57
|
-
"@dprint/json": "^0.
|
|
58
|
-
"@inquirer/prompts": "^8.
|
|
56
|
+
"@dprint/formatter": "^0.6.0",
|
|
57
|
+
"@dprint/json": "^0.25.2",
|
|
58
|
+
"@inquirer/prompts": "^8.7.3",
|
|
59
59
|
"@types/jscodeshift": "^17.3.0",
|
|
60
60
|
"@types/pluralize": "^0.0.33",
|
|
61
|
-
"change-case": "^4.
|
|
61
|
+
"change-case": "^5.4.4",
|
|
62
62
|
"fast-glob": "^3.3.3",
|
|
63
63
|
"jscodeshift": "^17.4.0",
|
|
64
64
|
"jsonc-parser": "^3.3.1",
|
|
65
65
|
"pluralize": "^8.0.0",
|
|
66
|
-
"prettier": "^3.9.
|
|
66
|
+
"prettier": "^3.9.10",
|
|
67
67
|
"ts-poet": "^6.12.0",
|
|
68
|
-
"zod": "^4.
|
|
68
|
+
"zod": "^4.6.7"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@swc/jest": "^0.2.39",
|
|
72
72
|
"@types/jest": "^30.0.0",
|
|
73
|
-
"@types/node": "^26.
|
|
73
|
+
"@types/node": "^26.6.5",
|
|
74
74
|
"jest": "30.4.2",
|
|
75
75
|
"tsconfig-paths": "^4.2.0",
|
|
76
|
-
"tsx": "^4.23.
|
|
76
|
+
"tsx": "^4.23.15",
|
|
77
77
|
"typescript": "7.0.2"
|
|
78
78
|
}
|
|
79
79
|
}
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: joist-test-factories
|
|
3
|
-
description: Use when writing or refactoring Joist ORM tests with newTestInstance factories, DeepNew,
|
|
3
|
+
description: Use when writing or refactoring Joist ORM entity or API-layer tests with newTestInstance factories, DeepNew, toMatchEntity, and nested Given graphs, or deciding whether EntityManager isolation with run, makeRun, or RunPlugin is needed.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Joist Test Factories
|
|
7
7
|
|
|
8
|
-
Write
|
|
8
|
+
Write focused, succinct tests that use Joist's factories for setup, retain
|
|
9
9
|
typed entity references through the action, and assert those same entities
|
|
10
10
|
with `toMatchEntity`.
|
|
11
11
|
|
|
12
|
+
Entity tests normally use one `EntityManager` for Given, When, and Then.
|
|
13
|
+
Use `run` for API-layer tests and other production boundaries that need a
|
|
14
|
+
separate `EntityManager`, not as a default wrapper around every test action.
|
|
15
|
+
|
|
12
16
|
Authoritative references:
|
|
13
17
|
|
|
14
18
|
- <https://joist-orm.io/testing/test-factories/>
|
|
@@ -27,10 +31,16 @@ Authoritative references:
|
|
|
27
31
|
4. Keep using the factory-created `DeepNew` graph after same-`EntityManager`
|
|
28
32
|
actions or actions run through Joist's test `run` helper. Do not reload the
|
|
29
33
|
same rows merely to assert against them.
|
|
30
|
-
5.
|
|
34
|
+
5. Keep entity tests in the original test `EntityManager`; they normally do not
|
|
35
|
+
need EM isolation or `RunPlugin`. Use `run` or the project's `makeRun` wrapper
|
|
36
|
+
for API/request-layer tests or another production boundary that needs an
|
|
31
37
|
isolated `EntityManager`; it flushes Given state and mirrors the callback's
|
|
32
38
|
flushed Joist writes into the original test graph.
|
|
33
|
-
|
|
39
|
+
Do not `await em.flush()` right before `run` or a `makeRun` helper: it
|
|
40
|
+
already flushes the Given graph, use as few `em.flush()` calls as possible.
|
|
41
|
+
6. Assert entity state and relationships with `toMatchEntity`. Prefer checking
|
|
42
|
+
side effects through retained entities and their relations instead of using
|
|
43
|
+
`em.getEntities` to discover what the action created or changed.
|
|
34
44
|
7. Prefer focused tests for one behavior over a single scenario that exercises
|
|
35
45
|
unrelated updates at several graph levels.
|
|
36
46
|
|
|
@@ -41,6 +51,23 @@ happens, Then the state of the world is Z": the factory-created graph is the
|
|
|
41
51
|
Given, the code under test is the When, and `toMatchEntity` proves the Then.
|
|
42
52
|
Mark the three phases with `// Given`, `// When`, `// Then` comments:
|
|
43
53
|
|
|
54
|
+
For an entity test, act directly on the factory-created entity:
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
it.withCtx("updates a book's title", async (ctx) => {
|
|
58
|
+
// Given a book with its original title
|
|
59
|
+
const book = newBook(ctx.em, { title: "Before" });
|
|
60
|
+
|
|
61
|
+
// When we change the book's title
|
|
62
|
+
book.title = "After";
|
|
63
|
+
|
|
64
|
+
// Then the book has the new title
|
|
65
|
+
expect(book).toMatchEntity({ title: "After" });
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
For an API-layer test, use `run` to model its separate production unit of work:
|
|
70
|
+
|
|
44
71
|
```ts
|
|
45
72
|
it.withCtx("updates a book", async (ctx) => {
|
|
46
73
|
// Given an author with one book
|
|
@@ -241,6 +268,23 @@ test-only loads.
|
|
|
241
268
|
|
|
242
269
|
## Use run for Production Isolation
|
|
243
270
|
|
|
271
|
+
Choose isolation based on the behavior under test:
|
|
272
|
+
|
|
273
|
+
- **Entity tests:** Test entity methods, properties, relationships, and domain
|
|
274
|
+
logic directly with the test's `ctx.em` and factory-created entities. These
|
|
275
|
+
normally do not need `run`, a second EM, or a manually installed `RunPlugin`.
|
|
276
|
+
Flush only when the behavior requires it, such as validation, flush hooks,
|
|
277
|
+
persisted reactive fields, or database constraints. Needing a flush does not
|
|
278
|
+
by itself mean the test needs EM isolation.
|
|
279
|
+
- **API/request-layer tests:** Use `run` or an existing project wrapper such as
|
|
280
|
+
`runMutation` when testing a resolver, endpoint, or service entry point whose
|
|
281
|
+
production unit of work uses a fresh EM. This ensures the action loads its
|
|
282
|
+
own entities rather than inheriting the test's loaded factory graph.
|
|
283
|
+
- **Other boundaries:** Use `run` when a fresh production unit of work is part
|
|
284
|
+
of the behavior being tested. A service/helper that operates on existing
|
|
285
|
+
entities or the caller's EM does not need isolation merely because it is
|
|
286
|
+
production code.
|
|
287
|
+
|
|
244
288
|
Joist's `run(ctx, fn)` executes `fn` with a fresh production-style context and
|
|
245
289
|
`EntityManager`. Before the callback, it flushes the test factory graph. As the
|
|
246
290
|
callback flushes Joist writes, `RunPlugin` mirrors those writes into the
|
|
@@ -248,6 +292,11 @@ original test `EntityManager`. It does not call `EntityManager.refresh`. The
|
|
|
248
292
|
callback result is also mapped back to entities from the original test
|
|
249
293
|
`EntityManager`.
|
|
250
294
|
|
|
295
|
+
`run` installs `RunPlugin` automatically on the isolated EM. The plugin bridges
|
|
296
|
+
that production unit of work back to the retained test entities; it is not
|
|
297
|
+
needed when Given, When, and Then already share one EM. Prefer `run` or the
|
|
298
|
+
project's wrapper over manually wiring the plugin.
|
|
299
|
+
|
|
251
300
|
```ts
|
|
252
301
|
const author = newAuthor(ctx.em, { books: [{ title: "Before" }] });
|
|
253
302
|
const [book] = author.books.get;
|
|
@@ -278,8 +327,9 @@ const books = await savedBook.author.load().then((author) => author.books.load()
|
|
|
278
327
|
Keep using `author` and `book`. They are the stable test references.
|
|
279
328
|
|
|
280
329
|
Call `em.flush()` directly only when the test intentionally needs a persistence
|
|
281
|
-
boundary and its helper does not provide one.
|
|
282
|
-
|
|
330
|
+
boundary and its helper does not provide one, e.g. to persist one Given state
|
|
331
|
+
before changing it into the next one. Pure entity tests should usually avoid
|
|
332
|
+
unnecessary flushes.
|
|
283
333
|
|
|
284
334
|
## Register toMatchEntity
|
|
285
335
|
|
|
@@ -338,6 +388,39 @@ expect((await author.books.load()).map((book) => ({ id: book.id, title: book.tit
|
|
|
338
388
|
]);
|
|
339
389
|
```
|
|
340
390
|
|
|
391
|
+
## Assert Side Effects Through the Domain Graph
|
|
392
|
+
|
|
393
|
+
Avoid `em.getEntities(Entity).filter(...)` or `.find(...)` to look up side
|
|
394
|
+
effects for assertions. `getEntities` inspects the `EntityManager`'s tracked
|
|
395
|
+
entities; finding a new child there does not prove that the action attached it
|
|
396
|
+
to the correct parent. Assert through the retained Given graph instead, so the
|
|
397
|
+
test describes the resulting domain state and checks relationship membership.
|
|
398
|
+
|
|
399
|
+
```ts
|
|
400
|
+
// Less useful: finds a book without proving which author owns it.
|
|
401
|
+
const [createdBook] = ctx.em.getEntities(Book).filter((book) => book.title === "New book");
|
|
402
|
+
expect(createdBook).toMatchEntity({ title: "New book" });
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
```ts
|
|
406
|
+
it.withCtx("adds a book to the existing author", async (ctx) => {
|
|
407
|
+
// Given an author with an existing book
|
|
408
|
+
const author = newAuthor(ctx.em, { books: [{}] });
|
|
409
|
+
const [existingBook] = author.books.get;
|
|
410
|
+
|
|
411
|
+
// When we add another book to that author
|
|
412
|
+
await run(ctx, (ctx) => addBook(ctx, { authorId: author.id, title: "New book" }));
|
|
413
|
+
|
|
414
|
+
// Then the author keeps the existing book and owns the new book
|
|
415
|
+
expect(author).toMatchEntity({ books: [existingBook, { title: "New book" }] });
|
|
416
|
+
});
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
Use the action result when a new entity has no natural path from the Given
|
|
420
|
+
graph. If neither a relation nor the result exposes it, use an intentional
|
|
421
|
+
domain query. Reserve `getEntities` assertions for tests whose behavior under
|
|
422
|
+
test is specifically which entities the `EntityManager` tracks.
|
|
423
|
+
|
|
341
424
|
## Keep Tests Focused
|
|
342
425
|
|
|
343
426
|
One test should describe one coherent boundary. Split a large graph mutation
|
|
@@ -390,8 +473,12 @@ reuse decisions instead of replacing factories with manual setup.
|
|
|
390
473
|
- Given state uses minimal factory opts and does not invoke the behavior under
|
|
391
474
|
test.
|
|
392
475
|
- Important entities have direct, role-based `const` names.
|
|
476
|
+
- Entity tests use the original test EM unless the behavior specifically needs
|
|
477
|
+
a separate production unit of work; a flush alone does not require `run`.
|
|
393
478
|
- Separate production units of work use `run`/`makeRun` and flush normally.
|
|
394
479
|
- Assertions reuse loaded factory entities with `toMatchEntity`.
|
|
480
|
+
- Side-effect assertions follow domain relations or action results instead of
|
|
481
|
+
scanning `em.getEntities` for created or changed entities.
|
|
395
482
|
- No unnecessary reloads, `load()` calls, assertion awaits, or direct flushes
|
|
396
483
|
remain.
|
|
397
484
|
- Each test covers one coherent boundary.
|