@rawsql-ts/ztd-cli 0.15.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/README.md +38 -25
  2. package/dist/commands/init.d.ts +13 -0
  3. package/dist/commands/init.js +372 -118
  4. package/dist/commands/init.js.map +1 -1
  5. package/dist/commands/lint.d.ts +4 -4
  6. package/dist/commands/lint.js +60 -40
  7. package/dist/commands/lint.js.map +1 -1
  8. package/dist/commands/ztdConfig.d.ts +2 -2
  9. package/dist/commands/ztdConfig.js +26 -12
  10. package/dist/commands/ztdConfig.js.map +1 -1
  11. package/dist/utils/optionalDependencies.d.ts +35 -0
  12. package/dist/utils/optionalDependencies.js +96 -0
  13. package/dist/utils/optionalDependencies.js.map +1 -0
  14. package/package.json +18 -10
  15. package/templates/AGENTS.md +36 -296
  16. package/templates/README.md +12 -237
  17. package/templates/dist/drivers/pg-testkit/src/driver/PgTestkitClient.d.ts +38 -0
  18. package/templates/dist/drivers/pg-testkit/src/driver/PgTestkitClient.js +117 -0
  19. package/templates/dist/drivers/pg-testkit/src/driver/PgTestkitClient.js.map +1 -0
  20. package/templates/dist/drivers/pg-testkit/src/driver/createPgTestkitPool.d.ts +4 -0
  21. package/templates/dist/drivers/pg-testkit/src/driver/createPgTestkitPool.js +71 -0
  22. package/templates/dist/drivers/pg-testkit/src/driver/createPgTestkitPool.js.map +1 -0
  23. package/templates/dist/drivers/pg-testkit/src/index.d.ts +5 -0
  24. package/templates/dist/drivers/pg-testkit/src/index.js +11 -0
  25. package/templates/dist/drivers/pg-testkit/src/index.js.map +1 -0
  26. package/templates/dist/drivers/pg-testkit/src/proxy/wrapPgClient.d.ts +3 -0
  27. package/templates/dist/drivers/pg-testkit/src/proxy/wrapPgClient.js +79 -0
  28. package/templates/dist/drivers/pg-testkit/src/proxy/wrapPgClient.js.map +1 -0
  29. package/templates/dist/drivers/pg-testkit/src/types.d.ts +69 -0
  30. package/templates/dist/drivers/pg-testkit/src/types.js +3 -0
  31. package/templates/dist/drivers/pg-testkit/src/types.js.map +1 -0
  32. package/templates/dist/drivers/pg-testkit/src/utils/fixtureState.d.ts +15 -0
  33. package/templates/dist/drivers/pg-testkit/src/utils/fixtureState.js +34 -0
  34. package/templates/dist/drivers/pg-testkit/src/utils/fixtureState.js.map +1 -0
  35. package/templates/dist/drivers/pg-testkit/src/utils/fixtureValidation.d.ts +12 -0
  36. package/templates/dist/drivers/pg-testkit/src/utils/fixtureValidation.js +53 -0
  37. package/templates/dist/drivers/pg-testkit/src/utils/fixtureValidation.js.map +1 -0
  38. package/templates/dist/mapper-core/src/index.d.ts +160 -0
  39. package/templates/dist/mapper-core/src/index.js +637 -0
  40. package/templates/dist/mapper-core/src/index.js.map +1 -0
  41. package/templates/dist/testkit-core/src/errors/index.d.ts +49 -0
  42. package/templates/dist/testkit-core/src/errors/index.js +111 -0
  43. package/templates/dist/testkit-core/src/errors/index.js.map +1 -0
  44. package/templates/dist/testkit-core/src/fixtures/ColumnAffinity.d.ts +5 -0
  45. package/templates/dist/testkit-core/src/fixtures/ColumnAffinity.js +29 -0
  46. package/templates/dist/testkit-core/src/fixtures/ColumnAffinity.js.map +1 -0
  47. package/templates/dist/testkit-core/src/fixtures/DdlFixtureLoader.d.ts +37 -0
  48. package/templates/dist/testkit-core/src/fixtures/DdlFixtureLoader.js +182 -0
  49. package/templates/dist/testkit-core/src/fixtures/DdlFixtureLoader.js.map +1 -0
  50. package/templates/dist/testkit-core/src/fixtures/FixtureProvider.d.ts +20 -0
  51. package/templates/dist/testkit-core/src/fixtures/FixtureProvider.js +121 -0
  52. package/templates/dist/testkit-core/src/fixtures/FixtureProvider.js.map +1 -0
  53. package/templates/dist/testkit-core/src/fixtures/FixtureStore.d.ts +51 -0
  54. package/templates/dist/testkit-core/src/fixtures/FixtureStore.js +199 -0
  55. package/templates/dist/testkit-core/src/fixtures/FixtureStore.js.map +1 -0
  56. package/templates/dist/testkit-core/src/fixtures/TableDefinitionSchemaRegistry.d.ts +10 -0
  57. package/templates/dist/testkit-core/src/fixtures/TableDefinitionSchemaRegistry.js +28 -0
  58. package/templates/dist/testkit-core/src/fixtures/TableDefinitionSchemaRegistry.js.map +1 -0
  59. package/templates/dist/testkit-core/src/fixtures/TableNameResolver.d.ts +18 -0
  60. package/templates/dist/testkit-core/src/fixtures/TableNameResolver.js +80 -0
  61. package/templates/dist/testkit-core/src/fixtures/TableNameResolver.js.map +1 -0
  62. package/templates/dist/testkit-core/src/fixtures/ddlLint.d.ts +59 -0
  63. package/templates/dist/testkit-core/src/fixtures/ddlLint.js +489 -0
  64. package/templates/dist/testkit-core/src/fixtures/ddlLint.js.map +1 -0
  65. package/templates/dist/testkit-core/src/fixtures/naming.d.ts +1 -0
  66. package/templates/dist/testkit-core/src/fixtures/naming.js +6 -0
  67. package/templates/dist/testkit-core/src/fixtures/naming.js.map +1 -0
  68. package/templates/dist/testkit-core/src/index.d.ts +17 -0
  69. package/templates/dist/testkit-core/src/index.js +47 -0
  70. package/templates/dist/testkit-core/src/index.js.map +1 -0
  71. package/templates/dist/testkit-core/src/logger/NoopLogger.d.ts +8 -0
  72. package/templates/dist/testkit-core/src/logger/NoopLogger.js +16 -0
  73. package/templates/dist/testkit-core/src/logger/NoopLogger.js.map +1 -0
  74. package/templates/dist/testkit-core/src/provider/TestkitProvider.d.ts +57 -0
  75. package/templates/dist/testkit-core/src/provider/TestkitProvider.js +149 -0
  76. package/templates/dist/testkit-core/src/provider/TestkitProvider.js.map +1 -0
  77. package/templates/dist/testkit-core/src/rewriter/ResultSelectRewriter.d.ts +43 -0
  78. package/templates/dist/testkit-core/src/rewriter/ResultSelectRewriter.js +473 -0
  79. package/templates/dist/testkit-core/src/rewriter/ResultSelectRewriter.js.map +1 -0
  80. package/templates/dist/testkit-core/src/rewriter/SelectAnalyzer.d.ts +9 -0
  81. package/templates/dist/testkit-core/src/rewriter/SelectAnalyzer.js +38 -0
  82. package/templates/dist/testkit-core/src/rewriter/SelectAnalyzer.js.map +1 -0
  83. package/templates/dist/testkit-core/src/rewriter/SelectFixtureRewriter.d.ts +42 -0
  84. package/templates/dist/testkit-core/src/rewriter/SelectFixtureRewriter.js +298 -0
  85. package/templates/dist/testkit-core/src/rewriter/SelectFixtureRewriter.js.map +1 -0
  86. package/templates/dist/testkit-core/src/sql/SqliteValuesBuilder.d.ts +12 -0
  87. package/templates/dist/testkit-core/src/sql/SqliteValuesBuilder.js +63 -0
  88. package/templates/dist/testkit-core/src/sql/SqliteValuesBuilder.js.map +1 -0
  89. package/templates/dist/testkit-core/src/types/index.d.ts +69 -0
  90. package/templates/dist/testkit-core/src/types/index.js +3 -0
  91. package/templates/dist/testkit-core/src/types/index.js.map +1 -0
  92. package/templates/dist/testkit-core/src/utils/queryHelpers.d.ts +28 -0
  93. package/templates/dist/testkit-core/src/utils/queryHelpers.js +81 -0
  94. package/templates/dist/testkit-core/src/utils/queryHelpers.js.map +1 -0
  95. package/templates/dist/writer-core/src/index.d.ts +34 -0
  96. package/templates/dist/writer-core/src/index.js +115 -0
  97. package/templates/dist/writer-core/src/index.js.map +1 -0
  98. package/templates/dist/ztd-cli/templates/src/db/sql-client.d.ts +20 -0
  99. package/templates/dist/ztd-cli/templates/src/db/sql-client.js +3 -0
  100. package/templates/dist/ztd-cli/templates/src/db/sql-client.js.map +1 -0
  101. package/templates/dist/ztd-cli/templates/src/db/sql-client.ts +24 -0
  102. package/templates/dist/ztd-cli/templates/src/repositories/user-accounts.d.ts +36 -0
  103. package/templates/dist/ztd-cli/templates/src/repositories/user-accounts.js +85 -0
  104. package/templates/dist/ztd-cli/templates/src/repositories/user-accounts.js.map +1 -0
  105. package/templates/dist/ztd-cli/templates/tests/generated/ztd-row-map.generated.d.ts +20 -0
  106. package/templates/dist/ztd-cli/templates/tests/generated/ztd-row-map.generated.js +33 -0
  107. package/templates/dist/ztd-cli/templates/tests/generated/ztd-row-map.generated.js.map +1 -0
  108. package/templates/dist/ztd-cli/templates/tests/support/global-setup.d.ts +10 -0
  109. package/templates/dist/ztd-cli/templates/tests/support/global-setup.js +29 -0
  110. package/templates/dist/ztd-cli/templates/tests/support/global-setup.js.map +1 -0
  111. package/templates/dist/ztd-cli/templates/tests/support/testkit-client.d.ts +66 -0
  112. package/templates/dist/ztd-cli/templates/tests/support/testkit-client.js +552 -0
  113. package/templates/dist/ztd-cli/templates/tests/support/testkit-client.js.map +1 -0
  114. package/templates/dist/ztd-cli/templates/tests/user-profiles.test.d.ts +1 -0
  115. package/templates/dist/ztd-cli/templates/tests/user-profiles.test.js +82 -0
  116. package/templates/dist/ztd-cli/templates/tests/user-profiles.test.js.map +1 -0
  117. package/templates/dist/ztd-cli/templates/tests/writer-constraints.test.d.ts +1 -0
  118. package/templates/dist/ztd-cli/templates/tests/writer-constraints.test.js +29 -0
  119. package/templates/dist/ztd-cli/templates/tests/writer-constraints.test.js.map +1 -0
  120. package/templates/dist/ztd-cli/templates/tests/ztd-layout.generated.d.ts +7 -0
  121. package/templates/dist/ztd-cli/templates/tests/ztd-layout.generated.js +10 -0
  122. package/templates/dist/ztd-cli/templates/tests/ztd-layout.generated.js.map +1 -0
  123. package/templates/src/AGENTS.md +26 -0
  124. package/templates/src/catalog/AGENTS.md +37 -0
  125. package/templates/src/catalog/runtime/AGENTS.md +75 -0
  126. package/templates/src/catalog/runtime/_coercions.ts +1 -0
  127. package/templates/src/catalog/runtime/_smoke.runtime.ts +21 -0
  128. package/templates/src/catalog/specs/AGENTS.md +48 -0
  129. package/templates/src/catalog/specs/_smoke.spec.arktype.ts +21 -0
  130. package/templates/src/catalog/specs/_smoke.spec.zod.ts +20 -0
  131. package/templates/src/db/sql-client.ts +5 -5
  132. package/templates/src/jobs/AGENTS.md +26 -0
  133. package/templates/src/jobs/README.md +3 -0
  134. package/templates/src/repositories/AGENTS.md +118 -0
  135. package/templates/src/repositories/tables/AGENTS.md +94 -0
  136. package/templates/src/repositories/tables/README.md +3 -0
  137. package/templates/src/repositories/views/AGENTS.md +25 -0
  138. package/templates/src/repositories/views/README.md +3 -0
  139. package/templates/src/sql/AGENTS.md +77 -0
  140. package/templates/src/sql/README.md +6 -0
  141. package/templates/tests/AGENTS.md +43 -129
  142. package/templates/tests/generated/AGENTS.md +16 -0
  143. package/templates/tests/smoke.test.ts +5 -0
  144. package/templates/tests/smoke.validation.test.ts +34 -0
  145. package/templates/tests/support/AGENTS.md +26 -0
  146. package/templates/tests/support/global-setup.ts +8 -23
  147. package/templates/tests/support/testkit-client.ts +13 -741
  148. package/templates/tests/ztd-layout.generated.ts +0 -2
  149. package/templates/tsconfig.json +9 -3
  150. package/templates/ztd/AGENTS.md +11 -142
  151. package/templates/ztd/README.md +4 -82
  152. package/templates/ztd/ddl/AGENTS.md +34 -0
  153. package/templates/ztd/ddl/demo.sql +74 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-profiles.test.js","sourceRoot":"","sources":["../../../../tests/user-profiles.test.ts"],"names":[],"mappings":";;AAAA,mCAAgD;AAEhD,6EAI2C;AAC3C,6DAA+D;AAC/D,qEAAqE;AAErE,SAAS,iBAAiB;IACxB,OAAO;QACL;YACE,eAAe,EAAE,CAAC;YAClB,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,mBAAmB;YAC1B,YAAY,EAAE,cAAc;YAC5B,UAAU,EAAE,sBAAsB;YAClC,UAAU,EAAE,sBAAsB;SACnC;QACD;YACE,eAAe,EAAE,CAAC;YAClB,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,mBAAmB;YAC1B,YAAY,EAAE,eAAe;YAC7B,UAAU,EAAE,sBAAsB;YAClC,UAAU,EAAE,sBAAsB;SACnC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB;IACxB,OAAO;QACL;YACE,UAAU,EAAE,GAAG;YACf,eAAe,EAAE,CAAC;YAClB,GAAG,EAAE,oCAAoC;YACzC,OAAO,EAAE,qBAAqB;YAC9B,QAAQ,EAAE,IAAI;SACf;KACF,CAAC;AACJ,CAAC;AAED,SAAS,aAAa;IACpB,OAAO;QACL,IAAA,oCAAY,EACV,qBAAqB,EACrB,iBAAiB,EAAE,EACnB,oCAAY,CAAC,qBAAqB,CAAC,CACpC;QACD,IAAA,oCAAY,EACV,qBAAqB,EACrB,iBAAiB,EAAE,EACnB,oCAAY,CAAC,qBAAqB,CAAC,CACpC;KACF,CAAC;AACJ,CAAC;AAED,IAAA,iBAAQ,EAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,IAAA,aAAI,EAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,QAAQ,GAAG,aAAa,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,IAAA,oCAAmB,EAAC,QAAQ,CAAC,CAAC;QACnD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAA,gCAAgB,EAAC,MAAM,CAAC,CAAC;YAC9C,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,OAAO,CAAC;gBACrB;oBACE,aAAa,EAAE,CAAC;oBAChB,QAAQ,EAAE,OAAO;oBACjB,KAAK,EAAE,mBAAmB;oBAC1B,WAAW,EAAE,cAAc;oBAC3B,SAAS,EAAE,IAAI,IAAI,CAAC,sBAAsB,CAAC;oBAC3C,SAAS,EAAE,IAAI,IAAI,CAAC,sBAAsB,CAAC;oBAC3C,OAAO,EAAE;wBACP,SAAS,EAAE,GAAG;wBACd,aAAa,EAAE,CAAC;wBAChB,GAAG,EAAE,oCAAoC;wBACzC,OAAO,EAAE,qBAAqB;wBAC9B,QAAQ,EAAE,IAAI;qBACf;iBACF;gBACD;oBACE,aAAa,EAAE,CAAC;oBAChB,QAAQ,EAAE,OAAO;oBACjB,KAAK,EAAE,mBAAmB;oBAC1B,WAAW,EAAE,eAAe;oBAC5B,SAAS,EAAE,IAAI,IAAI,CAAC,sBAAsB,CAAC;oBAC3C,SAAS,EAAE,IAAI,IAAI,CAAC,sBAAsB,CAAC;oBAC3C,OAAO,EAAE,SAAS;iBACnB;aACF,CAAC,CAAC;QACL,CAAC;gBAAS,CAAC;YACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const ztd_row_map_generated_1 = require("./generated/ztd-row-map.generated");
