joist-codegen 2.3.0 → 2.4.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/EntityDbMetadata.cjs +672 -0
- package/build/EntityDbMetadata.cjs.map +1 -0
- package/build/EntityDbMetadata.d.cts +301 -0
- package/build/EntityDbMetadata.d.cts.map +1 -0
- package/build/EntityDbMetadata.d.mts +301 -0
- package/build/EntityDbMetadata.d.mts.map +1 -0
- package/build/EntityDbMetadata.js +550 -662
- package/build/EntityDbMetadata.js.map +1 -1
- package/build/_virtual/_rolldown/runtime.cjs +23 -0
- package/build/_virtual/_rolldown/runtime.js +5 -0
- package/build/assignTags.cjs +45 -0
- package/build/assignTags.cjs.map +1 -0
- package/build/{assignTags.d.ts → assignTags.d.cts} +8 -4
- package/build/assignTags.d.cts.map +1 -0
- package/build/assignTags.d.mts +16 -0
- package/build/assignTags.d.mts.map +1 -0
- package/build/assignTags.js +37 -59
- package/build/assignTags.js.map +1 -1
- package/build/codemods/Codemod.cjs +2 -0
- package/build/codemods/Codemod.d.cts +17 -0
- package/build/codemods/Codemod.d.cts.map +1 -0
- package/build/codemods/Codemod.d.mts +17 -0
- package/build/codemods/Codemod.d.mts.map +1 -0
- package/build/codemods/Codemod.js +2 -3
- package/build/codemods/JscodeshiftMod.cjs +42 -0
- package/build/codemods/JscodeshiftMod.cjs.map +1 -0
- package/build/codemods/JscodeshiftMod.d.cts +14 -0
- package/build/codemods/JscodeshiftMod.d.cts.map +1 -0
- package/build/codemods/JscodeshiftMod.d.mts +14 -0
- package/build/codemods/JscodeshiftMod.d.mts.map +1 -0
- package/build/codemods/JscodeshiftMod.js +33 -33
- package/build/codemods/JscodeshiftMod.js.map +1 -1
- package/build/codemods/codemod_0001-rename_has_async_property.cjs +30 -0
- package/build/codemods/codemod_0001-rename_has_async_property.cjs.map +1 -0
- package/build/codemods/codemod_0001-rename_has_async_property.d.cts +9 -0
- package/build/codemods/codemod_0001-rename_has_async_property.d.cts.map +1 -0
- package/build/codemods/codemod_0001-rename_has_async_property.d.mts +9 -0
- package/build/codemods/codemod_0001-rename_has_async_property.d.mts.map +1 -0
- package/build/codemods/codemod_0001-rename_has_async_property.js +21 -25
- package/build/codemods/codemod_0001-rename_has_async_property.js.map +1 -1
- package/build/codemods/codemod_0002-rename_async_query_fields.cjs +50 -0
- package/build/codemods/codemod_0002-rename_async_query_fields.cjs.map +1 -0
- package/build/codemods/codemod_0002-rename_async_query_fields.d.cts +9 -0
- package/build/codemods/codemod_0002-rename_async_query_fields.d.cts.map +1 -0
- package/build/codemods/codemod_0002-rename_async_query_fields.d.mts +9 -0
- package/build/codemods/codemod_0002-rename_async_query_fields.d.mts.map +1 -0
- package/build/codemods/codemod_0002-rename_async_query_fields.js +38 -52
- package/build/codemods/codemod_0002-rename_async_query_fields.js.map +1 -1
- package/build/codemods/codemod_0003-rename_find_paginated.cjs +25 -0
- package/build/codemods/codemod_0003-rename_find_paginated.cjs.map +1 -0
- package/build/codemods/codemod_0003-rename_find_paginated.d.cts +9 -0
- package/build/codemods/codemod_0003-rename_find_paginated.d.cts.map +1 -0
- package/build/codemods/codemod_0003-rename_find_paginated.d.mts +9 -0
- package/build/codemods/codemod_0003-rename_find_paginated.d.mts.map +1 -0
- package/build/codemods/codemod_0003-rename_find_paginated.js +17 -26
- package/build/codemods/codemod_0003-rename_find_paginated.js.map +1 -1
- package/build/codemods/index.cjs +49 -0
- package/build/codemods/index.cjs.map +1 -0
- package/build/codemods/index.d.cts +12 -0
- package/build/codemods/index.d.cts.map +1 -0
- package/build/codemods/index.d.mts +12 -0
- package/build/codemods/index.d.mts.map +1 -0
- package/build/codemods/index.js +34 -42
- package/build/codemods/index.js.map +1 -1
- package/build/config.cjs +377 -0
- package/build/config.cjs.map +1 -0
- package/build/config.d.cts +181 -0
- package/build/config.d.cts.map +1 -0
- package/build/config.d.mts +181 -0
- package/build/config.d.mts.map +1 -0
- package/build/config.js +309 -347
- package/build/config.js.map +1 -1
- package/build/docs/cache.cjs +62 -0
- package/build/docs/cache.cjs.map +1 -0
- package/build/docs/cache.d.cts +17 -0
- package/build/docs/cache.d.cts.map +1 -0
- package/build/docs/cache.d.mts +17 -0
- package/build/docs/cache.d.mts.map +1 -0
- package/build/docs/cache.js +52 -53
- package/build/docs/cache.js.map +1 -1
- package/build/docs/generate-metadata-docs.cjs +32 -0
- package/build/docs/generate-metadata-docs.cjs.map +1 -0
- package/build/docs/generate-metadata-docs.d.cts +9 -0
- package/build/docs/generate-metadata-docs.d.cts.map +1 -0
- package/build/docs/generate-metadata-docs.d.mts +9 -0
- package/build/docs/generate-metadata-docs.d.mts.map +1 -0
- package/build/docs/generate-metadata-docs.js +19 -24
- package/build/docs/generate-metadata-docs.js.map +1 -1
- package/build/docs/index.cjs +90 -0
- package/build/docs/index.cjs.map +1 -0
- package/build/docs/index.d.cts +16 -0
- package/build/docs/index.d.cts.map +1 -0
- package/build/docs/index.d.mts +16 -0
- package/build/docs/index.d.mts.map +1 -0
- package/build/docs/index.js +75 -80
- package/build/docs/index.js.map +1 -1
- package/build/docs/markdown.cjs +181 -0
- package/build/docs/markdown.cjs.map +1 -0
- package/build/docs/{markdown.d.ts → markdown.d.cts} +14 -12
- package/build/docs/markdown.d.cts.map +1 -0
- package/build/docs/markdown.d.mts +32 -0
- package/build/docs/markdown.d.mts.map +1 -0
- package/build/docs/markdown.js +152 -220
- package/build/docs/markdown.js.map +1 -1
- package/build/docs/parsing.cjs +117 -0
- package/build/docs/parsing.cjs.map +1 -0
- package/build/docs/parsing.d.cts +48 -0
- package/build/docs/parsing.d.cts.map +1 -0
- package/build/docs/parsing.d.mts +48 -0
- package/build/docs/parsing.d.mts.map +1 -0
- package/build/docs/parsing.js +89 -88
- package/build/docs/parsing.js.map +1 -1
- package/build/findEntityScopes.cjs +119 -0
- package/build/findEntityScopes.cjs.map +1 -0
- package/build/findEntityScopes.d.cts +14 -0
- package/build/findEntityScopes.d.cts.map +1 -0
- package/build/findEntityScopes.d.mts +14 -0
- package/build/findEntityScopes.d.mts.map +1 -0
- package/build/findEntityScopes.js +83 -111
- package/build/findEntityScopes.js.map +1 -1
- package/build/foreignKeyOrdering.cjs +52 -0
- package/build/foreignKeyOrdering.cjs.map +1 -0
- package/build/foreignKeyOrdering.d.cts +8 -0
- package/build/foreignKeyOrdering.d.cts.map +1 -0
- package/build/foreignKeyOrdering.d.mts +8 -0
- package/build/foreignKeyOrdering.d.mts.map +1 -0
- package/build/foreignKeyOrdering.js +46 -55
- package/build/foreignKeyOrdering.js.map +1 -1
- package/build/generate.cjs +128 -0
- package/build/generate.cjs.map +1 -0
- package/build/generate.d.cts +17 -0
- package/build/generate.d.cts.map +1 -0
- package/build/generate.d.mts +17 -0
- package/build/generate.d.mts.map +1 -0
- package/build/generate.js +111 -124
- package/build/generate.js.map +1 -1
- package/build/generateEntitiesFile.cjs +46 -0
- package/build/generateEntitiesFile.cjs.map +1 -0
- package/build/generateEntitiesFile.d.cts +11 -0
- package/build/generateEntitiesFile.d.cts.map +1 -0
- package/build/generateEntitiesFile.d.mts +11 -0
- package/build/generateEntitiesFile.d.mts.map +1 -0
- package/build/generateEntitiesFile.js +28 -25
- package/build/generateEntitiesFile.js.map +1 -1
- package/build/generateEntityCodegenFile.cjs +1011 -0
- package/build/generateEntityCodegenFile.cjs.map +1 -0
- package/build/generateEntityCodegenFile.d.cts +16 -0
- package/build/generateEntityCodegenFile.d.cts.map +1 -0
- package/build/generateEntityCodegenFile.d.mts +16 -0
- package/build/generateEntityCodegenFile.d.mts.map +1 -0
- package/build/generateEntityCodegenFile.js +794 -827
- package/build/generateEntityCodegenFile.js.map +1 -1
- package/build/generateEntityFile.cjs +23 -0
- package/build/generateEntityFile.cjs.map +1 -0
- package/build/generateEntityFile.d.cts +9 -0
- package/build/generateEntityFile.d.cts.map +1 -0
- package/build/generateEntityFile.d.mts +9 -0
- package/build/generateEntityFile.d.mts.map +1 -0
- package/build/generateEntityFile.js +11 -8
- package/build/generateEntityFile.js.map +1 -1
- package/build/generateEntityTestFile.cjs +25 -0
- package/build/generateEntityTestFile.cjs.map +1 -0
- package/build/generateEntityTestFile.d.cts +9 -0
- package/build/generateEntityTestFile.d.cts.map +1 -0
- package/build/generateEntityTestFile.d.mts +9 -0
- package/build/generateEntityTestFile.d.mts.map +1 -0
- package/build/generateEntityTestFile.js +10 -7
- package/build/generateEntityTestFile.js.map +1 -1
- package/build/generateEnumFile.cjs +73 -0
- package/build/generateEnumFile.cjs.map +1 -0
- package/build/generateEnumFile.d.cts +9 -0
- package/build/generateEnumFile.d.cts.map +1 -0
- package/build/generateEnumFile.d.mts +9 -0
- package/build/generateEnumFile.d.mts.map +1 -0
- package/build/generateEnumFile.js +33 -43
- package/build/generateEnumFile.js.map +1 -1
- package/build/generateFactoriesFiles.cjs +28 -0
- package/build/generateFactoriesFiles.cjs.map +1 -0
- package/build/generateFactoriesFiles.d.cts +7 -0
- package/build/generateFactoriesFiles.d.cts.map +1 -0
- package/build/generateFactoriesFiles.d.mts +7 -0
- package/build/generateFactoriesFiles.d.mts.map +1 -0
- package/build/generateFactoriesFiles.js +21 -16
- package/build/generateFactoriesFiles.js.map +1 -1
- package/build/generateFlushFunction.cjs +61 -0
- package/build/generateFlushFunction.cjs.map +1 -0
- package/build/{generateFlushFunction.d.ts → generateFlushFunction.d.cts} +8 -5
- package/build/generateFlushFunction.d.cts.map +1 -0
- package/build/generateFlushFunction.d.mts +23 -0
- package/build/generateFlushFunction.d.mts.map +1 -0
- package/build/generateFlushFunction.js +32 -78
- package/build/generateFlushFunction.js.map +1 -1
- package/build/generateMetadataFile.cjs +315 -0
- package/build/generateMetadataFile.cjs.map +1 -0
- package/build/generateMetadataFile.d.cts +10 -0
- package/build/generateMetadataFile.d.cts.map +1 -0
- package/build/generateMetadataFile.d.mts +10 -0
- package/build/generateMetadataFile.d.mts.map +1 -0
- package/build/generateMetadataFile.js +156 -156
- package/build/generateMetadataFile.js.map +1 -1
- package/build/generatePgEnumFile.cjs +21 -0
- package/build/generatePgEnumFile.cjs.map +1 -0
- package/build/generatePgEnumFile.d.cts +9 -0
- package/build/generatePgEnumFile.d.cts.map +1 -0
- package/build/generatePgEnumFile.d.mts +9 -0
- package/build/generatePgEnumFile.d.mts.map +1 -0
- package/build/generatePgEnumFile.js +12 -9
- package/build/generatePgEnumFile.js.map +1 -1
- package/build/index.cjs +135 -0
- package/build/index.cjs.map +1 -0
- package/build/index.d.cts +12 -0
- package/build/index.d.cts.map +1 -0
- package/build/index.d.mts +12 -0
- package/build/index.d.mts.map +1 -0
- package/build/index.js +109 -127
- package/build/index.js.map +1 -1
- package/build/inheritance.cjs +258 -0
- package/build/inheritance.cjs.map +1 -0
- package/build/inheritance.d.cts +13 -0
- package/build/inheritance.d.cts.map +1 -0
- package/build/inheritance.d.mts +13 -0
- package/build/inheritance.d.mts.map +1 -0
- package/build/inheritance.js +238 -247
- package/build/inheritance.js.map +1 -1
- package/build/installSkills.cjs +68 -0
- package/build/installSkills.cjs.map +1 -0
- package/build/installSkills.d.cts +16 -0
- package/build/installSkills.d.cts.map +1 -0
- package/build/installSkills.d.mts +16 -0
- package/build/installSkills.d.mts.map +1 -0
- package/build/installSkills.js +67 -0
- package/build/installSkills.js.map +1 -0
- package/build/keywords.cjs +7 -0
- package/build/keywords.cjs.map +1 -0
- package/build/keywords.d.cts +5 -0
- package/build/keywords.d.cts.map +1 -0
- package/build/keywords.d.mts +5 -0
- package/build/keywords.d.mts.map +1 -0
- package/build/keywords.js +5 -4
- package/build/keywords.js.map +1 -1
- package/build/loadMetadata.cjs +39 -0
- package/build/loadMetadata.cjs.map +1 -0
- package/build/loadMetadata.d.cts +31 -0
- package/build/loadMetadata.d.cts.map +1 -0
- package/build/loadMetadata.d.mts +31 -0
- package/build/loadMetadata.d.mts.map +1 -0
- package/build/loadMetadata.js +32 -39
- package/build/loadMetadata.js.map +1 -1
- package/build/logger.cjs +28 -0
- package/build/logger.cjs.map +1 -0
- package/build/logger.d.cts +13 -0
- package/build/logger.d.cts.map +1 -0
- package/build/logger.d.mts +13 -0
- package/build/logger.d.mts.map +1 -0
- package/build/logger.js +17 -16
- package/build/logger.js.map +1 -1
- package/build/pgMetadata.cjs +332 -0
- package/build/pgMetadata.cjs.map +1 -0
- package/build/pgMetadata.d.cts +128 -0
- package/build/pgMetadata.d.cts.map +1 -0
- package/build/pgMetadata.d.mts +128 -0
- package/build/pgMetadata.d.mts.map +1 -0
- package/build/pgMetadata.js +320 -0
- package/build/pgMetadata.js.map +1 -0
- package/build/scanEntityFiles.cjs +46 -0
- package/build/scanEntityFiles.cjs.map +1 -0
- package/build/scanEntityFiles.d.cts +8 -0
- package/build/scanEntityFiles.d.cts.map +1 -0
- package/build/scanEntityFiles.d.mts +8 -0
- package/build/scanEntityFiles.d.mts.map +1 -0
- package/build/scanEntityFiles.js +37 -42
- package/build/scanEntityFiles.js.map +1 -1
- package/build/sortForeignKeys.cjs +99 -0
- package/build/sortForeignKeys.cjs.map +1 -0
- package/build/{sortForeignKeys.d.ts → sortForeignKeys.d.cts} +8 -5
- package/build/sortForeignKeys.d.cts.map +1 -0
- package/build/sortForeignKeys.d.mts +35 -0
- package/build/sortForeignKeys.d.mts.map +1 -0
- package/build/sortForeignKeys.js +88 -117
- package/build/sortForeignKeys.js.map +1 -1
- package/build/symbols.cjs +238 -0
- package/build/symbols.cjs.map +1 -0
- package/build/symbols.d.cts +120 -0
- package/build/symbols.d.cts.map +1 -0
- package/build/symbols.d.mts +120 -0
- package/build/symbols.d.mts.map +1 -0
- package/build/symbols.js +121 -113
- package/build/symbols.js.map +1 -1
- package/build/tsdoc.cjs +22 -0
- package/build/tsdoc.cjs.map +1 -0
- package/build/tsdoc.d.cts +15 -0
- package/build/tsdoc.d.cts.map +1 -0
- package/build/tsdoc.d.mts +15 -0
- package/build/tsdoc.d.mts.map +1 -0
- package/build/tsdoc.js +18 -15
- package/build/tsdoc.js.map +1 -1
- package/build/utils.cjs +175 -0
- package/build/utils.cjs.map +1 -0
- package/build/utils.d.cts +36 -0
- package/build/utils.d.cts.map +1 -0
- package/build/utils.d.mts +36 -0
- package/build/utils.d.mts.map +1 -0
- package/build/utils.js +113 -166
- package/build/utils.js.map +1 -1
- package/build/write-json-schema.cjs +23 -0
- package/build/write-json-schema.cjs.map +1 -0
- package/build/write-json-schema.d.cts +1 -0
- package/build/write-json-schema.d.mts +1 -0
- package/build/write-json-schema.js +19 -13
- package/build/write-json-schema.js.map +1 -1
- package/package.json +47 -18
- package/skills/joist-docs/SKILL.md +142 -0
- package/skills/joist-em-basics/SKILL.md +114 -0
- package/skills/joist-em-execute/SKILL.md +35 -0
- package/skills/joist-em-find/SKILL.md +27 -0
- package/skills/joist-em-query/SKILL.md +32 -0
- package/skills/joist-partial-updates/SKILL.md +352 -0
- package/skills/joist-reactive-hints/SKILL.md +150 -0
- package/skills/joist-test-factories/SKILL.md +397 -0
- package/skills/joist-upsert/SKILL.md +95 -0
- package/build/EntityDbMetadata.d.ts +0 -269
- package/build/EntityDbMetadata.d.ts.map +0 -1
- package/build/EntityDbMetadata.test.d.ts +0 -2
- package/build/EntityDbMetadata.test.d.ts.map +0 -1
- package/build/EntityDbMetadata.test.js +0 -211
- package/build/EntityDbMetadata.test.js.map +0 -1
- package/build/assignTags.d.ts.map +0 -1
- package/build/codemods/Codemod.d.ts +0 -14
- package/build/codemods/Codemod.d.ts.map +0 -1
- package/build/codemods/Codemod.js.map +0 -1
- package/build/codemods/JscodeshiftMod.d.ts +0 -11
- package/build/codemods/JscodeshiftMod.d.ts.map +0 -1
- package/build/codemods/__tests__/codemod_0001-rename_has_async_property.test.d.ts +0 -2
- package/build/codemods/__tests__/codemod_0001-rename_has_async_property.test.d.ts.map +0 -1
- package/build/codemods/__tests__/codemod_0001-rename_has_async_property.test.js +0 -9
- package/build/codemods/__tests__/codemod_0001-rename_has_async_property.test.js.map +0 -1
- package/build/codemods/__tests__/codemod_0002-rename_async_query_fields.test.d.ts +0 -2
- package/build/codemods/__tests__/codemod_0002-rename_async_query_fields.test.d.ts.map +0 -1
- package/build/codemods/__tests__/codemod_0002-rename_async_query_fields.test.js +0 -9
- package/build/codemods/__tests__/codemod_0002-rename_async_query_fields.test.js.map +0 -1
- package/build/codemods/__tests__/codemod_0003-rename_find_paginated.test.d.ts +0 -2
- package/build/codemods/__tests__/codemod_0003-rename_find_paginated.test.d.ts.map +0 -1
- package/build/codemods/__tests__/codemod_0003-rename_find_paginated.test.js +0 -9
- package/build/codemods/__tests__/codemod_0003-rename_find_paginated.test.js.map +0 -1
- package/build/codemods/codemod_0001-rename_has_async_property.d.ts +0 -7
- package/build/codemods/codemod_0001-rename_has_async_property.d.ts.map +0 -1
- package/build/codemods/codemod_0002-rename_async_query_fields.d.ts +0 -7
- package/build/codemods/codemod_0002-rename_async_query_fields.d.ts.map +0 -1
- package/build/codemods/codemod_0003-rename_find_paginated.d.ts +0 -7
- package/build/codemods/codemod_0003-rename_find_paginated.d.ts.map +0 -1
- package/build/codemods/index.d.ts +0 -9
- package/build/codemods/index.d.ts.map +0 -1
- package/build/codemods/index.test.d.ts +0 -2
- package/build/codemods/index.test.d.ts.map +0 -1
- package/build/codemods/index.test.js +0 -24
- package/build/codemods/index.test.js.map +0 -1
- package/build/config.d.ts +0 -167
- package/build/config.d.ts.map +0 -1
- package/build/config.test.d.ts +0 -2
- package/build/config.test.d.ts.map +0 -1
- package/build/config.test.js +0 -78
- package/build/config.test.js.map +0 -1
- package/build/docs/cache.d.ts +0 -14
- package/build/docs/cache.d.ts.map +0 -1
- package/build/docs/cache.test.d.ts +0 -2
- package/build/docs/cache.test.d.ts.map +0 -1
- package/build/docs/cache.test.js +0 -47
- package/build/docs/cache.test.js.map +0 -1
- package/build/docs/generate-metadata-docs.d.ts +0 -6
- package/build/docs/generate-metadata-docs.d.ts.map +0 -1
- package/build/docs/index.d.ts +0 -9
- package/build/docs/index.d.ts.map +0 -1
- package/build/docs/index.test.d.ts +0 -2
- package/build/docs/index.test.d.ts.map +0 -1
- package/build/docs/index.test.js +0 -100
- package/build/docs/index.test.js.map +0 -1
- package/build/docs/markdown.d.ts.map +0 -1
- package/build/docs/markdown.test.d.ts +0 -2
- package/build/docs/markdown.test.d.ts.map +0 -1
- package/build/docs/markdown.test.js +0 -280
- package/build/docs/markdown.test.js.map +0 -1
- package/build/docs/parsing.d.ts +0 -42
- package/build/docs/parsing.d.ts.map +0 -1
- package/build/docs/parsing.test.d.ts +0 -2
- package/build/docs/parsing.test.d.ts.map +0 -1
- package/build/docs/parsing.test.js +0 -190
- package/build/docs/parsing.test.js.map +0 -1
- package/build/findEntityScopes.d.ts +0 -11
- package/build/findEntityScopes.d.ts.map +0 -1
- package/build/foreignKeyOrdering.d.ts +0 -3
- package/build/foreignKeyOrdering.d.ts.map +0 -1
- package/build/generate.d.ts +0 -12
- package/build/generate.d.ts.map +0 -1
- package/build/generateEntitiesFile.d.ts +0 -7
- package/build/generateEntitiesFile.d.ts.map +0 -1
- package/build/generateEntityCodegenFile.d.ts +0 -11
- package/build/generateEntityCodegenFile.d.ts.map +0 -1
- package/build/generateEntityFile.d.ts +0 -6
- package/build/generateEntityFile.d.ts.map +0 -1
- package/build/generateEntityTestFile.d.ts +0 -6
- package/build/generateEntityTestFile.d.ts.map +0 -1
- package/build/generateEnumFile.d.ts +0 -5
- package/build/generateEnumFile.d.ts.map +0 -1
- package/build/generateFactoriesFiles.d.ts +0 -4
- package/build/generateFactoriesFiles.d.ts.map +0 -1
- package/build/generateFlushFunction.d.ts.map +0 -1
- package/build/generateMetadataFile.d.ts +0 -5
- package/build/generateMetadataFile.d.ts.map +0 -1
- package/build/generatePgEnumFile.d.ts +0 -5
- package/build/generatePgEnumFile.d.ts.map +0 -1
- package/build/index.d.ts +0 -11
- package/build/index.d.ts.map +0 -1
- package/build/inheritance.d.ts +0 -10
- package/build/inheritance.d.ts.map +0 -1
- package/build/keywords.d.ts +0 -2
- package/build/keywords.d.ts.map +0 -1
- package/build/loadMetadata.d.ts +0 -26
- package/build/loadMetadata.d.ts.map +0 -1
- package/build/logger.d.ts +0 -10
- package/build/logger.d.ts.map +0 -1
- package/build/scanEntityFiles.d.ts +0 -5
- package/build/scanEntityFiles.d.ts.map +0 -1
- package/build/sortForeignKeys.d.ts.map +0 -1
- package/build/symbols.d.ts +0 -108
- package/build/symbols.d.ts.map +0 -1
- package/build/tsdoc.d.ts +0 -12
- package/build/tsdoc.d.ts.map +0 -1
- package/build/utils.d.ts +0 -31
- package/build/utils.d.ts.map +0 -1
- package/build/write-json-schema.d.ts +0 -2
- package/build/write-json-schema.d.ts.map +0 -1
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: joist-docs
|
|
3
|
+
description: Read the `src/entities/<Entity>.md` business-docs when working on an entity, its resolvers, jobs, or tests. Add only durable, non-obvious domain knowledge that helps readers understand a business rule or avoid a likely mistake; prioritize succinctness, clarity, and discretion. Also covers how `## Overview` and `## Fields`/`### fieldName` sections sync to JSDocs via `yarn joist-codegen`.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Entity docs (`src/entities/<Entity>.md`)
|
|
7
|
+
|
|
8
|
+
Many Joist entities have a sibling Markdown doc — `src/entities/Author.ts` ↔
|
|
9
|
+
`src/entities/Author.md` (same basename; enums under `src/entities/enums/` too). These files hold the
|
|
10
|
+
**"why"** that code can't: business rationale, worked scenarios, gotchas, domain vocabulary, and
|
|
11
|
+
cross-entity workflows. They are written for **both humans and agents** — you are a primary audience.
|
|
12
|
+
|
|
13
|
+
Read routinely; write selectively:
|
|
14
|
+
|
|
15
|
+
1. **Read** the sibling `.md` before/while you work on an entity, to get domain context.
|
|
16
|
+
2. **Write** only when a concise addition would give future readers important context they cannot
|
|
17
|
+
readily get from the code or existing docs. Leaving the docs unchanged is often the right outcome.
|
|
18
|
+
|
|
19
|
+
## 1. Read it first
|
|
20
|
+
|
|
21
|
+
Before editing an entity — its `src/entities/<Entity>.ts`, its resolvers, a job that touches it, or its
|
|
22
|
+
tests — open `src/entities/<Entity>.md` if one exists. It routinely explains things you would otherwise
|
|
23
|
+
have to reverse-engineer or would get subtly wrong:
|
|
24
|
+
|
|
25
|
+
- **Business rationale** — *why* a field/entity exists and what real-world thing it models
|
|
26
|
+
(e.g. `PurchaseOrder.md` on tracking "what and why" a project's cost changed).
|
|
27
|
+
- **Worked scenarios** — concrete `I.e.` walkthroughs with real values ("when an `Employee` is termined, the status workflow is...").
|
|
28
|
+
- **Gotchas & edge cases** — footguns, "this looks stale but isn't", exemptions
|
|
29
|
+
- **Domain vocabulary** — statuses, flags, and other "esoteric unless you know it" domain concepts
|
|
30
|
+
|
|
31
|
+
Follow relevant cross-links (`[Book](Book.md)`, sometimes with anchors like
|
|
32
|
+
`Book.md#Definitions`) into related docs. A missing or thin doc is not by itself a reason to add content.
|
|
33
|
+
|
|
34
|
+
## 2. How the file maps to code (the codegen doc-sync)
|
|
35
|
+
|
|
36
|
+
`joist-config.json` has `"docs": true`, so `yarn joist-codegen` keeps these `.md` files and the entity
|
|
37
|
+
JSDocs in sync. Understanding this is what makes your writing land in the right place.
|
|
38
|
+
|
|
39
|
+
**Only two heading shapes are parsed and synced; everything else is free-form narrative:**
|
|
40
|
+
|
|
41
|
+
| `.md` section | Syncs to | Notes |
|
|
42
|
+
|---|---|---|
|
|
43
|
+
| `## Overview` (body) | the entity **class** JSDoc | exact heading `## Overview` |
|
|
44
|
+
| `## Fields` → `### <fieldName>` (body) | that field/property/relation's JSDoc | `### ` heading must be the **exact member name** |
|
|
45
|
+
| any other `## Section` (e.g. `## Hard vs. Soft Costs`, `## DB Constraints`, mermaid) | **nothing** | free-form; lives only in the `.md`, preserved verbatim |
|
|
46
|
+
|
|
47
|
+
Synced JSDocs are tagged `@generated <Entity>.md` in the `.ts` — that tag means "this comment came from
|
|
48
|
+
the `.md`; edit the `.md`, not here."
|
|
49
|
+
|
|
50
|
+
**Sync is bidirectional, but the `.md` wins.** `yarn joist-codegen`:
|
|
51
|
+
|
|
52
|
+
1. **Backfills** the `.md` from any hand-written `.ts` JSDoc that isn't in the `.md` yet (so a jsdoc you
|
|
53
|
+
write directly on a field gets pulled into `## Fields` for you), then
|
|
54
|
+
2. **Writes the `.md` back into the `.ts`** JSDocs — so for anything already in the `.md`, the `.md` is
|
|
55
|
+
the source of truth and will overwrite a divergent `.ts` comment.
|
|
56
|
+
|
|
57
|
+
Net rule: **to durably document an entity or field, edit the `.md`.** Hand-editing a `@generated` JSDoc
|
|
58
|
+
in the `.ts` gets stomped on the next codegen.
|
|
59
|
+
|
|
60
|
+
### Field-heading constraints (easy to get wrong)
|
|
61
|
+
|
|
62
|
+
- `### <fieldName>` must be a **single word** — the parser matches `\w+` only. `### excludeFromBudget`
|
|
63
|
+
works; `### is excluded`, `` ### `excludeFromBudget` ``, or `### excludeFromBudget (derived)` are **not**
|
|
64
|
+
recognized as field docs.
|
|
65
|
+
- It must be the **exact** name of a field, relation, or property on the entity, and must sit **under the
|
|
66
|
+
`## Fields` heading**. Any other `##` heading ends the fields section — so keep all `### fieldName`
|
|
67
|
+
entries together under the one `## Fields` section (conventionally at the bottom of the file).
|
|
68
|
+
- **Methods don't sync** — only fields/getters/properties/relations get their JSDoc updated.
|
|
69
|
+
|
|
70
|
+
## 3. Choose what is worth documenting
|
|
71
|
+
|
|
72
|
+
Add a note only when the knowledge is durable, non-obvious, and useful for a future domain decision or
|
|
73
|
+
for avoiding a likely mistake. Possible candidates, not a checklist to fill:
|
|
74
|
+
|
|
75
|
+
- You just figured out **why** an entity or field exists, or what it really models.
|
|
76
|
+
- A **non-obvious business rule**, invariant, or "this only applies to X clients" exemption.
|
|
77
|
+
- A **gotcha / footgun** — a value that looks stale but isn't, an ordering requirement, a special-cased
|
|
78
|
+
type.
|
|
79
|
+
- A **cross-entity interaction** or workflow that isn't visible from one file.
|
|
80
|
+
- **Domain vocabulary** a newcomer (human or agent) wouldn't know.
|
|
81
|
+
- A **worked scenario** needed to resolve an ambiguity that a short explanation cannot.
|
|
82
|
+
|
|
83
|
+
**Omit** what the code already says plainly, transient implementation details, exhaustive edge-case
|
|
84
|
+
lists, and a recap of the work just completed. Do not repeat knowledge already documented elsewhere;
|
|
85
|
+
link to it when readers need it. Correct outdated guidance rather than appending a competing explanation.
|
|
86
|
+
|
|
87
|
+
**Where to put it:**
|
|
88
|
+
|
|
89
|
+
- Something specific to one field → a `### <fieldName>` block under `## Fields`. It syncs to that
|
|
90
|
+
member's JSDoc, so it shows on hover/`@generated` in the `.ts`.
|
|
91
|
+
- The entity's purpose → a short `## Overview`, which syncs to the class JSDoc.
|
|
92
|
+
- Necessary longer explanations or cross-entity workflows → a free-form `##` section, linked from the
|
|
93
|
+
field doc if needed. Keep synced JSDocs small enough to read comfortably on hover.
|
|
94
|
+
|
|
95
|
+
**Style** (prioritize succinctness and clarity):
|
|
96
|
+
|
|
97
|
+
- Lead with business meaning and *why*. Use plain language and state each fact once.
|
|
98
|
+
- Default to one sentence for a field and one short paragraph for an overview. Add detail only when
|
|
99
|
+
shortening it would hide an important rule or make the meaning ambiguous.
|
|
100
|
+
- Use a single brief `I.e. ...` example with concrete values only when it clarifies a difficult rule.
|
|
101
|
+
Do not add examples, diagrams, or sections merely to make the doc look complete.
|
|
102
|
+
- Cross-link related entities with relative links: `[Book](Book.md)`.
|
|
103
|
+
- Reference field/entity names in backticks.
|
|
104
|
+
- Before finishing, remove any sentence that does not add necessary meaning. Match existing terminology,
|
|
105
|
+
but do not copy existing verbosity.
|
|
106
|
+
|
|
107
|
+
## 4. Workflow to add or update a doc
|
|
108
|
+
|
|
109
|
+
1. If an addition meets the criteria above, edit `src/entities/<Entity>.md` (create it only if needed — basename must equal the entity, e.g.
|
|
110
|
+
`Author.md`). For field docs, use the exact member name as a `### ` heading under `## Fields`.
|
|
111
|
+
2. Sync into the JSDocs:
|
|
112
|
+
```bash
|
|
113
|
+
mise exec -- yarn joist-codegen
|
|
114
|
+
```
|
|
115
|
+
(or `mise exec -- yarn codegen` to also run graphql-codegen.)
|
|
116
|
+
3. Verify the `@generated <Entity>.md` JSDoc now appears on the class / field in `src/entities/<Entity>.ts`.
|
|
117
|
+
4. Commit the `.md` **and** the regenerated `.ts` JSDoc changes together.
|
|
118
|
+
|
|
119
|
+
Never hand-edit a `@generated <Entity>.md` JSDoc in the `.ts` — edit the `.md` and re-run codegen. Do not
|
|
120
|
+
touch files under `src/entities/codegen/` (see the repo's generated-files rules).
|
|
121
|
+
|
|
122
|
+
## Skeleton for a new doc
|
|
123
|
+
|
|
124
|
+
Include only the sections and fields that need explanation; this is a structure, not a checklist.
|
|
125
|
+
|
|
126
|
+
```markdown
|
|
127
|
+
# <Entity>
|
|
128
|
+
|
|
129
|
+
## Overview
|
|
130
|
+
|
|
131
|
+
<What this entity models and *why* it exists, in business terms. One short paragraph.>
|
|
132
|
+
|
|
133
|
+
## <Some Business Concept> <!-- free-form: rationale, scenarios, gotchas, diagrams; NOT synced -->
|
|
134
|
+
|
|
135
|
+
<Only if needed: a concise explanation of a non-obvious business concept.>
|
|
136
|
+
|
|
137
|
+
## Fields <!-- each ### below syncs into that member's JSDoc -->
|
|
138
|
+
|
|
139
|
+
### someField
|
|
140
|
+
|
|
141
|
+
<Usually one sentence: why it exists or the important non-obvious rule.>
|
|
142
|
+
```
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: joist-em-basics
|
|
3
|
+
description: Create, load, find, mutate, and save entities with Joist's EntityManager. Use when writing data-access or business logic in a Joist project — anything using em.create, em.load, em.find, em.flush, or walking the entity graph.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- Managed by joist-codegen. Do not edit by hand; re-run codegen to update. -->
|
|
7
|
+
|
|
8
|
+
# Joist EntityManager basics
|
|
9
|
+
|
|
10
|
+
The `EntityManager` (`em`) is how entities are loaded from and saved to the
|
|
11
|
+
database. It is a Unit of Work: each request gets its own `em`, which tracks
|
|
12
|
+
the entities it has loaded/created and writes them all out on `em.flush()`.
|
|
13
|
+
|
|
14
|
+
Entities are always loaded/created _through_ the `em`, never via static methods
|
|
15
|
+
on the class (Joist is not ActiveRecord). IDs are tagged strings like `"a:1"`.
|
|
16
|
+
|
|
17
|
+
## Creating
|
|
18
|
+
|
|
19
|
+
`em.create` is synchronous and returns the new entity immediately:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
const author = em.create(Author, { firstName: "a1" });
|
|
23
|
+
// Nested/related entities can be created inline
|
|
24
|
+
const author = em.create(Author, { firstName: "a1", address: { street: "123 Main" } });
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Loading by id
|
|
28
|
+
|
|
29
|
+
Use tagged ids. These throw if the id does not exist (except the `IfExists`
|
|
30
|
+
variants):
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
const a = await em.load(Author, "a:1");
|
|
34
|
+
const as = await em.loadAll(Author, ["a:1", "a:2"]);
|
|
35
|
+
const as = await em.loadAllIfExists(Author, ["a:1", "a:2"]); // skips missing ids
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
To eagerly load relations, pass a populate hint as the 3rd argument; the
|
|
39
|
+
returned entity is typed as "loaded" so the relations can be read synchronously:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
const a = await em.load(Author, "a:1", { books: "reviews" });
|
|
43
|
+
a.books.get.flatMap((b) => b.reviews.get);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Walking the graph
|
|
47
|
+
|
|
48
|
+
~90% of reads are just navigating relations from an entity you already have.
|
|
49
|
+
These are guaranteed N+1-safe, even in a loop:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
const author = await book.author.load(); // load a single relation
|
|
53
|
+
const reviews = await publisher.load((p) => p.books.reviews); // lens
|
|
54
|
+
const loaded = await author.populate({ books: "reviews" }); // populate + .get
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Finding (filtered queries)
|
|
58
|
+
|
|
59
|
+
`em.find` issues a `SELECT` with a "join literal" of nested relations plus
|
|
60
|
+
inline `WHERE` conditions. It is batch/N+1-safe.
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
const books = await em.find(Book, { author: { firstName: "a1" } });
|
|
64
|
+
const recent = await em.find(Book, { publishedAt: { gte: jan1 } });
|
|
65
|
+
const some = await em.find(Author, { firstName: { in: ["a1", "a2"] } });
|
|
66
|
+
|
|
67
|
+
const one = await em.findOne(Book, { title: "b1" }); // undefined if none
|
|
68
|
+
const one = await em.findOneOrFail(Book, { title: "b1" }); // throws if none
|
|
69
|
+
const one = await em.findOrCreate(Author, { email: "a@b.com" });
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`undefined` values are pruned (the condition and any now-unused join are
|
|
73
|
+
dropped), so filters compose cleanly. To filter for null, pass `null`
|
|
74
|
+
explicitly, e.g. `{ firstName: null }`. For `OR` / nested boolean logic, use
|
|
75
|
+
`alias`/`aliases` with a `conditions` argument. See `joist-em-find` for more;
|
|
76
|
+
for aggregates or group-bys, use `joist-em-query` instead.
|
|
77
|
+
|
|
78
|
+
## Mutating
|
|
79
|
+
|
|
80
|
+
Assign fields directly, or use `.set` for a batch of changes:
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
author.firstName = "a2";
|
|
84
|
+
author.set({ firstName: "a2", lastName: "b2" });
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
For partial/RPC-style updates (treating `null` as "unset"), and for
|
|
88
|
+
incrementally updating children, see the `joist-upsert` skill.
|
|
89
|
+
|
|
90
|
+
## Deleting
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
const a = await em.load(Author, "a:1");
|
|
94
|
+
em.delete(a);
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Saving with `em.flush()`
|
|
98
|
+
|
|
99
|
+
`em.flush()` is where everything happens. It is async and:
|
|
100
|
+
|
|
101
|
+
1. Runs lifecycle hooks and validation rules,
|
|
102
|
+
2. Opens a transaction,
|
|
103
|
+
3. Issues batched `INSERT`/`UPDATE`/`DELETE` (one batch per entity type),
|
|
104
|
+
4. Commits.
|
|
105
|
+
|
|
106
|
+
You don't write individual SQL statements — let Joist batch them. `flush` can
|
|
107
|
+
be called multiple times as you do more work:
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
const author = em.create(Author, { firstName: "a1" });
|
|
111
|
+
await em.flush();
|
|
112
|
+
author.firstName = "a2";
|
|
113
|
+
await em.flush();
|
|
114
|
+
```
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: joist-em-execute
|
|
3
|
+
description: Use when writing bulk or immediate SQL INSERT, UPDATE, or DELETE statements with Joist em.execute, including typed table values, set expressions, and returning rows. Explains when to prefer entity mutations and em.flush and which hooks, validation, and in-memory state immediate writes bypass.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- Managed by joist-codegen. Do not edit by hand; re-run codegen to update. -->
|
|
7
|
+
|
|
8
|
+
# Immediate SQL writes with `em.execute`
|
|
9
|
+
|
|
10
|
+
Prefer mutating entities and calling `em.flush()` so Joist runs validation, hooks, and reactions. Use `em.execute` for bulk SQL writes that must happen immediately:
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { table, sql } from "joist-orm";
|
|
14
|
+
|
|
15
|
+
const b = table(Book);
|
|
16
|
+
const inserted = await em.execute({
|
|
17
|
+
insert: b,
|
|
18
|
+
values: [{ title: "New book", authorId: "a:1" }],
|
|
19
|
+
returning: b.id,
|
|
20
|
+
}); // inserted.rows is BookId[]
|
|
21
|
+
|
|
22
|
+
const updated = await em.execute({
|
|
23
|
+
update: b,
|
|
24
|
+
set: { order: sql.number`${b.order} + ${1}` },
|
|
25
|
+
where: b.id.eq("b:1"),
|
|
26
|
+
returning: b.order,
|
|
27
|
+
}); // updated.rows is number[]
|
|
28
|
+
|
|
29
|
+
await em.execute({ delete: b, where: b.id.eq("b:1") });
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
- `insert` also supports `from: { from: source, select: [...] }` for INSERT ... SELECT. `returning` accepts a column or a named projection; results are in `.rows`.
|
|
33
|
+
- These statements do **not** flush pending entities or run entity hooks, validation, defaults, reactions, updatedAt maintenance, or optimistic locking. Already-loaded entities may be stale afterward; database triggers still run.
|
|
34
|
+
|
|
35
|
+
Full docs: <https://joist-orm.io/features/sql-mutations/>.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: joist-em-find
|
|
3
|
+
description: Use when writing or debugging Joist em.find, findOne, or findOneOrFail entity queries, including relation filters, OR conditions, optional filters, collection joins, and N+1 behavior. For aggregates or custom SELECTs, use joist-em-query instead.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- Managed by joist-codegen. Do not edit by hand; re-run codegen to update. -->
|
|
7
|
+
|
|
8
|
+
# Finding entities with `em.find`
|
|
9
|
+
|
|
10
|
+
Prefer `em.find` for entity SELECTs: Joist automatically batches finds to avoid N+1 queries. Nested relation filters become joins; inline conditions are AND-ed:
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
const books = await em.find(Book, {
|
|
14
|
+
author: { firstName: "Alice" },
|
|
15
|
+
publishedAt: { gte: jan1 },
|
|
16
|
+
});
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
- Operators include `eq`, `ne`, `in`, `gt`, `gte`, `lt`, `lte`, `like`, and `ilike`. Pass an entity or tagged ID to filter a reference.
|
|
20
|
+
- `undefined` drops a condition and any unused join; use explicit `null` for `IS NULL`.
|
|
21
|
+
- For `OR`, bind `alias(Book)` with `{ as: b }` and pass `{ conditions: { or: [b.title.eq("A"), b.title.eq("B")] } }` as the third argument. Bind aliases on joined tables too when conditions span relations.
|
|
22
|
+
- Collection filters usually become `EXISTS` subqueries to avoid duplicate roots. Complex alias conditions may instead use `LEFT JOIN`s; opt into multiple collection left joins only when the fanout is intentional.
|
|
23
|
+
- `findOne` returns `undefined` when absent; `findOneOrFail` throws. Both reject multiple matches.
|
|
24
|
+
- Normal `find` reads the database, not unflushed entity changes; use `findWithNewOrChanged` for flat filters that must include in-memory changes.
|
|
25
|
+
|
|
26
|
+
For aggregates, projections, subqueries, or explicit SQL control, use `joist-em-query`.
|
|
27
|
+
Full docs: <https://joist-orm.io/features/queries-find/>.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: joist-em-query
|
|
3
|
+
description: Use when writing Joist em.query SELECTs that need aggregates, projections, grouping, subqueries, CTEs, or SQL expressions beyond em.find. Covers typed table aliases, joins, select result shapes, pruning, and the fact that every em.query is a database call.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- Managed by joist-codegen. Do not edit by hand; re-run codegen to update. -->
|
|
7
|
+
|
|
8
|
+
# SQL SELECTs with `em.query`
|
|
9
|
+
|
|
10
|
+
Use `em.find` for ordinary entity reads; use `em.query` for SQL-shaped SELECTs. Unlike batched `em.find`, **each `em.query` makes a database call**.
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { tables } from "joist-orm";
|
|
14
|
+
|
|
15
|
+
const [a, b] = tables(Author, Book);
|
|
16
|
+
const rows = await em.query({
|
|
17
|
+
from: a,
|
|
18
|
+
join: [a.books.as(b)],
|
|
19
|
+
select: { name: a.firstName, bookCount: b.id.count() },
|
|
20
|
+
groupBy: [a.firstName],
|
|
21
|
+
orderBy: { bookCount: "DESC" },
|
|
22
|
+
}); // { name: string; bookCount: number }[]
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
- `table(Entity)` / `tables(...)` expose typed columns. Join via relation paths (`a.books.as(b)`), a relation tree, or explicit `{ inner: b, on: ... }` / `{ left: b, on: ... }`.
|
|
26
|
+
- `select: { ... }` returns typed rows; `select: a.id` returns scalar values; `select: a` returns identity-mapped entities (optionally with `populate`). None are auto-batched.
|
|
27
|
+
- Use column methods (`eq`, `gte`, `count`, etc.) in `where`/`having`; compose conditions with `{ and: [...] }` or `{ or: [...] }`. Use `query(...)` for reusable subqueries or CTEs and typed `sql.*` tagged templates for custom SQL.
|
|
28
|
+
- Conditions with `undefined` and joins unused after pruning disappear. Use explicit `null` to filter for SQL NULL; use `keep: true` on a join or `pruneJoins: false` if it must remain.
|
|
29
|
+
- Joins to collections fan out rows. For a yes/no child filter without duplicates, use `exists` or an `in` subquery.
|
|
30
|
+
|
|
31
|
+
For immediate INSERT/UPDATE/DELETE, use `joist-em-execute`.
|
|
32
|
+
Full docs: <https://joist-orm.io/features/queries-raw/>.
|