5
+ const user_accounts_1 = require("../src/repositories/user-accounts");
6
+ const userColumns = new Set(Object.keys(ztd_row_map_generated_1.tableSchemas['public.user_account'].columns));
7
+ (0, vitest_1.describe)('user_account writer columns', () => {
8
+ (0, vitest_1.test)('insert columns must exist on the canonical table', () => {
9
+ const { insertColumns } = user_accounts_1.userAccountWriterColumnSets;
10
+ const missing = insertColumns.filter((column) => !userColumns.has(column));
11
+ (0, vitest_1.expect)(missing).toEqual([]);
12
+ (0, vitest_1.expect)(insertColumns).toEqual(vitest_1.expect.arrayContaining(['username', 'email', 'display_name']));
13
+ });
14
+ (0, vitest_1.test)('update columns stay within allowed set and avoid immutable columns', () => {
15
+ const { updateColumns, immutableColumns } = user_accounts_1.userAccountWriterColumnSets;
16
+ const missing = updateColumns.filter((column) => !userColumns.has(column));
17
+ (0, vitest_1.expect)(missing).toEqual([]);
18
+ (0, vitest_1.expect)(updateColumns).not.toEqual(vitest_1.expect.arrayContaining([...immutableColumns]));
19
+ });
20
+ (0, vitest_1.test)('immutable columns reflect the DDL and are not targetted by updates', () => {
21
+ const { immutableColumns, updateColumns } = user_accounts_1.userAccountWriterColumnSets;
22
+ const missing = immutableColumns.filter((column) => !userColumns.has(column));
23
+ (0, vitest_1.expect)(missing).toEqual([]);
24
+ immutableColumns.forEach((column) => {
25
+ (0, vitest_1.expect)(updateColumns).not.toContain(column);
26
+ });
27
+ });
28
+ });
29
+ //# sourceMappingURL=writer-constraints.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writer-constraints.test.js","sourceRoot":"","sources":["../../../../tests/writer-constraints.test.ts"],"names":[],"mappings":";;AAAA,mCAAgD;AAChD,6EAAiE;AACjE,qEAAgF;AAEhF,MAAM,WAAW,GAAG,IAAI,GAAG,CACzB,MAAM,CAAC,IAAI,CAAC,oCAAY,CAAC,qBAAqB,CAAC,CAAC,OAAO,CAAC,CACzD,CAAC;AAEF,IAAA,iBAAQ,EAAC,6BAA6B,EAAE,GAAG,EAAE;IAC3C,IAAA,aAAI,EAAC,kDAAkD,EAAE,GAAG,EAAE;QAC5D,MAAM,EAAE,aAAa,EAAE,GAAG,2CAA2B,CAAC;QACtD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3E,IAAA,eAAM,EAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC5B,IAAA,eAAM,EAAC,aAAa,CAAC,CAAC,OAAO,CAC3B,eAAM,CAAC,eAAe,CAAC,CAAC,UAAU,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC,CAC9D,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAA,aAAI,EAAC,oEAAoE,EAAE,GAAG,EAAE;QAC9E,MAAM,EAAE,aAAa,EAAE,gBAAgB,EAAE,GAAG,2CAA2B,CAAC;QACxE,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3E,IAAA,eAAM,EAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC5B,IAAA,eAAM,EAAC,aAAa,CAAC,CAAC,GAAG,CAAC,OAAO,CAC/B,eAAM,CAAC,eAAe,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAC9C,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAA,aAAI,EAAC,oEAAoE,EAAE,GAAG,EAAE;QAC9E,MAAM,EAAE,gBAAgB,EAAE,aAAa,EAAE,GAAG,2CAA2B,CAAC;QACxE,MAAM,OAAO,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9E,IAAA,eAAM,EAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC5B,gBAAgB,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;YAClC,IAAA,eAAM,EAAC,aAAa,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ declare const _default: {
2
+ ztdRootDir: string;
3
+ ddlDir: string;
4
+ enumsDir: string;
5
+ domainSpecsDir: string;
6
+ };
7
+ export default _default;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ // GENERATED FILE. DO NOT EDIT.
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.default = {
5
+ ztdRootDir: 'ztd',
6
+ ddlDir: 'ztd/ddl',
7
+ enumsDir: 'ztd/enums',
8
+ domainSpecsDir: 'ztd/domain-specs',
9
+ };
10
+ //# sourceMappingURL=ztd-layout.generated.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ztd-layout.generated.js","sourceRoot":"","sources":["../../../../tests/ztd-layout.generated.ts"],"names":[],"mappings":";AAAA,+BAA+B;;AAE/B,kBAAe;IACb,UAAU,EAAE,KAAK;IACjB,MAAM,EAAE,SAAS;IACjB,QAAQ,EAAE,WAAW;IACrB,cAAc,EAAE,kBAAkB;CACnC,CAAC"}
@@ -0,0 +1,26 @@
1
+ # src AGENTS
2
+
3
+ This directory is runtime application code.
4
+
5
+ ## Boundaries
6
+
7
+ - Code under "src/" MUST NOT import from:
8
+ - "tests/"
9
+ - "tests/generated/"
10
+ - any test-only helpers
11
+ - Runtime code MUST NOT depend on ZTD internals.
12
+ - Generated artifacts are test-only signals, not runtime dependencies.
13
+
14
+ ## Implementation principles
15
+
16
+ - Keep modules small and explicit.
17
+ - Prefer explicit contracts over inference.
18
+ - Favor deterministic behavior and clear error surfaces.
19
+
20
+ ## Verification (required)
21
+
22
+ After changes:
23
+ - Run the project typecheck command (example: "pnpm typecheck").
24
+ - Run relevant tests (example: "pnpm test" or a filtered command).
25
+
26
+ If you touched SQL contracts or catalog specs, run tests that exercise them.
@@ -0,0 +1,37 @@
1
+ # src/catalog AGENTS
2
+
3
+ This directory is runtime code.
4
+
5
+ ## Purpose
6
+
7
+ Catalog defines named query entry points by binding:
8
+ - SQL assets ("src/sql/*.sql")
9
+ - input parameter contracts
10
+ - output DTO contracts
11
+ - validation and mapping behavior
12
+ - observability hooks (if supported)
13
+
14
+ ## Directory roles (important)
15
+
16
+ - "src/catalog/specs": human-owned contracts (params + DTO + semantics)
17
+ - "src/catalog/runtime": AI-assisted runtime wiring (executors, helpers, sinks)
18
+
19
+ ## Non-negotiable ownership
20
+
21
+ - Specs are contracts. Do not infer, guess, widen, or narrow them.
22
+ - Do not change params / DTO shapes in "specs" without explicit instruction.
23
+
24
+ ## Boundaries
25
+
26
+ - Code under "src/catalog/" MUST NOT import from:
27
+ - "tests/"
28
+ - "tests/generated/"
29
+ - "ztd/"
30
+ - Do not depend on ZTD internals at runtime.
31
+
32
+ ## Testing rule (required)
33
+
34
+ Every spec MUST have tests that verify:
35
+ - SQL executes under ZTD rewriting
36
+ - mapping/validation behavior is correct (success and failure)
37
+ - output DTO shape matches expectations
@@ -0,0 +1,75 @@
1
+ # src/catalog/runtime AGENTS
2
+
3
+ This directory contains runtime wiring for catalog specs:
4
+ - parameter validation entrypoints
5
+ - row-to-DTO mapping
6
+ - output validation
7
+
8
+ ## Runtime classification
9
+
10
+ - This is a runtime directory.
11
+ - Code here is executed/loaded by the application.
12
+
13
+ ## Responsibilities (critical)
14
+
15
+ - Runtime MUST be the only place that:
16
+ - validates unknown inputs into typed params
17
+ - maps SQL rows (snake_case) into DTO objects
18
+ - validates DTO outputs before returning to repositories
19
+ - Runtime output validation MUST follow the output contract type (DTO or scalar).
20
+ - Command outputs MAY be scalar identifiers or `void`; DTO mapping is required only when the output contract is DTO.
21
+
22
+ Repositories MUST call runtime helpers (ensure*/map*) and MUST NOT bypass them.
23
+
24
+ ## Validator requirement (required)
25
+
26
+ - A validator library (zod or arktype) is always available.
27
+ - Runtime MUST apply validators for:
28
+ - input params (unknown -> typed)
29
+ - outputs (mapped DTO -> validated DTO)
30
+
31
+ Do not rely on TypeScript types alone.
32
+
33
+ ## SQL row normalization (important)
34
+
35
+ SQL drivers may return different runtime representations for the same column types.
36
+ Runtime MUST normalize driver-dependent values before validating DTOs.
37
+
38
+ Required normalization rules:
39
+ - Timestamp columns (e.g. timestamptz) may arrive as Date or string.
40
+ - Runtime MUST use `timestampFromDriver` from `@rawsql-ts/sql-contract`.
41
+ - Do NOT re-implement `normalizeTimestamp` locally.
42
+ - Do NOT call `new Date(...)` directly for driver-dependent timestamp normalization.
43
+ - Numeric columns may arrive as number, string, or bigint depending on driver.
44
+ - Normalization rules MUST be explicit per contract and MUST NOT be silent.
45
+
46
+ Never force SQL assets to encode driver-specific behavior.
47
+
48
+ ## Mapping rules (required)
49
+
50
+ - Keep SQL assets snake_case and DTO-independent.
51
+ - Mapping occurs in runtime:
52
+ - snake_case row -> DTO-shaped object
53
+ - apply normalization
54
+ - validate via spec-owned validator
55
+ - DTO camelCase aliases in SQL are forbidden.
56
+
57
+ ## Entry points (recommended)
58
+
59
+ Prefer these patterns:
60
+ - `ensureXxxParams(value: unknown): XxxParams` (validate inputs)
61
+ - `mapXxxRowToDto(row: XxxSqlRow): XxxDto` (normalize + validate outputs)
62
+
63
+ The `map*` functions MUST always validate before returning.
64
+
65
+ ## Error behavior (required)
66
+
67
+ - Validation errors must fail fast with clear messages.
68
+ - Do not swallow validator errors.
69
+ - Do not silently coerce invalid values unless explicitly defined by the contract.
70
+
71
+ ## Boundaries
72
+
73
+ - Do not perform database I/O here.
74
+ - Do not import from "tests/" or "tests/generated/".
75
+ - Do not define human-owned contracts here; they live in "src/catalog/specs".
@@ -0,0 +1 @@
1
+ export { timestampFromDriver as normalizeTimestamp } from '@rawsql-ts/sql-contract';
@@ -0,0 +1,21 @@
1
+ import { parseSmokeOutput, type SmokeOutput } from '../specs/_smoke.spec';
2
+ import { normalizeTimestamp } from './_coercions';
3
+
4
+ /**
5
+ * Validate runtime output against the catalog smoke invariant.
6
+ */
7
+ export function ensureSmokeOutput(value: unknown): SmokeOutput {
8
+ // Normalize driver-dependent timestamp representations before contract validation.
9
+ if (isRecord(value) && 'createdAt' in value) {
10
+ return parseSmokeOutput({
11
+ ...value,
12
+ createdAt: normalizeTimestamp(value.createdAt, 'createdAt')
13
+ });
14
+ }
15
+
16
+ return parseSmokeOutput(value);
17
+ }
18
+
19
+ function isRecord(value: unknown): value is Record<string, unknown> {
20
+ return typeof value === 'object' && value !== null;
21
+ }
@@ -0,0 +1,48 @@
1
+ # src/catalog/specs AGENTS
2
+
3
+ This directory defines query and command specifications (contracts).
4
+
5
+ ## Runtime classification
6
+
7
+ - This is a runtime directory.
8
+ - Contents are human-owned contracts, not implementation details.
9
+
10
+ ## Ownership (critical)
11
+
12
+ - Specs are human-owned.
13
+ - Input parameters are part of the domain contract.
14
+ - Output DTO shapes are part of the domain contract.
15
+ - Cardinality and semantics are part of the domain contract.
16
+
17
+ AI MUST NOT:
18
+ - infer missing parameters
19
+ - widen or narrow DTO shapes
20
+ - change nullability or optionality
21
+ - change CUD return shape implicitly
22
+
23
+ Changes require explicit human instruction.
24
+
25
+ ## Validator requirement (required)
26
+
27
+ - A validator library (zod or arktype) is always available.
28
+ - Every spec MUST define validators for its public inputs/outputs.
29
+ - Validators are part of the contract and are human-owned.
30
+
31
+ ## Driver variability policy (important)
32
+
33
+ Specs MUST NOT require SQL assets to encode driver-specific workarounds.
34
+
35
+ - Specs may acknowledge that SQL rows can vary in representation by driver
36
+ (e.g. timestamps as Date or string).
37
+ - Normalization for driver-dependent values is implemented in catalog runtime,
38
+ then validated against the spec.
39
+
40
+ Contracts define the final DTO shape.
41
+ Runtime defines normalization steps to reach that shape.
42
+
43
+ ## What does NOT belong here
44
+
45
+ - No executors
46
+ - No database connections
47
+ - No ZTD internals
48
+ - No SQL camelCase aliasing rules (SQL rules live under src/sql)
@@ -0,0 +1,21 @@
1
+ import { type } from 'arktype';
2
+
3
+ /**
4
+ * Validator invariant contract used to prove runtime validation wiring.
5
+ *
6
+ * This file is intentionally minimal and domain-agnostic.
7
+ */
8
+ export const smokeOutputSchema = type({
9
+ id: 'number.integer',
10
+ createdAt: 'Date'
11
+ });
12
+
13
+ export type SmokeOutput = ReturnType<typeof smokeOutputSchema>;
14
+
15
+ /**
16
+ * Parse and validate an unknown runtime payload.
17
+ */
18
+ export function parseSmokeOutput(value: unknown): SmokeOutput {
19
+ smokeOutputSchema.assert(value);
20
+ return value as SmokeOutput;
21
+ }
@@ -0,0 +1,20 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * Validator invariant contract used to prove runtime validation wiring.
5
+ *
6
+ * This file is intentionally minimal and domain-agnostic.
7
+ */
8
+ export const smokeOutputSchema = z.object({
9
+ id: z.number().int(),
10
+ createdAt: z.date()
11
+ });
12
+
13
+ export type SmokeOutput = z.infer<typeof smokeOutputSchema>;
14
+
15
+ /**
16
+ * Parse and validate an unknown runtime payload.
17
+ */
18
+ export function parseSmokeOutput(value: unknown): SmokeOutput {
19
+ return smokeOutputSchema.parse(value);
20
+ }
@@ -9,16 +9,16 @@ export type SqlQueryRows<T> = Promise<T[]>;
9
9
  /**
10
10
  * Minimal SQL client interface required by the repository layer.
11
11
  *
12
- * - Production: adapt `pg` (or other drivers) to normalize results into `T[]`
13
- * - Tests: compatible with `pg-testkit` clients returned by `createTestkitClient()`
12
+ * - Production: adapt this interface to your preferred driver (pg, mysql2, etc.) and normalize the results to `T[]`.
13
+ * - Tests: replace the implementation with a mock, a fixture helper, or an adapter that follows this contract.
14
14
  *
15
15
  * Connection strategy note:
16
- * - Prefer a shared client per worker process for performance.
17
- * - Do not share a live client across parallel workers.
16
+ * - Prefer a shared client per worker process for better performance.
17
+ * - Do not share a live client across parallel workers without proper synchronization.
18
18
  */
19
19
  export type SqlClient = {
20
20
  query<T extends Record<string, unknown> = Record<string, unknown>>(
21
21
  text: string,
22
- values?: readonly unknown[]
22
+ values?: readonly unknown[] | Record<string, unknown>
23
23
  ): SqlQueryRows<T>;
24
24
  };
@@ -0,0 +1,26 @@
1
+ # src/jobs AGENTS
2
+
3
+ This folder contains script-like operations (procedural SQL execution).
4
+
5
+ ## Scope
6
+
7
+ - Maintenance jobs
8
+ - Data backfills
9
+ - Batch operations
10
+ - Temporary-table driven workflows
11
+
12
+ ## Safety rules
13
+
14
+ - Be explicit about transaction boundaries.
15
+ - Prefer idempotent design (safe to rerun).
16
+ - Emit clear logs/events at start and end of the job.
17
+
18
+ ## SQL usage
19
+
20
+ - It is acceptable to run multiple statements in a job (including temp tables).
21
+ - Avoid coupling job logic to tests-only helpers.
22
+
23
+ ## Testing
24
+
25
+ - Prefer integration-style tests that verify observable outcomes.
26
+ - If the job is heavy, test smaller units or use fixtures to limit scope.
@@ -0,0 +1,3 @@
1
+ # Jobs
2
+
3
+ Job runners that orchestrate repository or SQL workflows.
@@ -0,0 +1,118 @@
1
+ # src/repositories AGENTS
2
+
3
+ This directory contains repository implementations.
4
+
5
+ ## Runtime classification
6
+
7
+ - This is a runtime directory.
8
+ - Code here is executed by the application.
9
+
10
+ ## Responsibilities
11
+
12
+ Repositories orchestrate execution only.
13
+
14
+ They are responsible for:
15
+ - loading SQL assets from `src/sql`
16
+ - validating external inputs via catalog runtime
17
+ - binding parameters
18
+ - calling `SqlClient`
19
+ - mapping SQL rows to DTOs via catalog runtime
20
+ - returning application-facing results
21
+
22
+ Repositories MUST remain thin adapters over SQL.
23
+
24
+ Repositories MUST NOT:
25
+ - embed business rules
26
+ - infer schema or DTO structure
27
+ - compensate for driver limitations with extra queries
28
+
29
+ ## Contract boundaries (important)
30
+
31
+ - Human-owned contracts live under "src/catalog/specs".
32
+ - Runtime normalization and validation live under "src/catalog/runtime".
33
+ - Repositories MUST NOT invent, infer, or modify contracts.
34
+
35
+ If a contract is insufficient, update the spec/runtime first.
36
+
37
+ ## Mandatory runtime usage (required)
38
+
39
+ Repositories MUST use catalog runtime helpers:
40
+ - `ensure*Params` for all external inputs (`unknown -> typed`)
41
+ - `map*RowToDto` for row-to-DTO mapping and output validation
42
+
43
+ Repositories MUST NOT:
44
+ - call spec validators directly
45
+ - bypass runtime normalization
46
+ - return DTOs without runtime validation
47
+ - assume driver-specific runtime types (e.g. timestamps always `Date`)
48
+
49
+ ## SQL rules
50
+
51
+ - SQL assets MUST remain DTO-independent.
52
+ - SQL files MUST use snake_case column names.
53
+ - Repositories MUST NOT push DTO aliasing into SQL.
54
+ - Inline SQL strings are forbidden.
55
+ - Repository SQL loading MUST be centralized in shared runtime/repository infrastructure.
56
+ - Repositories MUST reference SQL assets by stable logical key (example: `user/insert_user.sql`).
57
+ - Repository modules MUST NOT pass caller-relative paths (`./`, `../`) or absolute filesystem paths to SQL loaders.
58
+ - The shared loader MUST resolve logical keys against the `src/sql` root (or catalog SQL registry), never relative to the caller file location.
59
+ - Repository modules MUST NOT implement ad-hoc SQL file loading with `readFileSync`, `__dirname`, `import.meta.url`, or direct path resolution.
60
+
61
+ ## CUD default policy (important)
62
+
63
+ Default policy for table-oriented CUD is:
64
+ - CREATE SQL MAY use `RETURNING` for identifier columns only.
65
+ - CREATE repository methods MUST return the generated identifier by default.
66
+ - CREATE repository methods MUST NOT perform a follow-up SELECT whose purpose is DTO return shaping.
67
+ - UPDATE/DELETE SQL MUST NOT use `RETURNING`.
68
+ - repositories do NOT perform follow-up SELECTs after UPDATE/DELETE.
69
+ - UPDATE/DELETE methods return `Promise<void>` by default.
70
+
71
+ If a CREATE method must return a DTO, that requirement MUST be explicitly declared in catalog specs by human instruction.
72
+
73
+ ## CUD row count rules (non-negotiable)
74
+
75
+ - UPDATE and DELETE MUST rely on driver-reported affected row counts (`rowCount` or equivalent).
76
+ - Repositories MUST NOT use SQL `RETURNING` result presence/count as a substitute for affected row counts.
77
+ - Repositories MUST NOT emulate affected rows using:
78
+ - pre-check SELECT
79
+ - post-check SELECT
80
+ - retry loops
81
+ - shadow queries / CTE hacks
82
+
83
+ If `rowCount === 0`, repositories MUST throw an explicit error.
84
+
85
+ If the driver cannot report affected row counts:
86
+ - CUD verification is unsupported
87
+ - tests MUST fail fast
88
+ - do NOT add workaround logic in repositories
89
+
90
+ ## Read (SELECT) rules
91
+
92
+ - SELECT methods may return:
93
+ - `T | null` for single-row queries
94
+ - `T[]` for multi-row queries
95
+ - Absence of rows is NOT an error unless specified by the contract.
96
+
97
+ ## Error behavior
98
+
99
+ - Propagate validation errors as failures.
100
+ - Do not silently coerce invalid data.
101
+ - Error messages SHOULD include operation name and identifying parameters.
102
+
103
+ ## Testing expectations
104
+
105
+ - Every public repository method MUST be covered by tests.
106
+ - Update/Delete tests MUST verify rowCount handling explicitly.
107
+ - Repository changes without tests are incomplete.
108
+
109
+ ## Guiding principle
110
+
111
+ Repositories execute contracts.
112
+ They do not interpret intent.
113
+
114
+ If correctness depends on extra queries to "confirm" changes:
115
+ - the contract is wrong
116
+ - or the driver is unsupported
117
+
118
+ Fix the contract, not the repository.
@@ -0,0 +1,94 @@
1
+ # src/repositories/tables AGENTS
2
+
3
+ This directory contains simple CRUD-style repositories.
4
+
5
+ ## Runtime classification
6
+
7
+ - This is a runtime directory.
8
+ - Code here executes SQL and returns application-facing results.
9
+
10
+ ## Responsibilities
11
+
12
+ - Execute SQL assets using defined contracts.
13
+ - Perform explicit mapping from SQL rows to DTOs.
14
+ - Enforce CUD semantics at the application boundary (including "0 rows" handling).
15
+
16
+ ## Contract ownership (important)
17
+
18
+ - Input parameter types and DTO shapes are defined in specs ("src/catalog/specs").
19
+ - Repositories MUST NOT invent or modify contracts.
20
+ - Repositories may adapt SQL results into DTOs, but must not redefine the contract.
21
+
22
+ ## SQL usage rules (tables CRUD quality bar)
23
+
24
+ - Repositories in this folder MUST treat SQL assets as human-maintained, idiomatic SQL.
25
+ - Do not require SQL assets to implement driver-specific behaviors.
26
+ - If a driver does not provide affected-row counts for UPDATE/DELETE, fail fast as unsupported.
27
+
28
+ Examples:
29
+ - Prefer a plain UPDATE statement in SQL.
30
+ - Do not force SQL to return `affected_count` via CTE tricks.
31
+
32
+ ## CUD behavior rules
33
+
34
+ ### CREATE (INSERT)
35
+
36
+ Default:
37
+ - SQL MUST use `insert ... returning <primary_key>` when a generated key is needed.
38
+ - Repository CREATE MUST return identifier only (scalar) per contract.
39
+ - Repository CREATE MUST NOT perform a follow-up SELECT for DTO return shaping.
40
+ - SQL MUST NOT return full rows or DTO-shaped payloads.
41
+
42
+ Exception:
43
+ - If a CREATE endpoint must return DTO, the spec MUST explicitly require it by human instruction.
44
+ - Without that explicit contract, identifier-only return is mandatory.
45
+
46
+ ### UPDATE
47
+
48
+ Default:
49
+ - SQL: plain UPDATE without RETURNING.
50
+ - Repository: determine success by affected row count when available.
51
+
52
+ Driver variability handling:
53
+ - If affected row count is unavailable:
54
+ - Treat UPDATE verification as unsupported for that driver/runtime.
55
+ - Throw an explicit error.
56
+ - Do not add fallback checks or workaround logic in repositories.
57
+ - Do not push this variability down into SQL assets.
58
+
59
+ 0-row rule (important):
60
+ - Treat "0 rows updated" as a meaningful condition.
61
+ - Default behavior is to surface it clearly (often an error), per spec.
62
+
63
+ ### DELETE
64
+
65
+ Default:
66
+ - SQL: plain DELETE without RETURNING.
67
+ - Repository: determine success by affected row count when available.
68
+
69
+ Driver variability handling:
70
+ - If affected row count is unavailable:
71
+ - Treat DELETE verification as unsupported for that driver/runtime.
72
+ - Throw an explicit error.
73
+ - Do not add fallback checks or workaround logic in repositories.
74
+
75
+ 0-row rule (important):
76
+ - Treat "0 rows deleted" as a meaningful condition, per spec.
77
+
78
+ ## Patch updates (important)
79
+
80
+ - Avoid ambiguous patterns such as `coalesce(param, column)` by default.
81
+ - Contracts should distinguish:
82
+ - "not provided"
83
+ - "explicitly set to null"
84
+ - If patch semantics are needed, implement them explicitly via:
85
+ - separate SQL variants, or
86
+ - explicit contract types that preserve intent.
87
+
88
+ ## Testing rule (required)
89
+
90
+ - Every public repository method MUST be covered by tests.
91
+ - Tests should verify:
92
+ - correct mapping behavior
93
+ - correct "0 rows" behavior for UPDATE/DELETE
94
+ - correct error surfaces (do not silently succeed)
@@ -0,0 +1,3 @@
1
+ # Table Repositories
2
+
3
+ Write-focused repositories that execute CRUD SQL from `src/sql`.
@@ -0,0 +1,25 @@
1
+ # src/repositories/views AGENTS
2
+
3
+ This folder is for complex read-only queries.
4
+
5
+ ## Scope
6
+
7
+ - Complex SELECT queries (joins, aggregations, window functions).
8
+ - Read models that are not 1:1 with a single table.
9
+
10
+ ## Allowed
11
+
12
+ - Multi-table joins and aggregations.
13
+ - Purpose-built DTOs for read models.
14
+ - Validation at the boundary (catalog validator or repository-level validator).
15
+
16
+ ## Forbidden
17
+
18
+ - INSERT/UPDATE/DELETE in this folder by default.
19
+ - Hidden write side-effects.
20
+
21
+ ## Guidance
22
+
23
+ - Keep query intent clear in naming.
24
+ - Document cardinality assumptions (one, many, optional).
25
+ - Prefer stable ordering if tests rely on order.
@@ -0,0 +1,3 @@
1
+ # View Repositories
2
+
3
+ Read-only repositories backed by SELECT SQL in `src/sql`.