declapract-typescript-ehmpathy 0.49.11 → 0.49.13

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 (752) hide show
  1. package/dist/.test/assets/cache/declarations/practices/cache/.declapract.integration.test.ts +4 -4
  2. package/dist/.test/assets/cache/declarations/practices/cache/.test/assets/repo-with-valid-cache-package/package.json +1 -1
  3. package/dist/.test/assets/cache/declarations/practices/cache/best-practice/package.json +3 -3
  4. package/dist/.test/assets/cicd-service/declarations/declapract.declare.yml +9 -0
  5. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/.declapract.integration.test.ts +175 -0
  6. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/.test/assets/demo-repo-pre-stamped-nords/.github/workflows/provision.yml +110 -0
  7. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/.test/assets/demo-repo-pre-stamped-nords/declapract.use.nords.yml +20 -0
  8. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/.test/assets/demo-repo-pre-stamped-nords/declapract.use.rds.yml +20 -0
  9. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/.test/assets/demo-repo-pre-stamped-nords/package.json +4 -0
  10. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/.test/assets/demo-repo-service/declapract.use.nords.yml +20 -0
  11. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/.test/assets/demo-repo-service/declapract.use.rds.yml +20 -0
  12. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/.test/assets/demo-repo-service/package.json +4 -0
  13. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/__snapshots__/.declapract.integration.test.ts.snap +24 -0
  14. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/__snapshots__/acceptanceContempFleetGuard.declapract.integration.test.ts.snap +13 -0
  15. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/__snapshots__/insync-grep.declapract.integration.test.ts.snap +5 -0
  16. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/__snapshots__/provision.yml.declapract.integration.test.ts.snap +297 -0
  17. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/acceptanceContempFleetGuard.declapract.integration.test.ts +89 -0
  18. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/bad-practices/old-names/.github/workflows/deploy_dev_on_master.yml.declapract.ts +3 -0
  19. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/bad-practices/old-names/.github/workflows/deploy_on_tag.yml.declapract.ts +3 -0
  20. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/bad-practices/old-names/.github/workflows/deploy_prod_on_tag.yml.declapract.ts +3 -0
  21. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/bad-practices/rds-jobs-in-non-rds-service/.declapract.integration.test.ts +153 -0
  22. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/bad-practices/rds-jobs-in-non-rds-service/.declapract.readme.md +38 -0
  23. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/bad-practices/rds-jobs-in-non-rds-service/.github/workflows/provision.yml.declapract.integration.test.ts +167 -0
  24. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/bad-practices/rds-jobs-in-non-rds-service/.github/workflows/provision.yml.declapract.ts +88 -0
  25. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/bad-practices/rds-jobs-in-non-rds-service/.test/assets/repo-non-rds/readme.md +9 -0
  26. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/bad-practices/rds-jobs-in-non-rds-service/.test/assets/repo-with-aws-resources-callee/provision/aws/resources.ts +5 -0
  27. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/bad-practices/rds-jobs-in-non-rds-service/.test/assets/repo-with-schema-callee/provision/schema/init.sql +5 -0
  28. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/bad-practices/rds-jobs-in-non-rds-service/__snapshots__/.declapract.integration.test.ts.snap +183 -0
  29. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/best-practice/.declapract.readme.md +22 -0
  30. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/best-practice/.github/workflows/.deploy-sls.yml +163 -0
  31. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/best-practice/.github/workflows/.sql-schema-control.yml +154 -0
  32. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/best-practice/.github/workflows/.terraform.yml +118 -0
  33. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/best-practice/.github/workflows/deploy.yml +77 -0
  34. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/best-practice/.github/workflows/deploy.yml.declapract.ts +15 -0
  35. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/best-practice/.github/workflows/provision.yml +110 -0
  36. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/best-practice/.github/workflows/provision.yml.declapract.ts +74 -0
  37. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/best-practice/package.json +7 -0
  38. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/insync-grep.declapract.integration.test.ts +76 -0
  39. package/dist/.test/assets/cicd-service/declarations/practices/cicd-service/provision.yml.declapract.integration.test.ts +182 -0
  40. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/.declapract.integration.test.ts +224 -0
  41. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/.extensions.sql.declapract.integration.test.ts +38 -0
  42. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/.test/assets/demo-repo-with-dev-config/config/dev.json +18 -0
  43. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/.test/assets/demo-repo-with-dev-config/declapract.declare.yml +4 -0
  44. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/.test/assets/demo-repo-with-dev-config/declapract.use.yml +18 -0
  45. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/.test/assets/demo-repo-with-dev-config/package.json +4 -0
  46. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/__snapshots__/.declapract.integration.test.ts.snap +45 -0
  47. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/__snapshots__/.extensions.sql.declapract.integration.test.ts.snap +42 -0
  48. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/__snapshots__/deploy-database-gerunds.declapract.integration.test.ts.snap +102 -0
  49. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/__snapshots__/provision-testdb-access.declapract.integration.test.ts.snap +3 -0
  50. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/__snapshots__/ssm-cicd-param-names.declapract.integration.test.ts.snap +10 -0
  51. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/__snapshots__/testdb-preflight-failloud.declapract.integration.test.ts.snap +30 -0
  52. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/non-prefixed-manual-init-sqls/provision/schema/sql/init/database.sql.declapract.ts +3 -0
  53. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/non-prefixed-manual-init-sqls/provision/schema/sql/init/extensions.sql.declapract.ts +13 -0
  54. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/non-prefixed-manual-init-sqls/provision/schema/sql/init/schema.sql.declapract.ts +3 -0
  55. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/non-prefixed-manual-init-sqls/provision/schema/sql/init/user.cicd.sql.declapract.ts +3 -0
  56. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/non-prefixed-manual-init-sqls/provision/schema/sql/init/user.datalakedb.sql.declapract.ts +3 -0
  57. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/non-prefixed-manual-init-sqls/readme.md +5 -0
  58. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/old-config-file-names/codegen.sql.yml.declapract.ts +3 -0
  59. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/old-dev-config-location/config/dev.json.declapract.ts +33 -0
  60. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/old-integration-test-db-dir/.declapract.readme.md +1 -0
  61. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/old-integration-test-db-dir/provision/docker/integration_test_db/<star><star>/<star>.declapract.ts +15 -0
  62. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/old-integration-test-db-hyphen-dir/.declapract.readme.md +1 -0
  63. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/old-integration-test-db-hyphen-dir/provision/docker/integration-test-db/<star><star>/<star>.declapract.ts +15 -0
  64. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/old-integration-test-db-paths/.declapract.readme.md +1 -0
  65. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/old-integration-test-db-paths/package.json +8 -0
  66. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/old-integration-test-db-paths/package.json.declapract.ts +10 -0
  67. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/old-packagejson-script-names/package.json +9 -0
  68. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/old-packagejson-script-names/package.json.declapract.ts +22 -0
  69. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/old-param-placeholder/config/<star>.json.declapract.ts +14 -0
  70. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/schema-entities-dir/.declapract.readme.md +1 -0
  71. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/schema-entities-dir/provision/schema/entities/<star>.ts.declapract.ts +12 -0
  72. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/schema-entities-dir/provision/schema/sql/entities.yml.declapract.ts +13 -0
  73. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/terraform-parameters/.declapract.integration.test.ts +88 -0
  74. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/terraform-parameters/.test/assets/demo-repo-with-terraform-ssm/declapract.declare.yml +4 -0
  75. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/terraform-parameters/.test/assets/demo-repo-with-terraform-ssm/declapract.use.yml +18 -0
  76. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/terraform-parameters/.test/assets/demo-repo-with-terraform-ssm/package.json +4 -0
  77. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/terraform-parameters/.test/assets/demo-repo-with-terraform-ssm/provision/aws/product/parameter-store.tf +23 -0
  78. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/terraform-parameters/__snapshots__/.declapract.integration.test.ts.snap +44 -0
  79. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/terraform-parameters/provision/aws/product/parameter-store.tf.declapract.ts +55 -0
  80. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/with-connection-in-input/.declapract.readme.md +1 -0
  81. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/bad-practices/with-connection-in-input/src/utils/database/withDatabaseConnection.ts +3 -0
  82. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/.declapract.readme.md +58 -0
  83. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/codegen.sql.dao.yml +18 -0
  84. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/codegen.sql.dao.yml.declapract.ts +3 -0
  85. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/codegen.sql.schema.yml +6 -0
  86. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/codegen.sql.types.yml +16 -0
  87. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/config/prep.json +36 -0
  88. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/config/prep.json.declapract.ts +15 -0
  89. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/config/prod.json +36 -0
  90. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/config/prod.json.declapract.ts +15 -0
  91. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/config/test.json +33 -0
  92. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/config/test.json.declapract.ts +15 -0
  93. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/package.json +30 -0
  94. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/package.json.declapract.ts +3 -0
  95. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/provision/aws/readme.md +79 -0
  96. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/provision/aws/resources.parameters.ts +106 -0
  97. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/provision/aws/resources.ts +30 -0
  98. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/provision/docker/testdb/build-image.dockerfile +7 -0
  99. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/provision/docker/testdb/docker-compose.yml +18 -0
  100. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/provision/docker/testdb/init/.gitignore +3 -0
  101. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/provision/docker/testdb/init/readme.md +3 -0
  102. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/provision/docker/testdb/wait-for-postgres.sh +25 -0
  103. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/provision/schema/connection.config.js +29 -0
  104. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/provision/schema/control.yml +7 -0
  105. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/provision/schema/deploy.database.sh +97 -0
  106. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/provision/schema/sql/init/.database.sql +10 -0
  107. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/provision/schema/sql/init/.extensions.sql +16 -0
  108. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/provision/schema/sql/init/.extensions.sql.declapract.ts +37 -0
  109. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/provision/schema/sql/init/.schema.sql +11 -0
  110. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/provision/schema/sql/init/.user.cicd.sql +14 -0
  111. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/provision/schema/sql/init/.user.datalakedb.sql +12 -0
  112. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/provision/schema/sql/init/default_transaction_isolation.sql +6 -0
  113. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/provision/schema/sql/init/user.service.sql +16 -0
  114. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/provision/schema/sql/init.yml +9 -0
  115. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/provision/schema/sql/init.yml.declapract.ts +3 -0
  116. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/src/utils/config/config.schema.ts +110 -0
  117. package/dist/{practices/persist-with-rds/best-practice/src/utils/database/getDatabaseConnection.integration.test.ts → .test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/src/utils/database/getOneDatabaseConnection.integration.test.ts} +3 -3
  118. package/dist/{practices/persist-with-rds/best-practice/src/utils/database/getDatabaseConnection.ts → .test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/src/utils/database/getOneDatabaseConnection.ts} +1 -1
  119. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/src/utils/database/withDatabaseContext.ts +53 -0
  120. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/best-practice/src/utils/database/withDatabaseTransaction.ts +33 -0
  121. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/deploy-database-gerunds.declapract.integration.test.ts +57 -0
  122. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/empty-template-declares-zero-clusters.declapract.integration.test.ts +71 -0
  123. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/provision-testdb-access.declapract.integration.test.ts +50 -0
  124. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/ssm-cicd-param-names.declapract.integration.test.ts +73 -0
  125. package/dist/.test/assets/cicd-service/declarations/practices/persist-with-rds/testdb-preflight-failloud.declapract.integration.test.ts +83 -0
  126. package/dist/.test/assets/cicd-service/declarations/useCases.yml +13 -0
  127. package/dist/.test/assets/environments/declarations/declapract.declare.yml +4 -0
  128. package/dist/.test/assets/environments/declarations/practices/environments/.declapract.integration.test.ts +136 -0
  129. package/dist/.test/assets/environments/declarations/practices/environments/__snapshots__/.declapract.integration.test.ts.snap +55 -0
  130. package/dist/.test/assets/environments/declarations/practices/environments/bad-practices/old-dev-scripts/package.json.declapract.ts +59 -0
  131. package/dist/.test/assets/environments/declarations/practices/environments/bad-practices/old-stage-enum/.declapract.integration.test.ts +133 -0
  132. package/dist/.test/assets/environments/declarations/practices/environments/bad-practices/old-stage-enum/.test/assets/demo-repo-with-stage-enum/declapract.use.yml +8 -0
  133. package/dist/.test/assets/environments/declarations/practices/environments/bad-practices/old-stage-enum/.test/assets/demo-repo-with-stage-enum/package.json +4 -0
  134. package/dist/.test/assets/environments/declarations/practices/environments/bad-practices/old-stage-enum/.test/assets/demo-repo-with-stage-enum/src/logic/getDeployTarget.ts +15 -0
  135. package/dist/.test/assets/environments/declarations/practices/environments/bad-practices/old-stage-enum/__snapshots__/.declapract.integration.test.ts.snap +40 -0
  136. package/dist/.test/assets/environments/declarations/practices/environments/bad-practices/old-stage-enum/src/<star><star>/<star>.ts.declapract.ts +304 -0
  137. package/dist/.test/assets/environments/declarations/practices/environments/best-practice/.declapract.readme.md +61 -0
  138. package/dist/.test/assets/environments/declarations/practices/environments/best-practice/package.json +7 -0
  139. package/dist/.test/assets/environments/declarations/practices/environments/best-practice/package.json.declapract.ts +3 -0
  140. package/dist/.test/assets/environments/declarations/practices/environments/best-practice/src/access/sdks/sdkAwsLambdaEnvAccessAncient.ts +32 -0
  141. package/dist/.test/assets/environments/declarations/practices/environments/best-practice/src/access/sdks/sdkAwsLambdaEnvAccessContemp.ts +14 -0
  142. package/dist/.test/assets/environments/declarations/practices/environments/best-practice/src/utils/environment.ts +9 -0
  143. package/dist/.test/assets/environments/declarations/useCases.yml +5 -0
  144. package/dist/.test/assets/expo/declarations/practices/cicd-app-react-native-expo/.declapract.integration.test.ts +122 -22
  145. package/dist/.test/assets/expo/declarations/practices/cicd-app-react-native-expo/__snapshots__/.declapract.integration.test.ts.snap +40 -29
  146. package/dist/.test/assets/expo/declarations/practices/cicd-app-react-native-expo/best-practice/.github/workflows/.deploy-expo.yml +16 -6
  147. package/dist/.test/assets/expo/declarations/practices/cicd-app-react-native-expo/best-practice/.github/workflows/deploy.yml +11 -11
  148. package/dist/.test/assets/expo/declarations/practices/cicd-app-react-native-expo/best-practice/.github/workflows/test.yml +3 -5
  149. package/dist/.test/assets/expo/declarations/practices/cicd-app-react-native-expo/best-practice/package.json +2 -2
  150. package/dist/.test/assets/expo/declarations/practices/node/bad-practices/self-deps-not-link/.declapract.integration.test.ts +102 -0
  151. package/dist/.test/assets/expo/declarations/practices/node/bad-practices/self-deps-not-link/.test/assets/demo-repo-with-self-deps/declapract.declare.yml +4 -0
  152. package/dist/.test/assets/expo/declarations/practices/node/bad-practices/self-deps-not-link/.test/assets/demo-repo-with-self-deps/declapract.use.yml +8 -0
  153. package/dist/.test/assets/expo/declarations/practices/node/bad-practices/self-deps-not-link/.test/assets/demo-repo-with-self-deps/package.json +15 -0
  154. package/dist/.test/assets/expo/declarations/practices/node/bad-practices/self-deps-not-link/__snapshots__/.declapract.integration.test.ts.snap +46 -0
  155. package/dist/.test/assets/expo/declarations/practices/node/bad-practices/self-deps-not-link/package.json.declapract.ts +22 -29
  156. package/dist/.test/assets/expo/declarations/practices/node/best-practice/.npmrc.declapract.ts +5 -1
  157. package/dist/.test/assets/expo/declarations/practices/node/best-practice/package.json +1 -1
  158. package/dist/.test/assets/expo-fullusecase/declarations/practices/cache/.declapract.integration.test.ts +4 -4
  159. package/dist/.test/assets/expo-fullusecase/declarations/practices/cache/.test/assets/repo-with-valid-cache-package/package.json +1 -1
  160. package/dist/.test/assets/expo-fullusecase/declarations/practices/cache/best-practice/package.json +3 -3
  161. package/dist/.test/assets/expo-fullusecase/declarations/practices/cicd-app-react-native-expo/.declapract.integration.test.ts +122 -22
  162. package/dist/.test/assets/expo-fullusecase/declarations/practices/cicd-app-react-native-expo/__snapshots__/.declapract.integration.test.ts.snap +40 -29
  163. package/dist/.test/assets/expo-fullusecase/declarations/practices/cicd-app-react-native-expo/best-practice/.github/workflows/.deploy-expo.yml +16 -6
  164. package/dist/.test/assets/expo-fullusecase/declarations/practices/cicd-app-react-native-expo/best-practice/.github/workflows/deploy.yml +11 -11
  165. package/dist/.test/assets/expo-fullusecase/declarations/practices/cicd-app-react-native-expo/best-practice/.github/workflows/test.yml +3 -5
  166. package/dist/.test/assets/expo-fullusecase/declarations/practices/cicd-app-react-native-expo/best-practice/package.json +2 -2
  167. package/dist/.test/assets/expo-fullusecase/declarations/practices/cicd-common/.declapract.integration.test.ts +25 -0
  168. package/dist/.test/assets/expo-fullusecase/declarations/practices/cicd-common/__snapshots__/.declapract.integration.test.ts.snap +11 -23
  169. package/dist/.test/assets/expo-fullusecase/declarations/practices/cicd-common/__snapshots__/declastruct-insync-grep.declapract.integration.test.ts.snap +3 -0
  170. package/dist/.test/assets/expo-fullusecase/declarations/practices/cicd-common/best-practice/.github/workflows/.declastruct.yml +22 -8
  171. package/dist/.test/assets/expo-fullusecase/declarations/practices/cicd-common/best-practice/.github/workflows/.test.yml +11 -23
  172. package/dist/.test/assets/expo-fullusecase/declarations/practices/cicd-common/best-practice/.github/workflows/.test.yml.declapract.ts +12 -1
  173. package/dist/.test/assets/expo-fullusecase/declarations/practices/cicd-common/best-practice/.github/workflows/report-slow-tests.sh +65 -0
  174. package/dist/.test/assets/expo-fullusecase/declarations/practices/cicd-common/declastruct-insync-grep.declapract.integration.test.ts +49 -0
  175. package/dist/.test/assets/expo-fullusecase/declarations/practices/cicd-common/report-slow-tests.play.declapract.integration.test.ts +144 -0
  176. package/dist/.test/assets/expo-fullusecase/declarations/practices/conventional-commits/__snapshots__/commitlint-body-max-line.declapract.integration.test.ts.snap +3 -0
  177. package/dist/.test/assets/expo-fullusecase/declarations/practices/conventional-commits/best-practice/commitlint.config.js +5 -0
  178. package/dist/.test/assets/expo-fullusecase/declarations/practices/conventional-commits/best-practice/package.json +1 -1
  179. package/dist/.test/assets/expo-fullusecase/declarations/practices/conventional-commits/commitlint-body-max-line.declapract.integration.test.ts +49 -0
  180. package/dist/.test/assets/expo-fullusecase/declarations/practices/domain/.declapract.integration.test.ts +115 -0
  181. package/dist/.test/assets/expo-fullusecase/declarations/practices/domain/bad-practices/schematic-joi-model/src/{domain → domain.objects}/<star><star>/<star>.ts.declapract.ts +4 -1
  182. package/dist/.test/assets/expo-fullusecase/declarations/practices/domain/best-practice/package.json +2 -2
  183. package/dist/.test/assets/expo-fullusecase/declarations/practices/domain/best-practice/src/domain.objects/index.ts.declapract.ts +12 -0
  184. package/dist/.test/assets/expo-fullusecase/declarations/practices/errors/.declapract.integration.test.ts +121 -0
  185. package/dist/.test/assets/expo-fullusecase/declarations/practices/errors/bad-practices/own-implementation/src/<star><star>/UnexpectedCodePathError.ts.declapract.ts +8 -0
  186. package/dist/.test/assets/expo-fullusecase/declarations/practices/errors/best-practice/package.json +1 -1
  187. package/dist/.test/assets/expo-fullusecase/declarations/practices/format/.declapract.integration.test.ts +131 -0
  188. package/dist/.test/assets/expo-fullusecase/declarations/practices/format/__snapshots__/.declapract.integration.test.ts.snap +17 -0
  189. package/dist/.test/assets/expo-fullusecase/declarations/practices/format/bad-practices/prettier/prettier.config.js.declapract.ts +1 -1
  190. package/dist/.test/assets/expo-fullusecase/declarations/practices/format/best-practice/package.json.declapract.ts +36 -18
  191. package/dist/.test/assets/expo-fullusecase/declarations/practices/git/.declapract.integration.test.ts +57 -6
  192. package/dist/.test/assets/expo-fullusecase/declarations/practices/git/__snapshots__/.declapract.integration.test.ts.snap +2 -0
  193. package/dist/.test/assets/expo-fullusecase/declarations/practices/git/best-practice/.gitattributes.declapract.ts +50 -37
  194. package/dist/.test/assets/expo-fullusecase/declarations/practices/git/best-practice/.gitignore.declapract.ts +8 -0
  195. package/dist/.test/assets/expo-fullusecase/declarations/practices/husky/__snapshots__/check.timestamps.play.declapract.integration.test.ts.snap +7 -0
  196. package/dist/.test/assets/expo-fullusecase/declarations/practices/husky/best-practice/.husky/check.timestamps.sh +11 -2
  197. package/dist/.test/assets/expo-fullusecase/declarations/practices/husky/check.timestamps.play.declapract.integration.test.ts +65 -0
  198. package/dist/.test/assets/expo-fullusecase/declarations/practices/lint/__snapshots__/dpdmrc-exclude-policy.declapract.integration.test.ts.snap +3 -0
  199. package/dist/.test/assets/expo-fullusecase/declarations/practices/lint/bad-practices/depcheck-denylisted-ignores/.depcheckrc.yml.declapract.ts +4 -0
  200. package/dist/.test/assets/expo-fullusecase/declarations/practices/lint/best-practice/.depcheckrc.yml.declapract.ts +10 -9
  201. package/dist/.test/assets/expo-fullusecase/declarations/practices/lint/best-practice/.dpdmrc.yaml +10 -6
  202. package/dist/.test/assets/expo-fullusecase/declarations/practices/lint/dpdmrc-exclude-policy.declapract.integration.test.ts +50 -0
  203. package/dist/.test/assets/expo-fullusecase/declarations/practices/node/bad-practices/self-deps-not-link/.declapract.integration.test.ts +102 -0
  204. package/dist/.test/assets/expo-fullusecase/declarations/practices/node/bad-practices/self-deps-not-link/.test/assets/demo-repo-with-self-deps/declapract.declare.yml +4 -0
  205. package/dist/.test/assets/expo-fullusecase/declarations/practices/node/bad-practices/self-deps-not-link/.test/assets/demo-repo-with-self-deps/declapract.use.yml +8 -0
  206. package/dist/.test/assets/expo-fullusecase/declarations/practices/node/bad-practices/self-deps-not-link/.test/assets/demo-repo-with-self-deps/package.json +15 -0
  207. package/dist/.test/assets/expo-fullusecase/declarations/practices/node/bad-practices/self-deps-not-link/__snapshots__/.declapract.integration.test.ts.snap +46 -0
  208. package/dist/.test/assets/expo-fullusecase/declarations/practices/node/bad-practices/self-deps-not-link/package.json.declapract.ts +22 -29
  209. package/dist/.test/assets/expo-fullusecase/declarations/practices/node/best-practice/.npmrc.declapract.ts +5 -1
  210. package/dist/.test/assets/expo-fullusecase/declarations/practices/node/best-practice/package.json +1 -1
  211. package/dist/.test/assets/expo-fullusecase/declarations/practices/package-json-order/best-practice/package.json.declapract.ts +7 -1
  212. package/dist/.test/assets/expo-fullusecase/declarations/practices/pnpm/.declapract.integration.test.ts +163 -13
  213. package/dist/.test/assets/expo-fullusecase/declarations/practices/pnpm/.test/assets/repo-npm-to-pnpm/package.json +1 -1
  214. package/dist/.test/assets/expo-fullusecase/declarations/practices/pnpm/.test/assets/repo-npm-to-pnpm/pnpm-workspace.yaml +3 -0
  215. package/dist/.test/assets/expo-fullusecase/declarations/practices/pnpm/__snapshots__/.declapract.integration.test.ts.snap +9 -2
  216. package/dist/.test/assets/expo-fullusecase/declarations/practices/pnpm/bad-practices/inert-build-allowlist/pnpm-workspace.yaml.declapract.ts +59 -0
  217. package/dist/.test/assets/expo-fullusecase/declarations/practices/pnpm/best-practice/.declapract.readme.md +1 -1
  218. package/dist/.test/assets/expo-fullusecase/declarations/practices/pnpm/best-practice/package.json +1 -1
  219. package/dist/.test/assets/expo-fullusecase/declarations/practices/pnpm/best-practice/package.json.declapract.ts +4 -2
  220. package/dist/.test/assets/expo-fullusecase/declarations/practices/provision-github/best-practice/package.json +2 -2
  221. package/dist/.test/assets/expo-fullusecase/declarations/practices/provision-github/best-practice/provision/github.repo/resources.ts +16 -0
  222. package/dist/.test/assets/expo-fullusecase/declarations/practices/rhachet/.declapract.integration.test.ts +98 -0
  223. package/dist/.test/assets/expo-fullusecase/declarations/practices/rhachet/.test/assets/demo-repo-with-consumer-boot/.agent/repo=.this/role=any/boot.yml +7 -0
  224. package/dist/.test/assets/expo-fullusecase/declarations/practices/rhachet/.test/assets/demo-repo-with-consumer-boot/declapract.declare.yml +4 -0
  225. package/dist/.test/assets/expo-fullusecase/declarations/practices/rhachet/.test/assets/demo-repo-with-consumer-boot/declapract.use.yml +2 -0
  226. package/dist/.test/assets/expo-fullusecase/declarations/practices/rhachet/.test/assets/demo-repo-with-consumer-boot/package.json +4 -0
  227. package/dist/.test/assets/expo-fullusecase/declarations/practices/rhachet/__snapshots__/.declapract.integration.test.ts.snap +45 -0
  228. package/dist/.test/assets/expo-fullusecase/declarations/practices/rhachet/__snapshots__/boot-refs-glossary.declapract.integration.test.ts.snap +6 -0
  229. package/dist/.test/assets/expo-fullusecase/declarations/practices/rhachet/__snapshots__/boot-yml-findsert.declapract.integration.test.ts.snap +27 -0
  230. package/dist/.test/assets/expo-fullusecase/declarations/practices/rhachet/bad-practices/prod-deps/.declapract.readme.md +6 -2
  231. package/dist/.test/assets/expo-fullusecase/declarations/practices/rhachet/bad-practices/prod-deps/.test/assets/demo-repo-with-rhachet-prod-deps/declapract.declare.yml +4 -0
  232. package/dist/.test/assets/expo-fullusecase/declarations/practices/rhachet/bad-practices/prod-deps/.test/assets/demo-repo-with-rhachet-prod-deps/declapract.use.yml +2 -0
  233. package/dist/.test/assets/expo-fullusecase/declarations/practices/rhachet/bad-practices/prod-deps/.test/assets/demo-repo-with-rhachet-prod-deps/package.json +12 -0
  234. package/dist/.test/assets/expo-fullusecase/declarations/practices/rhachet/bad-practices/prod-deps/package.json.declapract.ts +58 -17
  235. package/dist/.test/assets/expo-fullusecase/declarations/practices/rhachet/best-practice/.agent/repo=.this/role=any/boot.yml +46 -0
  236. package/dist/.test/assets/expo-fullusecase/declarations/practices/rhachet/best-practice/.agent/repo=.this/role=any/boot.yml.declapract.ts +165 -0
  237. package/dist/.test/assets/expo-fullusecase/declarations/practices/rhachet/best-practice/.gitignore.declapract.ts +18 -5
  238. package/dist/.test/assets/expo-fullusecase/declarations/practices/rhachet/best-practice/package.json +8 -8
  239. package/dist/.test/assets/expo-fullusecase/declarations/practices/rhachet/boot-refs-glossary.declapract.integration.test.ts +89 -0
  240. package/dist/.test/assets/expo-fullusecase/declarations/practices/rhachet/boot-yml-findsert.declapract.integration.test.ts +145 -0
  241. package/dist/.test/assets/expo-fullusecase/declarations/practices/tests-any/__snapshots__/changedsince-origin-main.declapract.integration.test.ts.snap +8 -0
  242. package/dist/.test/assets/expo-fullusecase/declarations/practices/tests-any/autoprune-hooks.declapract.integration.test.ts +104 -0
  243. package/dist/.test/assets/expo-fullusecase/declarations/practices/tests-any/bad-practices/old-acceptance-import-paths/.declapract.readme.md +2 -2
  244. package/dist/.test/assets/expo-fullusecase/declarations/practices/tests-any/bad-practices/old-acceptance-test-utils/blackbox/lambdas/<star>.ts.declapract.ts +9 -9
  245. package/dist/.test/assets/expo-fullusecase/declarations/practices/tests-any/best-practice/package.json +3 -3
  246. package/dist/.test/assets/expo-fullusecase/declarations/practices/tests-any/changedsince-origin-main.declapract.integration.test.ts +58 -0
  247. package/dist/.test/assets/expo-fullusecase/declarations/practices/tests-any/{best-practice/package.json.shell-flags.declapract.integration.test.ts → package.json.shell-flags.declapract.integration.test.ts} +26 -16
  248. package/dist/.test/assets/expo-fullusecase/declarations/practices/tests-expo/.declapract.integration.test.ts +7 -3
  249. package/dist/.test/assets/expo-fullusecase/declarations/practices/tests-expo/.test/assets/repo-expo-greenfield/package.json +5 -1
  250. package/dist/.test/assets/expo-fullusecase/declarations/practices/tests-expo/__snapshots__/.declapract.integration.test.ts.snap +17 -8
  251. package/dist/.test/assets/expo-fullusecase/declarations/practices/tests-expo/__snapshots__/package.json.declapract.integration.test.ts.snap +60 -0
  252. package/dist/.test/assets/expo-fullusecase/declarations/practices/tests-expo/best-practice/jest.acceptance.config.ts +5 -0
  253. package/dist/.test/assets/expo-fullusecase/declarations/practices/tests-expo/best-practice/jest.integration.config.ts +5 -0
  254. package/dist/.test/assets/expo-fullusecase/declarations/practices/tests-expo/best-practice/jest.integration.env.ts +5 -1
  255. package/dist/.test/assets/expo-fullusecase/declarations/practices/tests-expo/best-practice/jest.unit.config.ts +5 -0
  256. package/dist/.test/assets/expo-fullusecase/declarations/practices/tests-expo/best-practice/jest.unit.env.ts +6 -1
  257. package/dist/.test/assets/expo-fullusecase/declarations/practices/tests-expo/best-practice/package.json.declapract.ts +190 -13
  258. package/dist/.test/assets/expo-fullusecase/declarations/practices/tests-expo/package.json.declapract.integration.test.ts +94 -0
  259. package/dist/.test/assets/expo-fullusecase/declarations/practices/typescript-expo/__snapshots__/package.json.declapract.integration.test.ts.snap +8 -0
  260. package/dist/.test/assets/expo-fullusecase/declarations/practices/typescript-expo/__snapshots__/tsconfig.json.declapract.integration.test.ts.snap +19 -0
  261. package/dist/.test/assets/expo-fullusecase/declarations/practices/typescript-expo/{best-practice/package.json.declapract.integration.test.ts → package.json.declapract.integration.test.ts} +15 -2
  262. package/dist/.test/assets/{expo-toolchain/declarations/practices/typescript-expo/best-practice → expo-fullusecase/declarations/practices/typescript-expo}/tsconfig.json.declapract.integration.test.ts +13 -2
  263. package/dist/.test/assets/expo-migration/declarations/practices/cicd-app-react-native-expo/.declapract.integration.test.ts +122 -22
  264. package/dist/.test/assets/expo-migration/declarations/practices/cicd-app-react-native-expo/__snapshots__/.declapract.integration.test.ts.snap +40 -29
  265. package/dist/.test/assets/expo-migration/declarations/practices/cicd-app-react-native-expo/best-practice/.github/workflows/.deploy-expo.yml +16 -6
  266. package/dist/.test/assets/expo-migration/declarations/practices/cicd-app-react-native-expo/best-practice/.github/workflows/deploy.yml +11 -11
  267. package/dist/.test/assets/expo-migration/declarations/practices/cicd-app-react-native-expo/best-practice/.github/workflows/test.yml +3 -5
  268. package/dist/.test/assets/expo-migration/declarations/practices/cicd-app-react-native-expo/best-practice/package.json +2 -2
  269. package/dist/.test/assets/expo-migration/declarations/practices/domain/.declapract.integration.test.ts +115 -0
  270. package/dist/{practices/domain/bad-practices/schematic-joi-model/src/domain → .test/assets/expo-migration/declarations/practices/domain/bad-practices/schematic-joi-model/src/domain.objects}/<star><star>/<star>.ts.declapract.ts +4 -1
  271. package/dist/.test/assets/expo-migration/declarations/practices/domain/best-practice/package.json +2 -2
  272. package/dist/.test/assets/expo-migration/declarations/practices/domain/best-practice/src/domain.objects/index.ts.declapract.ts +12 -0
  273. package/dist/.test/assets/expo-migration/declarations/practices/git/.declapract.integration.test.ts +57 -6
  274. package/dist/.test/assets/expo-migration/declarations/practices/git/__snapshots__/.declapract.integration.test.ts.snap +2 -0
  275. package/dist/.test/assets/expo-migration/declarations/practices/git/best-practice/.gitattributes.declapract.ts +50 -37
  276. package/dist/.test/assets/expo-migration/declarations/practices/git/best-practice/.gitignore.declapract.ts +8 -0
  277. package/dist/.test/assets/expo-migration/declarations/practices/node/bad-practices/self-deps-not-link/.declapract.integration.test.ts +102 -0
  278. package/dist/.test/assets/expo-migration/declarations/practices/node/bad-practices/self-deps-not-link/.test/assets/demo-repo-with-self-deps/declapract.declare.yml +4 -0
  279. package/dist/.test/assets/expo-migration/declarations/practices/node/bad-practices/self-deps-not-link/.test/assets/demo-repo-with-self-deps/declapract.use.yml +8 -0
  280. package/dist/.test/assets/expo-migration/declarations/practices/node/bad-practices/self-deps-not-link/.test/assets/demo-repo-with-self-deps/package.json +15 -0
  281. package/dist/.test/assets/expo-migration/declarations/practices/node/bad-practices/self-deps-not-link/__snapshots__/.declapract.integration.test.ts.snap +46 -0
  282. package/dist/.test/assets/expo-migration/declarations/practices/node/bad-practices/self-deps-not-link/package.json.declapract.ts +22 -29
  283. package/dist/.test/assets/expo-migration/declarations/practices/node/best-practice/.npmrc.declapract.ts +5 -1
  284. package/dist/.test/assets/expo-migration/declarations/practices/node/best-practice/package.json +1 -1
  285. package/dist/.test/assets/expo-migration/declarations/practices/pnpm/.declapract.integration.test.ts +163 -13
  286. package/dist/.test/assets/expo-migration/declarations/practices/pnpm/.test/assets/repo-npm-to-pnpm/package.json +1 -1
  287. package/dist/.test/assets/expo-migration/declarations/practices/pnpm/.test/assets/repo-npm-to-pnpm/pnpm-workspace.yaml +3 -0
  288. package/dist/.test/assets/expo-migration/declarations/practices/pnpm/__snapshots__/.declapract.integration.test.ts.snap +9 -2
  289. package/dist/.test/assets/expo-migration/declarations/practices/pnpm/bad-practices/inert-build-allowlist/pnpm-workspace.yaml.declapract.ts +59 -0
  290. package/dist/.test/assets/expo-migration/declarations/practices/pnpm/best-practice/.declapract.readme.md +1 -1
  291. package/dist/.test/assets/expo-migration/declarations/practices/pnpm/best-practice/package.json +1 -1
  292. package/dist/.test/assets/expo-migration/declarations/practices/pnpm/best-practice/package.json.declapract.ts +4 -2
  293. package/dist/.test/assets/expo-migration/declarations/practices/rhachet/.declapract.integration.test.ts +98 -0
  294. package/dist/.test/assets/expo-migration/declarations/practices/rhachet/.test/assets/demo-repo-with-consumer-boot/.agent/repo=.this/role=any/boot.yml +7 -0
  295. package/dist/.test/assets/expo-migration/declarations/practices/rhachet/.test/assets/demo-repo-with-consumer-boot/declapract.declare.yml +4 -0
  296. package/dist/.test/assets/expo-migration/declarations/practices/rhachet/.test/assets/demo-repo-with-consumer-boot/declapract.use.yml +2 -0
  297. package/dist/.test/assets/expo-migration/declarations/practices/rhachet/.test/assets/demo-repo-with-consumer-boot/package.json +4 -0
  298. package/dist/.test/assets/expo-migration/declarations/practices/rhachet/__snapshots__/.declapract.integration.test.ts.snap +45 -0
  299. package/dist/.test/assets/expo-migration/declarations/practices/rhachet/__snapshots__/boot-refs-glossary.declapract.integration.test.ts.snap +6 -0
  300. package/dist/.test/assets/expo-migration/declarations/practices/rhachet/__snapshots__/boot-yml-findsert.declapract.integration.test.ts.snap +27 -0
  301. package/dist/.test/assets/expo-migration/declarations/practices/rhachet/bad-practices/prod-deps/.declapract.readme.md +6 -2
  302. package/dist/.test/assets/expo-migration/declarations/practices/rhachet/bad-practices/prod-deps/.test/assets/demo-repo-with-rhachet-prod-deps/declapract.declare.yml +4 -0
  303. package/dist/.test/assets/expo-migration/declarations/practices/rhachet/bad-practices/prod-deps/.test/assets/demo-repo-with-rhachet-prod-deps/declapract.use.yml +2 -0
  304. package/dist/.test/assets/expo-migration/declarations/practices/rhachet/bad-practices/prod-deps/.test/assets/demo-repo-with-rhachet-prod-deps/package.json +12 -0
  305. package/dist/.test/assets/expo-migration/declarations/practices/rhachet/bad-practices/prod-deps/package.json.declapract.ts +58 -17
  306. package/dist/.test/assets/expo-migration/declarations/practices/rhachet/best-practice/.agent/repo=.this/role=any/boot.yml +46 -0
  307. package/dist/.test/assets/expo-migration/declarations/practices/rhachet/best-practice/.agent/repo=.this/role=any/boot.yml.declapract.ts +165 -0
  308. package/dist/.test/assets/expo-migration/declarations/practices/rhachet/best-practice/.gitignore.declapract.ts +18 -5
  309. package/dist/.test/assets/expo-migration/declarations/practices/rhachet/best-practice/package.json +8 -8
  310. package/dist/.test/assets/expo-migration/declarations/practices/rhachet/boot-refs-glossary.declapract.integration.test.ts +89 -0
  311. package/dist/.test/assets/expo-migration/declarations/practices/rhachet/boot-yml-findsert.declapract.integration.test.ts +145 -0
  312. package/dist/.test/assets/expo-migration/declarations/practices/tests-any/__snapshots__/changedsince-origin-main.declapract.integration.test.ts.snap +8 -0
  313. package/dist/.test/assets/expo-migration/declarations/practices/tests-any/autoprune-hooks.declapract.integration.test.ts +104 -0
  314. package/dist/.test/assets/expo-migration/declarations/practices/tests-any/bad-practices/old-acceptance-import-paths/.declapract.readme.md +2 -2
  315. package/dist/.test/assets/expo-migration/declarations/practices/tests-any/bad-practices/old-acceptance-test-utils/blackbox/lambdas/<star>.ts.declapract.ts +9 -9
  316. package/dist/.test/assets/expo-migration/declarations/practices/tests-any/best-practice/package.json +3 -3
  317. package/dist/.test/assets/expo-migration/declarations/practices/tests-any/changedsince-origin-main.declapract.integration.test.ts +58 -0
  318. package/dist/.test/assets/{expo-toolchain/declarations/practices/tests-any/best-practice → expo-migration/declarations/practices/tests-any}/package.json.shell-flags.declapract.integration.test.ts +26 -16
  319. package/dist/.test/assets/expo-migration/declarations/practices/tests-expo/.declapract.integration.test.ts +7 -3
  320. package/dist/.test/assets/expo-migration/declarations/practices/tests-expo/.test/assets/repo-expo-greenfield/package.json +5 -1
  321. package/dist/.test/assets/expo-migration/declarations/practices/tests-expo/__snapshots__/.declapract.integration.test.ts.snap +17 -8
  322. package/dist/.test/assets/expo-migration/declarations/practices/tests-expo/__snapshots__/package.json.declapract.integration.test.ts.snap +60 -0
  323. package/dist/.test/assets/expo-migration/declarations/practices/tests-expo/best-practice/jest.acceptance.config.ts +5 -0
  324. package/dist/.test/assets/expo-migration/declarations/practices/tests-expo/best-practice/jest.integration.config.ts +5 -0
  325. package/dist/.test/assets/expo-migration/declarations/practices/tests-expo/best-practice/jest.integration.env.ts +5 -1
  326. package/dist/.test/assets/expo-migration/declarations/practices/tests-expo/best-practice/jest.unit.config.ts +5 -0
  327. package/dist/.test/assets/expo-migration/declarations/practices/tests-expo/best-practice/jest.unit.env.ts +6 -1
  328. package/dist/.test/assets/expo-migration/declarations/practices/tests-expo/best-practice/package.json.declapract.ts +190 -13
  329. package/dist/.test/assets/expo-migration/declarations/practices/tests-expo/package.json.declapract.integration.test.ts +94 -0
  330. package/dist/.test/assets/expo-migration/declarations/practices/typescript-expo/__snapshots__/package.json.declapract.integration.test.ts.snap +8 -0
  331. package/dist/.test/assets/expo-migration/declarations/practices/typescript-expo/__snapshots__/tsconfig.json.declapract.integration.test.ts.snap +19 -0
  332. package/dist/.test/assets/{expo-toolchain/declarations/practices/typescript-expo/best-practice → expo-migration/declarations/practices/typescript-expo}/package.json.declapract.integration.test.ts +15 -2
  333. package/dist/.test/assets/{expo-fullusecase/declarations/practices/typescript-expo/best-practice → expo-migration/declarations/practices/typescript-expo}/tsconfig.json.declapract.integration.test.ts +13 -2
  334. package/dist/.test/assets/expo-migration/repo-app-protools-shaped/.github/workflows/.deploy-expo.yml +1 -1
  335. package/dist/.test/assets/expo-toolchain/declarations/practices/tests-any/__snapshots__/changedsince-origin-main.declapract.integration.test.ts.snap +8 -0
  336. package/dist/.test/assets/expo-toolchain/declarations/practices/tests-any/autoprune-hooks.declapract.integration.test.ts +104 -0
  337. package/dist/.test/assets/expo-toolchain/declarations/practices/tests-any/bad-practices/old-acceptance-import-paths/.declapract.readme.md +2 -2
  338. package/dist/.test/assets/expo-toolchain/declarations/practices/tests-any/bad-practices/old-acceptance-test-utils/blackbox/lambdas/<star>.ts.declapract.ts +9 -9
  339. package/dist/.test/assets/expo-toolchain/declarations/practices/tests-any/best-practice/package.json +3 -3
  340. package/dist/.test/assets/expo-toolchain/declarations/practices/tests-any/changedsince-origin-main.declapract.integration.test.ts +58 -0
  341. package/dist/.test/assets/{expo-migration/declarations/practices/tests-any/best-practice → expo-toolchain/declarations/practices/tests-any}/package.json.shell-flags.declapract.integration.test.ts +26 -16
  342. package/dist/.test/assets/expo-toolchain/declarations/practices/tests-expo/.declapract.integration.test.ts +7 -3
  343. package/dist/.test/assets/expo-toolchain/declarations/practices/tests-expo/.test/assets/repo-expo-greenfield/package.json +5 -1
  344. package/dist/.test/assets/expo-toolchain/declarations/practices/tests-expo/__snapshots__/.declapract.integration.test.ts.snap +17 -8
  345. package/dist/.test/assets/expo-toolchain/declarations/practices/tests-expo/__snapshots__/package.json.declapract.integration.test.ts.snap +60 -0
  346. package/dist/.test/assets/expo-toolchain/declarations/practices/tests-expo/best-practice/jest.acceptance.config.ts +5 -0
  347. package/dist/.test/assets/expo-toolchain/declarations/practices/tests-expo/best-practice/jest.integration.config.ts +5 -0
  348. package/dist/.test/assets/expo-toolchain/declarations/practices/tests-expo/best-practice/jest.integration.env.ts +5 -1
  349. package/dist/.test/assets/expo-toolchain/declarations/practices/tests-expo/best-practice/jest.unit.config.ts +5 -0
  350. package/dist/.test/assets/expo-toolchain/declarations/practices/tests-expo/best-practice/jest.unit.env.ts +6 -1
  351. package/dist/.test/assets/expo-toolchain/declarations/practices/tests-expo/best-practice/package.json.declapract.ts +190 -13
  352. package/dist/.test/assets/expo-toolchain/declarations/practices/tests-expo/package.json.declapract.integration.test.ts +94 -0
  353. package/dist/.test/assets/expo-toolchain/declarations/practices/typescript-expo/__snapshots__/package.json.declapract.integration.test.ts.snap +8 -0
  354. package/dist/.test/assets/expo-toolchain/declarations/practices/typescript-expo/__snapshots__/tsconfig.json.declapract.integration.test.ts.snap +19 -0
  355. package/dist/.test/assets/{expo-migration/declarations/practices/typescript-expo/best-practice → expo-toolchain/declarations/practices/typescript-expo}/package.json.declapract.integration.test.ts +15 -2
  356. package/dist/{practices/typescript-expo/best-practice → .test/assets/expo-toolchain/declarations/practices/typescript-expo}/tsconfig.json.declapract.integration.test.ts +13 -2
  357. package/dist/.test/assets/format/declarations/declapract.declare.yml +9 -0
  358. package/dist/.test/assets/format/declarations/practices/format/.declapract.integration.test.ts +131 -0
  359. package/dist/.test/assets/format/declarations/practices/format/__snapshots__/.declapract.integration.test.ts.snap +17 -0
  360. package/dist/.test/assets/format/declarations/practices/format/bad-practices/format-script/package.json.declapract.ts +26 -0
  361. package/dist/.test/assets/format/declarations/practices/format/bad-practices/prettier/.declapract.readme.md +6 -0
  362. package/dist/.test/assets/format/declarations/practices/format/bad-practices/prettier/.prettierignore +3 -0
  363. package/dist/.test/assets/format/declarations/practices/format/bad-practices/prettier/.prettierignore.declapract.ts +8 -0
  364. package/dist/.test/assets/format/declarations/practices/format/bad-practices/prettier/package.json +10 -0
  365. package/dist/.test/assets/format/declarations/practices/format/bad-practices/prettier/package.json.declapract.ts +35 -0
  366. package/dist/.test/assets/format/declarations/practices/format/bad-practices/prettier/prettier.config.js +10 -0
  367. package/dist/.test/assets/format/declarations/practices/format/bad-practices/prettier/prettier.config.js.declapract.ts +8 -0
  368. package/dist/.test/assets/format/declarations/practices/format/best-practice/package.json.declapract.ts +50 -0
  369. package/dist/.test/assets/format/declarations/practices/terraform-common/bad-practices/terraform-dir/.declapract.readme.md +8 -0
  370. package/dist/.test/assets/format/declarations/practices/terraform-common/bad-practices/terraform-dir/provision/terraform/<star><star>/<star>.declapract.ts +17 -0
  371. package/dist/.test/assets/format/declarations/practices/terraform-common/best-practice/.terraform-version +1 -0
  372. package/dist/.test/assets/format/declarations/practices/terraform-common/best-practice/package.json +6 -0
  373. package/dist/.test/assets/format/declarations/practices/terraform-common/best-practice/package.json.declapract.ts +3 -0
  374. package/dist/.test/assets/format/declarations/useCases.yml +13 -0
  375. package/dist/.test/assets/format/repo-with-terraform/declapract.use.yml +8 -0
  376. package/dist/.test/assets/format/repo-with-terraform/package.json +5 -0
  377. package/dist/.test/assets/format/repo-without-terraform/declapract.use.yml +6 -0
  378. package/dist/.test/assets/format/repo-without-terraform/package.json +5 -0
  379. package/dist/.test/assets/node-service/declarations/declapract.declare.yml +4 -0
  380. package/dist/.test/assets/node-service/declarations/practices/node-service/bad-practices/license/package.json.declapract.ts +22 -0
  381. package/dist/.test/assets/node-service/declarations/practices/node-service/bad-practices/simple-lambda-client/.declapract.readme.md +55 -0
  382. package/dist/.test/assets/node-service/declarations/practices/node-service/bad-practices/simple-lambda-client/package.json +5 -0
  383. package/dist/.test/assets/node-service/declarations/practices/node-service/bad-practices/simple-lambda-client/package.json.declapract.ts +27 -0
  384. package/dist/.test/assets/node-service/declarations/practices/node-service/bad-practices/simple-lambda-client/src/<star><star>/<star>.ts.declapract.ts +44 -0
  385. package/dist/.test/assets/node-service/declarations/practices/node-service/bad-practices/simple-lambda-handlers/.declapract.integration.test.ts +103 -0
  386. package/dist/.test/assets/node-service/declarations/practices/node-service/bad-practices/simple-lambda-handlers/.declapract.readme.md +60 -0
  387. package/dist/.test/assets/node-service/declarations/practices/node-service/bad-practices/simple-lambda-handlers/.test/assets/demo-repo-with-simple-lambda-handlers/declapract.use.yml +5 -0
  388. package/dist/.test/assets/node-service/declarations/practices/node-service/bad-practices/simple-lambda-handlers/.test/assets/demo-repo-with-simple-lambda-handlers/package.json +4 -0
  389. package/dist/.test/assets/node-service/declarations/practices/node-service/bad-practices/simple-lambda-handlers/.test/assets/demo-repo-with-simple-lambda-handlers/src/contract/handlers/getWidget.ts +13 -0
  390. package/dist/.test/assets/node-service/declarations/practices/node-service/bad-practices/simple-lambda-handlers/__snapshots__/.declapract.integration.test.ts.snap +44 -0
  391. package/dist/.test/assets/node-service/declarations/practices/node-service/bad-practices/simple-lambda-handlers/package.json +5 -0
  392. package/dist/.test/assets/node-service/declarations/practices/node-service/bad-practices/simple-lambda-handlers/package.json.declapract.ts +27 -0
  393. package/dist/.test/assets/node-service/declarations/practices/node-service/bad-practices/simple-lambda-handlers/src/<star><star>/<star>.ts.declapract.ts +130 -0
  394. package/dist/.test/assets/node-service/declarations/practices/node-service/best-practice/package.json +6 -0
  395. package/dist/.test/assets/node-service/declarations/practices/node-service/best-practice/package.json.declapract.ts +3 -0
  396. package/dist/.test/assets/node-service/declarations/useCases.yml +5 -0
  397. package/dist/.test/assets/pnpm/declarations/practices/pnpm/.declapract.integration.test.ts +163 -13
  398. package/dist/.test/assets/pnpm/declarations/practices/pnpm/.test/assets/repo-npm-to-pnpm/package.json +1 -1
  399. package/dist/.test/assets/pnpm/declarations/practices/pnpm/.test/assets/repo-npm-to-pnpm/pnpm-workspace.yaml +3 -0
  400. package/dist/.test/assets/pnpm/declarations/practices/pnpm/__snapshots__/.declapract.integration.test.ts.snap +9 -2
  401. package/dist/.test/assets/pnpm/declarations/practices/pnpm/bad-practices/inert-build-allowlist/pnpm-workspace.yaml.declapract.ts +59 -0
  402. package/dist/.test/assets/pnpm/declarations/practices/pnpm/best-practice/.declapract.readme.md +1 -1
  403. package/dist/.test/assets/pnpm/declarations/practices/pnpm/best-practice/package.json +1 -1
  404. package/dist/.test/assets/pnpm/declarations/practices/pnpm/best-practice/package.json.declapract.ts +4 -2
  405. package/dist/.test/assets/runtime-schemas/declarations/declapract.declare.yml +4 -0
  406. package/dist/.test/assets/runtime-schemas/declarations/practices/runtime-schemas/bad-practices/joi/.declapract.integration.test.ts +102 -0
  407. package/dist/.test/assets/runtime-schemas/declarations/practices/runtime-schemas/bad-practices/joi/.declapract.readme.md +3 -0
  408. package/dist/.test/assets/runtime-schemas/declarations/practices/runtime-schemas/bad-practices/joi/.test/assets/demo-repo-with-joi/declapract.use.yml +5 -0
  409. package/dist/.test/assets/runtime-schemas/declarations/practices/runtime-schemas/bad-practices/joi/.test/assets/demo-repo-with-joi/package.json +4 -0
  410. package/dist/.test/assets/runtime-schemas/declarations/practices/runtime-schemas/bad-practices/joi/.test/assets/demo-repo-with-joi/src/contract/schemas/widget.schema.ts +9 -0
  411. package/dist/.test/assets/runtime-schemas/declarations/practices/runtime-schemas/bad-practices/joi/__snapshots__/.declapract.integration.test.ts.snap +37 -0
  412. package/dist/.test/assets/runtime-schemas/declarations/practices/runtime-schemas/bad-practices/joi/package.json +5 -0
  413. package/dist/.test/assets/runtime-schemas/declarations/practices/runtime-schemas/bad-practices/joi/package.json.declapract.ts +23 -0
  414. package/dist/.test/assets/runtime-schemas/declarations/practices/runtime-schemas/bad-practices/joi/src/<star><star>/<star>.ts.declapract.ts +79 -0
  415. package/dist/.test/assets/runtime-schemas/declarations/practices/runtime-schemas/best-practice/package.json +5 -0
  416. package/dist/.test/assets/runtime-schemas/declarations/practices/runtime-schemas/best-practice/package.json.declapract.ts +3 -0
  417. package/dist/.test/assets/runtime-schemas/declarations/useCases.yml +5 -0
  418. package/dist/.test/assets/tests-service/declarations/declapract.declare.yml +10 -0
  419. package/dist/.test/assets/tests-service/declarations/practices/tests-service/.test/assets/demo-repo-service/declapract.use.yml +5 -0
  420. package/dist/.test/assets/tests-service/declarations/practices/tests-service/.test/assets/demo-repo-service/package.json +4 -0
  421. package/dist/.test/assets/tests-service/declarations/practices/tests-service/__snapshots__/package.json.declapract.integration.test.ts.snap +26 -0
  422. package/dist/.test/assets/tests-service/declarations/practices/tests-service/asFunctionNameFromTestFileName.ts +7 -0
  423. package/dist/.test/assets/tests-service/declarations/practices/tests-service/best-practice/.declapract.readme.md +68 -0
  424. package/dist/.test/assets/tests-service/declarations/practices/tests-service/best-practice/blackbox/<star><star>/<star>.acceptance.test.ts.declapract.ts +3 -0
  425. package/dist/.test/assets/tests-service/declarations/practices/tests-service/best-practice/blackbox/lambdas/<star>.acceptance.test.ts.declapract.ts +56 -0
  426. package/dist/.test/assets/tests-service/declarations/practices/tests-service/best-practice/package.json +8 -0
  427. package/dist/.test/assets/tests-service/declarations/practices/tests-service/best-practice/package.json.declapract.ts +101 -0
  428. package/dist/.test/assets/tests-service/declarations/practices/tests-service/best-practice/src/<star><star>/<star>.integration.test.ts.declapract.ts +3 -0
  429. package/dist/.test/assets/tests-service/declarations/practices/tests-service/best-practice/src/<star><star>/<star>.test.ts.declapract.ts +3 -0
  430. package/dist/.test/assets/tests-service/declarations/practices/tests-service/package.json.declapract.integration.test.ts +204 -0
  431. package/dist/.test/assets/tests-service/declarations/useCases.yml +9 -0
  432. package/dist/__snapshots__/ancientTargetPublished.declapract.integration.test.ts.snap +42 -0
  433. package/dist/__snapshots__/workflowCallerCalleeReconciliation.declapract.integration.test.ts.snap +450 -0
  434. package/dist/__snapshots__/workflowEnvDeploymentFalse.declapract.integration.test.ts.snap +36 -0
  435. package/dist/actionPins.declapract.integration.test.ts +3 -18
  436. package/dist/ancientTargetPublished.declapract.integration.test.ts +174 -0
  437. package/dist/bestPracticeTemplateParse.declapract.integration.test.ts +169 -0
  438. package/dist/parsePackageJSONAdoption.declapract.integration.test.ts +136 -0
  439. package/dist/practiceTestFileLocation.declapract.integration.test.ts +75 -0
  440. package/dist/practices/cache/.declapract.integration.test.ts +4 -4
  441. package/dist/practices/cache/.test/assets/repo-with-valid-cache-package/package.json +1 -1
  442. package/dist/practices/cache/best-practice/package.json +3 -3
  443. package/dist/practices/cicd-app-react-native-expo/.declapract.integration.test.ts +122 -22
  444. package/dist/practices/cicd-app-react-native-expo/__snapshots__/.declapract.integration.test.ts.snap +40 -29
  445. package/dist/practices/cicd-app-react-native-expo/best-practice/.github/workflows/.deploy-expo.yml +16 -6
  446. package/dist/practices/cicd-app-react-native-expo/best-practice/.github/workflows/deploy.yml +11 -11
  447. package/dist/practices/cicd-app-react-native-expo/best-practice/.github/workflows/test.yml +3 -5
  448. package/dist/practices/cicd-app-react-native-expo/best-practice/package.json +2 -2
  449. package/dist/practices/cicd-common/.declapract.integration.test.ts +25 -0
  450. package/dist/practices/cicd-common/__snapshots__/.declapract.integration.test.ts.snap +11 -23
  451. package/dist/practices/cicd-common/__snapshots__/declastruct-insync-grep.declapract.integration.test.ts.snap +3 -0
  452. package/dist/practices/cicd-common/best-practice/.github/workflows/.declastruct.yml +22 -8
  453. package/dist/practices/cicd-common/best-practice/.github/workflows/.test.yml +11 -23
  454. package/dist/practices/cicd-common/best-practice/.github/workflows/.test.yml.declapract.ts +12 -1
  455. package/dist/practices/cicd-common/best-practice/.github/workflows/report-slow-tests.sh +65 -0
  456. package/dist/practices/cicd-common/declastruct-insync-grep.declapract.integration.test.ts +49 -0
  457. package/dist/practices/cicd-common/report-slow-tests.play.declapract.integration.test.ts +144 -0
  458. package/dist/practices/cicd-package/best-practice/.github/workflows/provision.yml +2 -1
  459. package/dist/practices/cicd-service/.declapract.integration.test.ts +175 -0
  460. package/dist/practices/cicd-service/.test/assets/demo-repo-pre-stamped-nords/.github/workflows/provision.yml +110 -0
  461. package/dist/practices/cicd-service/.test/assets/demo-repo-pre-stamped-nords/declapract.use.nords.yml +20 -0
  462. package/dist/practices/cicd-service/.test/assets/demo-repo-pre-stamped-nords/declapract.use.rds.yml +20 -0
  463. package/dist/practices/cicd-service/.test/assets/demo-repo-pre-stamped-nords/package.json +4 -0
  464. package/dist/practices/cicd-service/.test/assets/demo-repo-service/declapract.use.nords.yml +20 -0
  465. package/dist/practices/cicd-service/.test/assets/demo-repo-service/declapract.use.rds.yml +20 -0
  466. package/dist/practices/cicd-service/.test/assets/demo-repo-service/package.json +4 -0
  467. package/dist/practices/cicd-service/__snapshots__/.declapract.integration.test.ts.snap +24 -0
  468. package/dist/practices/cicd-service/__snapshots__/acceptanceContempFleetGuard.declapract.integration.test.ts.snap +13 -0
  469. package/dist/practices/cicd-service/__snapshots__/insync-grep.declapract.integration.test.ts.snap +5 -0
  470. package/dist/practices/cicd-service/__snapshots__/provision.yml.declapract.integration.test.ts.snap +297 -0
  471. package/dist/practices/cicd-service/acceptanceContempFleetGuard.declapract.integration.test.ts +89 -0
  472. package/dist/practices/cicd-service/bad-practices/rds-jobs-in-non-rds-service/.declapract.integration.test.ts +153 -0
  473. package/dist/practices/cicd-service/bad-practices/rds-jobs-in-non-rds-service/.declapract.readme.md +38 -0
  474. package/dist/practices/cicd-service/bad-practices/rds-jobs-in-non-rds-service/.github/workflows/provision.yml.declapract.integration.test.ts +167 -0
  475. package/dist/practices/cicd-service/bad-practices/rds-jobs-in-non-rds-service/.github/workflows/provision.yml.declapract.ts +88 -0
  476. package/dist/practices/cicd-service/bad-practices/rds-jobs-in-non-rds-service/.test/assets/repo-non-rds/readme.md +9 -0
  477. package/dist/practices/cicd-service/bad-practices/rds-jobs-in-non-rds-service/.test/assets/repo-with-aws-resources-callee/provision/aws/resources.ts +5 -0
  478. package/dist/practices/cicd-service/bad-practices/rds-jobs-in-non-rds-service/.test/assets/repo-with-schema-callee/provision/schema/init.sql +5 -0
  479. package/dist/practices/cicd-service/bad-practices/rds-jobs-in-non-rds-service/__snapshots__/.declapract.integration.test.ts.snap +183 -0
  480. package/dist/practices/cicd-service/best-practice/.declapract.readme.md +18 -0
  481. package/dist/practices/cicd-service/best-practice/.github/workflows/.deploy-sls.yml +32 -11
  482. package/dist/practices/cicd-service/best-practice/.github/workflows/.sql-schema-control.yml +20 -10
  483. package/dist/practices/cicd-service/best-practice/.github/workflows/.terraform.yml +14 -4
  484. package/dist/practices/cicd-service/best-practice/.github/workflows/deploy.yml +17 -9
  485. package/dist/practices/cicd-service/best-practice/.github/workflows/provision.yml +15 -10
  486. package/dist/practices/cicd-service/best-practice/.github/workflows/provision.yml.declapract.ts +74 -0
  487. package/dist/practices/cicd-service/best-practice/package.json +3 -3
  488. package/dist/practices/cicd-service/insync-grep.declapract.integration.test.ts +76 -0
  489. package/dist/practices/cicd-service/provision.yml.declapract.integration.test.ts +182 -0
  490. package/dist/practices/commands/best-practice/package.json +2 -2
  491. package/dist/practices/commands/best-practice/src/contract/commands/sayHello.ts +3 -2
  492. package/dist/practices/config/.declapract.integration.test.ts +116 -0
  493. package/dist/practices/config/.test/assets/demo-repo-with-dev-config/config/dev.json +17 -0
  494. package/dist/practices/config/.test/assets/demo-repo-with-dev-config/declapract.declare.yml +4 -0
  495. package/dist/practices/config/.test/assets/demo-repo-with-dev-config/declapract.use.yml +9 -0
  496. package/dist/practices/config/.test/assets/demo-repo-with-dev-config/package.json +4 -0
  497. package/dist/practices/config/__snapshots__/.declapract.integration.test.ts.snap +43 -0
  498. package/dist/practices/config/bad-practices/divergent-config-shapes/config/prep.json.declapract.ts +3 -3
  499. package/dist/practices/config/bad-practices/divergent-config-shapes/config/prod.json.declapract.ts +3 -3
  500. package/dist/practices/config/bad-practices/old-dev-config-location/config/dev.json.declapract.ts +10 -12
  501. package/dist/practices/config/best-practice/package.json +2 -2
  502. package/dist/practices/config/best-practice/src/utils/config/getConfig.ts +24 -5
  503. package/dist/practices/config/best-practice/src/utils/config/getOneCacheDirectory.ts +33 -0
  504. package/dist/practices/config/best-practice/src/utils/config/getOneProjectBucket.ts +22 -0
  505. package/dist/practices/config/best-practice/src/utils/environment.ts +9 -3
  506. package/dist/practices/config/best-practice/src/utils/environment.ts.declapract.ts +8 -0
  507. package/dist/practices/config/no-hand-written-config-type.declapract.integration.test.ts +64 -0
  508. package/dist/practices/conventional-commits/__snapshots__/commitlint-body-max-line.declapract.integration.test.ts.snap +3 -0
  509. package/dist/practices/conventional-commits/best-practice/commitlint.config.js +5 -0
  510. package/dist/practices/conventional-commits/best-practice/package.json +1 -1
  511. package/dist/practices/conventional-commits/commitlint-body-max-line.declapract.integration.test.ts +49 -0
  512. package/dist/practices/domain/.declapract.integration.test.ts +115 -0
  513. package/dist/{.test/assets/expo-migration/declarations/practices/domain/bad-practices/schematic-joi-model/src/domain → practices/domain/bad-practices/schematic-joi-model/src/domain.objects}/<star><star>/<star>.ts.declapract.ts +4 -1
  514. package/dist/practices/domain/best-practice/package.json +2 -2
  515. package/dist/practices/domain/best-practice/src/domain.objects/index.ts.declapract.ts +12 -0
  516. package/dist/practices/environments/.declapract.integration.test.ts +136 -0
  517. package/dist/practices/environments/__snapshots__/.declapract.integration.test.ts.snap +55 -0
  518. package/dist/practices/environments/bad-practices/old-dev-scripts/package.json.declapract.ts +6 -4
  519. package/dist/practices/environments/bad-practices/old-stage-enum/.declapract.integration.test.ts +133 -0
  520. package/dist/practices/environments/bad-practices/old-stage-enum/.test/assets/demo-repo-with-stage-enum/declapract.use.yml +8 -0
  521. package/dist/practices/environments/bad-practices/old-stage-enum/.test/assets/demo-repo-with-stage-enum/package.json +4 -0
  522. package/dist/practices/environments/bad-practices/old-stage-enum/.test/assets/demo-repo-with-stage-enum/src/logic/getDeployTarget.ts +15 -0
  523. package/dist/practices/environments/bad-practices/old-stage-enum/__snapshots__/.declapract.integration.test.ts.snap +40 -0
  524. package/dist/practices/environments/bad-practices/old-stage-enum/src/<star><star>/<star>.ts.declapract.ts +291 -24
  525. package/dist/practices/environments/best-practice/.declapract.readme.md +44 -11
  526. package/dist/practices/environments/best-practice/src/access/sdks/sdkAwsLambdaEnvAccessAncient.ts +32 -0
  527. package/dist/practices/environments/best-practice/src/access/sdks/sdkAwsLambdaEnvAccessContemp.ts +14 -0
  528. package/dist/practices/environments/best-practice/src/utils/environment.ts +3 -2
  529. package/dist/practices/errors/.declapract.integration.test.ts +121 -0
  530. package/dist/practices/errors/bad-practices/own-implementation/src/<star><star>/UnexpectedCodePathError.ts.declapract.ts +8 -0
  531. package/dist/practices/errors/best-practice/package.json +1 -1
  532. package/dist/practices/format/.declapract.integration.test.ts +131 -0
  533. package/dist/practices/format/__snapshots__/.declapract.integration.test.ts.snap +17 -0
  534. package/dist/practices/format/bad-practices/prettier/prettier.config.js.declapract.ts +1 -1
  535. package/dist/practices/format/best-practice/package.json.declapract.ts +36 -18
  536. package/dist/practices/git/.declapract.integration.test.ts +57 -6
  537. package/dist/practices/git/__snapshots__/.declapract.integration.test.ts.snap +2 -0
  538. package/dist/practices/git/best-practice/.gitattributes.declapract.ts +50 -37
  539. package/dist/practices/git/best-practice/.gitignore.declapract.ts +8 -0
  540. package/dist/practices/husky/__snapshots__/check.timestamps.play.declapract.integration.test.ts.snap +7 -0
  541. package/dist/practices/husky/best-practice/.husky/check.timestamps.sh +11 -2
  542. package/dist/practices/husky/check.timestamps.play.declapract.integration.test.ts +65 -0
  543. package/dist/practices/lint/__snapshots__/dpdmrc-exclude-policy.declapract.integration.test.ts.snap +3 -0
  544. package/dist/practices/lint/bad-practices/depcheck-denylisted-ignores/.depcheckrc.yml.declapract.ts +4 -0
  545. package/dist/practices/lint/best-practice/.depcheckrc.yml.declapract.ts +10 -9
  546. package/dist/practices/lint/best-practice/.dpdmrc.yaml +10 -6
  547. package/dist/practices/lint/dpdmrc-exclude-policy.declapract.integration.test.ts +50 -0
  548. package/dist/practices/logs/.declapract.integration.test.ts +100 -0
  549. package/dist/practices/logs/__snapshots__/.declapract.integration.test.ts.snap +33 -0
  550. package/dist/practices/logs/bad-practices/leveled-term/.test/assets/demo-repo-with-leveled-term/declapract.declare.yml +4 -0
  551. package/dist/practices/logs/bad-practices/leveled-term/.test/assets/demo-repo-with-leveled-term/declapract.use.yml +2 -0
  552. package/dist/practices/logs/bad-practices/leveled-term/.test/assets/demo-repo-with-leveled-term/package.json +12 -0
  553. package/dist/practices/logs/bad-practices/leveled-term/package.json.declapract.ts +56 -12
  554. package/dist/practices/node/bad-practices/self-deps-not-link/.declapract.integration.test.ts +102 -0
  555. package/dist/practices/node/bad-practices/self-deps-not-link/.test/assets/demo-repo-with-self-deps/declapract.declare.yml +4 -0
  556. package/dist/practices/node/bad-practices/self-deps-not-link/.test/assets/demo-repo-with-self-deps/declapract.use.yml +8 -0
  557. package/dist/practices/node/bad-practices/self-deps-not-link/.test/assets/demo-repo-with-self-deps/package.json +15 -0
  558. package/dist/practices/node/bad-practices/self-deps-not-link/__snapshots__/.declapract.integration.test.ts.snap +46 -0
  559. package/dist/practices/node/bad-practices/self-deps-not-link/package.json.declapract.ts +22 -29
  560. package/dist/practices/node/best-practice/.npmrc.declapract.ts +5 -1
  561. package/dist/practices/node/best-practice/package.json +1 -1
  562. package/dist/practices/node-service/bad-practices/simple-lambda-handlers/.declapract.integration.test.ts +103 -0
  563. package/dist/practices/node-service/bad-practices/simple-lambda-handlers/.declapract.readme.md +8 -0
  564. package/dist/practices/node-service/bad-practices/simple-lambda-handlers/.test/assets/demo-repo-with-simple-lambda-handlers/declapract.use.yml +5 -0
  565. package/dist/practices/node-service/bad-practices/simple-lambda-handlers/.test/assets/demo-repo-with-simple-lambda-handlers/package.json +4 -0
  566. package/dist/practices/node-service/bad-practices/simple-lambda-handlers/.test/assets/demo-repo-with-simple-lambda-handlers/src/contract/handlers/getWidget.ts +13 -0
  567. package/dist/practices/node-service/bad-practices/simple-lambda-handlers/__snapshots__/.declapract.integration.test.ts.snap +44 -0
  568. package/dist/practices/node-service/bad-practices/simple-lambda-handlers/src/<star><star>/<star>.ts.declapract.ts +90 -10
  569. package/dist/practices/node-service/best-practice/package.json +1 -1
  570. package/dist/practices/package-json-order/best-practice/package.json.declapract.ts +7 -1
  571. package/dist/practices/persist-with-dynamodb/.declapract.integration.test.ts +92 -0
  572. package/dist/practices/persist-with-dynamodb/.test/assets/demo-repo-with-divergent-jest-env/declapract.declare.yml +4 -0
  573. package/dist/practices/persist-with-dynamodb/.test/assets/demo-repo-with-divergent-jest-env/declapract.use.yml +2 -0
  574. package/dist/practices/persist-with-dynamodb/.test/assets/demo-repo-with-divergent-jest-env/jest.integration.env.ts +4 -0
  575. package/dist/practices/persist-with-dynamodb/.test/assets/demo-repo-with-divergent-jest-env/package.json +4 -0
  576. package/dist/practices/persist-with-dynamodb/__snapshots__/.declapract.integration.test.ts.snap +20 -0
  577. package/dist/practices/persist-with-dynamodb/best-practice/jest.integration.env.ts +3 -3
  578. package/dist/practices/persist-with-dynamodb/best-practice/package.json +2 -2
  579. package/dist/practices/persist-with-rds/.declapract.integration.test.ts +224 -0
  580. package/dist/practices/persist-with-rds/.extensions.sql.declapract.integration.test.ts +38 -0
  581. package/dist/practices/persist-with-rds/.test/assets/demo-repo-with-dev-config/config/dev.json +18 -0
  582. package/dist/practices/persist-with-rds/.test/assets/demo-repo-with-dev-config/declapract.declare.yml +4 -0
  583. package/dist/practices/persist-with-rds/.test/assets/demo-repo-with-dev-config/declapract.use.yml +18 -0
  584. package/dist/practices/persist-with-rds/.test/assets/demo-repo-with-dev-config/package.json +4 -0
  585. package/dist/practices/persist-with-rds/__snapshots__/.declapract.integration.test.ts.snap +45 -0
  586. package/dist/practices/persist-with-rds/__snapshots__/.extensions.sql.declapract.integration.test.ts.snap +42 -0
  587. package/dist/practices/persist-with-rds/__snapshots__/deploy-database-gerunds.declapract.integration.test.ts.snap +102 -0
  588. package/dist/practices/persist-with-rds/__snapshots__/provision-testdb-access.declapract.integration.test.ts.snap +3 -0
  589. package/dist/practices/persist-with-rds/__snapshots__/ssm-cicd-param-names.declapract.integration.test.ts.snap +10 -0
  590. package/dist/practices/persist-with-rds/__snapshots__/testdb-preflight-failloud.declapract.integration.test.ts.snap +30 -0
  591. package/dist/practices/persist-with-rds/bad-practices/old-dev-config-location/config/dev.json.declapract.ts +22 -8
  592. package/dist/practices/persist-with-rds/best-practice/.declapract.readme.md +32 -0
  593. package/dist/practices/persist-with-rds/best-practice/codegen.sql.dao.yml +1 -1
  594. package/dist/practices/persist-with-rds/best-practice/package.json +5 -5
  595. package/dist/practices/persist-with-rds/best-practice/provision/aws/readme.md +9 -6
  596. package/dist/practices/persist-with-rds/best-practice/provision/aws/resources.parameters.ts +38 -14
  597. package/dist/practices/persist-with-rds/best-practice/provision/aws/resources.ts +6 -3
  598. package/dist/practices/persist-with-rds/best-practice/provision/docker/testdb/wait-for-postgres.sh +13 -3
  599. package/dist/practices/persist-with-rds/best-practice/provision/schema/deploy.database.sh +27 -22
  600. package/dist/practices/persist-with-rds/best-practice/src/utils/config/config.schema.ts +13 -6
  601. package/dist/practices/persist-with-rds/best-practice/src/utils/database/getOneDatabaseConnection.integration.test.ts +10 -0
  602. package/dist/practices/persist-with-rds/best-practice/src/utils/database/getOneDatabaseConnection.ts +90 -0
  603. package/dist/practices/persist-with-rds/best-practice/src/utils/database/withDatabaseContext.ts +12 -4
  604. package/dist/practices/persist-with-rds/best-practice/src/utils/database/withDatabaseTransaction.ts +16 -4
  605. package/dist/practices/persist-with-rds/deploy-database-gerunds.declapract.integration.test.ts +57 -0
  606. package/dist/practices/persist-with-rds/empty-template-declares-zero-clusters.declapract.integration.test.ts +71 -0
  607. package/dist/practices/persist-with-rds/provision-testdb-access.declapract.integration.test.ts +50 -0
  608. package/dist/practices/persist-with-rds/ssm-cicd-param-names.declapract.integration.test.ts +73 -0
  609. package/dist/practices/persist-with-rds/testdb-preflight-failloud.declapract.integration.test.ts +83 -0
  610. package/dist/practices/pnpm/.declapract.integration.test.ts +163 -13
  611. package/dist/practices/pnpm/.test/assets/repo-npm-to-pnpm/package.json +1 -1
  612. package/dist/practices/pnpm/.test/assets/repo-npm-to-pnpm/pnpm-workspace.yaml +3 -0
  613. package/dist/practices/pnpm/__snapshots__/.declapract.integration.test.ts.snap +9 -2
  614. package/dist/practices/pnpm/bad-practices/inert-build-allowlist/pnpm-workspace.yaml.declapract.ts +59 -0
  615. package/dist/practices/pnpm/best-practice/.declapract.readme.md +1 -1
  616. package/dist/practices/pnpm/best-practice/package.json +1 -1
  617. package/dist/practices/pnpm/best-practice/package.json.declapract.ts +4 -2
  618. package/dist/practices/provision-github/best-practice/package.json +2 -2
  619. package/dist/practices/provision-github/best-practice/provision/github.repo/resources.ts +16 -0
  620. package/dist/practices/rhachet/.declapract.integration.test.ts +98 -0
  621. package/dist/practices/rhachet/.test/assets/demo-repo-with-consumer-boot/.agent/repo=.this/role=any/boot.yml +7 -0
  622. package/dist/practices/rhachet/.test/assets/demo-repo-with-consumer-boot/declapract.declare.yml +4 -0
  623. package/dist/practices/rhachet/.test/assets/demo-repo-with-consumer-boot/declapract.use.yml +2 -0
  624. package/dist/practices/rhachet/.test/assets/demo-repo-with-consumer-boot/package.json +4 -0
  625. package/dist/practices/rhachet/__snapshots__/.declapract.integration.test.ts.snap +45 -0
  626. package/dist/practices/rhachet/__snapshots__/boot-refs-glossary.declapract.integration.test.ts.snap +6 -0
  627. package/dist/practices/rhachet/__snapshots__/boot-yml-findsert.declapract.integration.test.ts.snap +27 -0
  628. package/dist/practices/rhachet/bad-practices/prod-deps/.declapract.readme.md +6 -2
  629. package/dist/practices/rhachet/bad-practices/prod-deps/.test/assets/demo-repo-with-rhachet-prod-deps/declapract.declare.yml +4 -0
  630. package/dist/practices/rhachet/bad-practices/prod-deps/.test/assets/demo-repo-with-rhachet-prod-deps/declapract.use.yml +2 -0
  631. package/dist/practices/rhachet/bad-practices/prod-deps/.test/assets/demo-repo-with-rhachet-prod-deps/package.json +12 -0
  632. package/dist/practices/rhachet/bad-practices/prod-deps/package.json.declapract.ts +58 -17
  633. package/dist/practices/rhachet/best-practice/.agent/repo=.this/role=any/boot.yml +46 -0
  634. package/dist/practices/rhachet/best-practice/.agent/repo=.this/role=any/boot.yml.declapract.ts +165 -0
  635. package/dist/practices/rhachet/best-practice/.gitignore.declapract.ts +18 -5
  636. package/dist/practices/rhachet/best-practice/package.json +8 -8
  637. package/dist/practices/rhachet/boot-refs-glossary.declapract.integration.test.ts +89 -0
  638. package/dist/practices/rhachet/boot-yml-findsert.declapract.integration.test.ts +145 -0
  639. package/dist/practices/runtime-schemas/bad-practices/joi/.declapract.integration.test.ts +102 -0
  640. package/dist/practices/runtime-schemas/bad-practices/joi/.test/assets/demo-repo-with-joi/declapract.use.yml +5 -0
  641. package/dist/practices/runtime-schemas/bad-practices/joi/.test/assets/demo-repo-with-joi/package.json +4 -0
  642. package/dist/practices/runtime-schemas/bad-practices/joi/.test/assets/demo-repo-with-joi/src/contract/schemas/widget.schema.ts +9 -0
  643. package/dist/practices/runtime-schemas/bad-practices/joi/__snapshots__/.declapract.integration.test.ts.snap +37 -0
  644. package/dist/practices/runtime-schemas/bad-practices/joi/src/<star><star>/<star>.ts.declapract.ts +32 -3
  645. package/dist/practices/serverless/.declapract.integration.test.ts +230 -0
  646. package/dist/practices/serverless/.test/assets/demo-repo-with-serverless/declapract.declare.yml +4 -0
  647. package/dist/practices/serverless/.test/assets/demo-repo-with-serverless/declapract.use.yml +8 -0
  648. package/dist/practices/serverless/.test/assets/demo-repo-with-serverless/package.json +4 -0
  649. package/dist/practices/serverless/.test/assets/demo-repo-with-serverless/serverless.yml +8 -0
  650. package/dist/practices/serverless/__snapshots__/.declapract.integration.test.ts.snap +43 -0
  651. package/dist/practices/serverless/__snapshots__/cache-grant-stage-globbed.declapract.integration.test.ts.snap +3 -0
  652. package/dist/practices/serverless/__snapshots__/deployment-bucket-account-scoped.declapract.integration.test.ts.snap +9 -0
  653. package/dist/practices/serverless/__snapshots__/divergentStageGuard.declapract.integration.test.ts.snap +15 -0
  654. package/dist/practices/serverless/__snapshots__/serverless.yml.declapract.integration.test.ts.snap +165 -0
  655. package/dist/practices/serverless/best-practice/.declapract.readme.md +111 -0
  656. package/dist/practices/serverless/best-practice/package.json +7 -5
  657. package/dist/practices/serverless/best-practice/serverless.yml +14 -6
  658. package/dist/practices/serverless/best-practice/serverless.yml.declapract.ts +609 -64
  659. package/dist/practices/serverless/cache-grant-stage-globbed.declapract.integration.test.ts +69 -0
  660. package/dist/practices/serverless/deployment-bucket-account-scoped.declapract.integration.test.ts +78 -0
  661. package/dist/practices/serverless/divergentStageGuard.declapract.integration.test.ts +280 -0
  662. package/dist/practices/serverless/serverless.yml.declapract.integration.test.ts +1285 -0
  663. package/dist/practices/terraform-aws/best-practice/provision/aws/environments/prep/main.tf +1 -1
  664. package/dist/practices/tests-any/__snapshots__/changedsince-origin-main.declapract.integration.test.ts.snap +8 -0
  665. package/dist/practices/tests-any/autoprune-hooks.declapract.integration.test.ts +104 -0
  666. package/dist/practices/tests-any/bad-practices/old-acceptance-import-paths/.declapract.readme.md +2 -2
  667. package/dist/practices/tests-any/bad-practices/old-acceptance-test-utils/blackbox/lambdas/<star>.ts.declapract.ts +9 -9
  668. package/dist/practices/tests-any/best-practice/package.json +3 -3
  669. package/dist/practices/tests-any/changedsince-origin-main.declapract.integration.test.ts +58 -0
  670. package/dist/practices/tests-any/{best-practice/package.json.shell-flags.declapract.integration.test.ts → package.json.shell-flags.declapract.integration.test.ts} +26 -16
  671. package/dist/practices/tests-expo/.declapract.integration.test.ts +7 -3
  672. package/dist/practices/tests-expo/.test/assets/repo-expo-greenfield/package.json +5 -1
  673. package/dist/practices/tests-expo/__snapshots__/.declapract.integration.test.ts.snap +17 -8
  674. package/dist/practices/tests-expo/__snapshots__/package.json.declapract.integration.test.ts.snap +60 -0
  675. package/dist/practices/tests-expo/best-practice/jest.acceptance.config.ts +5 -0
  676. package/dist/practices/tests-expo/best-practice/jest.integration.config.ts +5 -0
  677. package/dist/practices/tests-expo/best-practice/jest.integration.env.ts +5 -1
  678. package/dist/practices/tests-expo/best-practice/jest.unit.config.ts +5 -0
  679. package/dist/practices/tests-expo/best-practice/jest.unit.env.ts +6 -1
  680. package/dist/practices/tests-expo/best-practice/package.json.declapract.ts +190 -13
  681. package/dist/practices/tests-expo/package.json.declapract.integration.test.ts +94 -0
  682. package/dist/practices/tests-node/__snapshots__/livedb-wake-branches.declapract.integration.test.ts.snap +6 -0
  683. package/dist/practices/tests-node/best-practice/jest.acceptance.config.ts +8 -0
  684. package/dist/practices/tests-node/best-practice/jest.acceptance.env.ts +16 -26
  685. package/dist/practices/tests-node/best-practice/jest.acceptance.prepare.ts +36 -0
  686. package/dist/practices/tests-node/best-practice/jest.integration.config.ts +8 -0
  687. package/dist/practices/tests-node/best-practice/jest.integration.env.db.ts +90 -0
  688. package/dist/practices/tests-node/best-practice/jest.integration.env.ts +26 -74
  689. package/dist/practices/tests-node/best-practice/jest.integration.prepare.ts +33 -0
  690. package/dist/practices/tests-node/best-practice/jest.unit.config.ts +7 -0
  691. package/dist/practices/tests-node/best-practice/jest.unit.env.ts +11 -4
  692. package/dist/practices/tests-node/best-practice/jest.unit.env.ts.declapract.ts +3 -1
  693. package/dist/practices/tests-node/best-practice/src/.test/useKeyrack.ts +211 -0
  694. package/dist/practices/tests-node/best-practice/src/.test/useWakeOfLivedb.ts +181 -0
  695. package/dist/practices/tests-node/best-practice/src/.test/useWakeOfTestdb.ts +71 -0
  696. package/dist/practices/tests-node/livedb-wake-branches.declapract.integration.test.ts +227 -0
  697. package/dist/practices/tests-node/livedb-wake-prepare.declapract.integration.test.ts +112 -0
  698. package/dist/practices/tests-node/testdb-preflight-branches.declapract.integration.test.ts +203 -0
  699. package/dist/practices/tests-node/testdb-preflight-env.declapract.integration.test.ts +65 -0
  700. package/dist/practices/tests-service/.test/assets/demo-repo-service/declapract.use.yml +5 -0
  701. package/dist/practices/tests-service/.test/assets/demo-repo-service/package.json +4 -0
  702. package/dist/practices/tests-service/__snapshots__/package.json.declapract.integration.test.ts.snap +26 -0
  703. package/dist/practices/tests-service/asFunctionNameFromTestFileName.ts +7 -0
  704. package/dist/practices/tests-service/best-practice/.declapract.readme.md +68 -0
  705. package/dist/practices/tests-service/best-practice/blackbox/lambdas/<star>.acceptance.test.ts.declapract.ts +33 -8
  706. package/dist/practices/tests-service/best-practice/package.json +4 -1
  707. package/dist/practices/tests-service/best-practice/package.json.declapract.ts +99 -1
  708. package/dist/practices/tests-service/package.json.declapract.integration.test.ts +204 -0
  709. package/dist/practices/typescript-expo/__snapshots__/package.json.declapract.integration.test.ts.snap +8 -0
  710. package/dist/practices/typescript-expo/__snapshots__/tsconfig.json.declapract.integration.test.ts.snap +19 -0
  711. package/dist/practices/typescript-expo/{best-practice/package.json.declapract.integration.test.ts → package.json.declapract.integration.test.ts} +15 -2
  712. package/dist/{.test/assets/expo-migration/declarations/practices/typescript-expo/best-practice → practices/typescript-expo}/tsconfig.json.declapract.integration.test.ts +13 -2
  713. package/dist/practices/typescript-node/best-practice/package.json.declapract.ts +3 -1
  714. package/dist/practices/uuid/best-practice/package.json +1 -1
  715. package/dist/stageAccessBridge.declapract.integration.test.ts +163 -0
  716. package/dist/utils/asPackageJSON.ts +57 -0
  717. package/dist/utils/asPrepConfigPath.ts +12 -0
  718. package/dist/utils/getAllPathsUnderDir.ts +45 -0
  719. package/dist/utils/getAllPracticesForUsecase.ts +35 -9
  720. package/dist/utils/migrateDevConfigToPrep.ts +47 -0
  721. package/dist/utils/readFile.ts +2 -2
  722. package/dist/workflowCallerCalleeReconciliation.declapract.integration.test.ts +319 -0
  723. package/dist/workflowEnvDeploymentFalse.declapract.integration.test.ts +173 -0
  724. package/package.json +10 -9
  725. package/dist/.test/assets/expo-fullusecase/declarations/practices/domain/best-practice/src/domain/objects/index.ts.declapract.ts +0 -4
  726. package/dist/.test/assets/expo-fullusecase/declarations/practices/tests-expo/best-practice/package.json +0 -9
  727. package/dist/.test/assets/expo-migration/declarations/practices/domain/best-practice/src/domain/objects/index.ts.declapract.ts +0 -4
  728. package/dist/.test/assets/expo-migration/declarations/practices/tests-expo/best-practice/package.json +0 -9
  729. package/dist/.test/assets/expo-toolchain/declarations/practices/tests-expo/best-practice/package.json +0 -9
  730. package/dist/practices/config/best-practice/src/utils/config/Config.ts +0 -10
  731. package/dist/practices/config/best-practice/src/utils/config/Config.ts.declapract.ts +0 -16
  732. package/dist/practices/config/best-practice/src/utils/config/getCacheDirectory.ts +0 -42
  733. package/dist/practices/domain/best-practice/src/domain/objects/index.ts.declapract.ts +0 -4
  734. package/dist/practices/logs/bad-practices/leveled-term/package.json +0 -5
  735. package/dist/practices/persist-with-rds/best-practice/src/utils/config/Config.ts +0 -26
  736. package/dist/practices/persist-with-rds/best-practice/src/utils/config/Config.ts.declapract.ts +0 -39
  737. package/dist/practices/persist-with-rds/best-practice/src/utils/config/config.schema.ts.declapract.ts +0 -49
  738. package/dist/practices/persist-with-rds/best-practice/src/utils/config/getConfig.ts +0 -2
  739. package/dist/practices/tests-expo/best-practice/package.json +0 -9
  740. package/dist/practices/tests-service/defineFunctionNameFromTestFileName.ts +0 -11
  741. /package/dist/.test/assets/{expo-fullusecase/declarations/practices/errors/bad-practices/own-implementation/src/utils/errors/UnexpectedCodePathError.ts.declapract.ts → cicd-service/declarations/practices/cicd-service/bad-practices/old-names/.github/workflows/deploy-dev-on-main.yml.declapract.ts} +0 -0
  742. /package/dist/{practices/errors/bad-practices/own-implementation/src/utils/errors/UnexpectedCodePathError.ts.declapract.ts → .test/assets/cicd-service/declarations/practices/cicd-service/bad-practices/old-names/.github/workflows/deploy-prod-on-tag.yml.declapract.ts} +0 -0
  743. /package/dist/{practices/persist-with-rds/best-practice/src/utils/config/getConfig.ts.declapract.ts → .test/assets/cicd-service/declarations/practices/cicd-service/bad-practices/old-names/.github/workflows/deploy_dev_on_main.yml.declapract.ts} +0 -0
  744. /package/dist/{practices/persist-with-dynamodb/best-practice/jest.integration.env.ts.declapract.ts → .test/assets/cicd-service/declarations/practices/cicd-service/best-practice/package.json.declapract.ts} +0 -0
  745. /package/dist/.test/assets/expo/declarations/practices/node/{best-practice/.npmrc.declapract.integration.test.ts → .npmrc.declapract.integration.test.ts} +0 -0
  746. /package/dist/.test/assets/expo/declarations/practices/node/{best-practice/__snapshots__ → __snapshots__}/.npmrc.declapract.integration.test.ts.snap +0 -0
  747. /package/dist/.test/assets/expo-fullusecase/declarations/practices/node/{best-practice/.npmrc.declapract.integration.test.ts → .npmrc.declapract.integration.test.ts} +0 -0
  748. /package/dist/.test/assets/expo-fullusecase/declarations/practices/node/{best-practice/__snapshots__ → __snapshots__}/.npmrc.declapract.integration.test.ts.snap +0 -0
  749. /package/dist/.test/assets/expo-migration/declarations/practices/node/{best-practice/.npmrc.declapract.integration.test.ts → .npmrc.declapract.integration.test.ts} +0 -0
  750. /package/dist/.test/assets/expo-migration/declarations/practices/node/{best-practice/__snapshots__ → __snapshots__}/.npmrc.declapract.integration.test.ts.snap +0 -0
  751. /package/dist/practices/node/{best-practice/.npmrc.declapract.integration.test.ts → .npmrc.declapract.integration.test.ts} +0 -0
  752. /package/dist/practices/node/{best-practice/__snapshots__ → __snapshots__}/.npmrc.declapract.integration.test.ts.snap +0 -0
@@ -0,0 +1,1285 @@
1
+ import { readFileSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { given, then } from 'test-fns';
4
+
5
+ import {
6
+ fix,
7
+ withInsertOnceBefore,
8
+ withPackageArtifact,
9
+ withPrunePlugin,
10
+ } from './best-practice/serverless.yml.declapract';
11
+
12
+ describe('serverless.yml', () => {
13
+ given(
14
+ 'the exported leaf transformers, exercised independently (r4 n1 recomposition surface)',
15
+ () => {
16
+ // r4 i030 nitpick (arch-opport-decomposition): the with* transformers + withInsertOnceBefore
17
+ // were unexported module-locals, so none could be unit-tested or recomposed independently —
18
+ // only the composed `fix` was exercised, and a per-leaf defect (the withPackageArtifact /
19
+ // withPrunePlugin anchor fragility, i006/i007) hid in a composite snapshot rather than a named
20
+ // leaf assertion. exporting the leaf-most-fragile transformers makes the decomposition an
21
+ // independent surface. these cases exercise them in isolation, off the fold.
22
+
23
+ then('withInsertOnceBefore is idempotent when the guard is already present', () => {
24
+ const held = 'service: x\n\nplugins:\n - serverless-prune-plugin\n\nprovider:\n';
25
+ const out = withInsertOnceBefore({
26
+ contents: held,
27
+ guard: '- serverless-prune-plugin',
28
+ section: 'plugins',
29
+ anchor: /\nprovider:/,
30
+ insert: '\nplugins:\n - serverless-prune-plugin\n\nprovider:',
31
+ });
32
+ expect(out).toEqual(held); // guard hit -> a no-op return
33
+ });
34
+
35
+ then('withInsertOnceBefore soft-skips a pre-extant section with a review marker, not a clobber', () => {
36
+ const legacy = 'service: x\n\nplugins:\n - serverless-esbuild\n\nprovider:\n';
37
+ const out = withInsertOnceBefore({
38
+ contents: legacy,
39
+ guard: '- serverless-prune-plugin',
40
+ section: 'plugins',
41
+ anchor: /\nprovider:/,
42
+ insert: '\nplugins:\n - serverless-prune-plugin\n\nprovider:',
43
+ });
44
+ expect((out.match(/\nplugins:/g) || []).length).toBe(1); // no second plugins: key
45
+ expect(out).toContain('serverless-esbuild'); // consumer plugin preserved
46
+ expect(out).toContain('@declapract:review'); // the actionable marker, not a silent stall
47
+ });
48
+
49
+ then('withInsertOnceBefore lands the insert on an anchor match when absent', () => {
50
+ const bare = 'service: x\n\nprovider:\n name: aws\n';
51
+ const out = withInsertOnceBefore({
52
+ contents: bare,
53
+ guard: 'artifact: .artifact/contents.zip',
54
+ section: 'package',
55
+ anchor: /\nprovider:/,
56
+ insert: '\npackage:\n artifact: .artifact/contents.zip\n\nprovider:',
57
+ });
58
+ expect(out).toContain('package:\n artifact: .artifact/contents.zip');
59
+ });
60
+
61
+ then('withPackageArtifact + withPrunePlugin recompose off the fold', () => {
62
+ const bare = 'service: x\n\nprovider:\n name: aws\n';
63
+ const out = withPrunePlugin({
64
+ contents: withPackageArtifact({ contents: bare }),
65
+ });
66
+ expect(out).toContain('artifact: .artifact/contents.zip');
67
+ expect(out).toContain('plugins:\n - serverless-prune-plugin');
68
+ });
69
+ },
70
+ );
71
+ given('a sls.yaml with STAGE env var', () => {
72
+ const example = `
73
+ service: svc-example
74
+
75
+ provider:
76
+ name: aws
77
+ stage: \${opt:stage}
78
+ environment:
79
+ NODE_ENV: production
80
+ STAGE: \${self:provider.stage} # the deploy stage
81
+ AWS_NODEJS_CONNECTION_REUSE_ENABLED: true
82
+ `.trim();
83
+
84
+ then('it should add accessByStage custom block', async () => {
85
+ const fixed = await fix(example, {} as any);
86
+ expect(fixed.contents).toContain('accessByStage:');
87
+ expect(fixed.contents).toContain('dev: prep'); // stage=dev (ancient slug) uses ACCESS=prep
88
+ expect(fixed.contents).toContain('prod: prod');
89
+ });
90
+
91
+ then('it dual-publishes: accessByStage carries the prep→prep contemp key', async () => {
92
+ // teeth: the north-star dual-publish maps BOTH non-prod stages to the prep access —
93
+ // `dev` (the ancient -dev- fleet) AND `prep` (the contemp -prep- fleet). drop the `prep: prep`
94
+ // entry and self publishes only the ancient slug, so the D31 acceptance suite (which targets
95
+ // the contemp -prep- fleet) lands on a name no deploy publishes. this assertion reddens on
96
+ // that regression.
97
+ const fixed = await fix(example, {} as any);
98
+ expect(fixed.contents).toContain('prep: prep');
99
+ });
100
+
101
+ then('it should replace STAGE with ACCESS + COMMIT', async () => {
102
+ const fixed = await fix(example, {} as any);
103
+ expect(fixed.contents).toContain('ACCESS:');
104
+ expect(fixed.contents).toContain('COMMIT:');
105
+ expect(fixed.contents).not.toContain('STAGE: ${self:provider.stage}');
106
+ });
107
+
108
+ then('it should add variablesResolutionMode after service line', async () => {
109
+ const fixed = await fix(example, {} as any);
110
+ expect(fixed.contents).toContain('variablesResolutionMode: 20210326');
111
+ });
112
+
113
+ then('the composed fix over this example matches snapshot', async () => {
114
+ const fixed = await fix(example, {} as any);
115
+ expect(fixed.contents).toMatchSnapshot('STAGE example — after');
116
+ });
117
+
118
+ then('a second apply is a no-op (fix(fix(x)) === fix(x))', async () => {
119
+ const once = await fix(example, {} as any);
120
+ const twice = await fix(once.contents!, {} as any);
121
+ expect(twice.contents).toEqual(once.contents);
122
+ });
123
+ });
124
+
125
+ given('a sls.yaml that needs the timezone environmental variable', () => {
126
+ const example = `
127
+ service: svc-notifications
128
+
129
+ package:
130
+ artifact: .artifact/contents.zip
131
+
132
+ plugins:
133
+ - serverless-prune-plugin
134
+
135
+ provider:
136
+ name: aws
137
+ runtime: nodejs16.x
138
+ memorySize: 1024 # optional, in MB, default is 1024
139
+ timeout: 60 # default timeout to 1min, for resilience against increased cold start times; individual functions can override this
140
+ stage: \${opt:stage}
141
+ stackTags:
142
+ app: ahbode
143
+ environment: \${self:provider.stage}
144
+ product: \${self:service}
145
+ environment:
146
+ NODE_ENV: production # deploy with production optimizations of all resources
147
+ STAGE: \${self:provider.stage} # the deploy stage
148
+ AWS_NODEJS_CONNECTION_REUSE_ENABLED: true # https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/node-reusing-connections.html
149
+ deploymentBucket: serverless-deployment-xyz-\${self:provider.stage}
150
+ `.trim();
151
+ then('it should be able to add the timezone env var', async () => {
152
+ const fixed = await fix(example, {} as any);
153
+ expect(fixed.contents).toContain('TZ: UTC');
154
+ });
155
+ });
156
+
157
+ given(
158
+ 'a legacy sls.yaml whose NODE_ENV references custom.stageToNodeEnvMapping (r7.b1)',
159
+ () => {
160
+ // r7 i012 blocker: the fix inserts a `custom:` block that holds only `accessByStage`, yet a
161
+ // legacy NODE_ENV reads `${self:custom.stageToNodeEnvMapping.${self:provider.stage}}` — a key
162
+ // the emitted custom: block never declares. the old fix left that reference verbatim, so its
163
+ // own output deploy-failed and failed its own CONTAINS check (which requires the go-forward
164
+ // literal `NODE_ENV: production`). withNodeEnvProduction rewrites the value to the literal.
165
+ const example = `
166
+ service: svc-legacy-nodeenv
167
+
168
+ provider:
169
+ name: aws
170
+ stage: \${opt:stage}
171
+ environment:
172
+ NODE_ENV: \${self:custom.stageToNodeEnvMapping.\${self:provider.stage}}
173
+ deploymentBucket: serverless-deployment-\${self:provider.stage}
174
+ `.trim();
175
+
176
+ then('it rewrites NODE_ENV to the go-forward literal `production`', async () => {
177
+ // teeth: drop withNodeEnvProduction -> this reddens (the legacy reference survives)
178
+ const fixed = (await fix(example, {} as any)).contents ?? '';
179
+ expect(fixed).toContain('NODE_ENV: production');
180
+ });
181
+
182
+ then('it emits no reference to the undeclared stageToNodeEnvMapping key', async () => {
183
+ // teeth: the emitted custom: block declares only accessByStage, so a surviving
184
+ // stageToNodeEnvMapping reference would deploy-fail and fail the fix's own CONTAINS check
185
+ const fixed = (await fix(example, {} as any)).contents ?? '';
186
+ expect(fixed).not.toContain('stageToNodeEnvMapping');
187
+ });
188
+
189
+ then('a second apply is a no-op (fix(fix(x)) === fix(x))', async () => {
190
+ const once = await fix(example, {} as any);
191
+ const twice = await fix(once.contents!, {} as any);
192
+ expect(twice.contents).toEqual(once.contents);
193
+ });
194
+ },
195
+ );
196
+
197
+ given('a sls.yaml that needs account:GetAccountInformation policy', () => {
198
+ const example = `
199
+ service: svc-example
200
+
201
+ provider:
202
+ name: aws
203
+ runtime: nodejs16.x
204
+ iamRoleStatements:
205
+ # parameter store access
206
+ - Effect: Allow
207
+ Action:
208
+ - ssm:GetParameter
209
+ Resource: arn:aws:ssm:\${aws:region}:\${aws:accountId}:parameter/*
210
+ `.trim();
211
+
212
+ then(
213
+ 'it should append GetAccountInformation policy if not already present',
214
+ async () => {
215
+ const fixed = await fix(example, {} as any);
216
+ expect(fixed.contents).toContain('account:GetAccountInformation');
217
+ expect(fixed.contents).toContain(
218
+ '# allow access inference from account name',
219
+ );
220
+ },
221
+ );
222
+
223
+ then(
224
+ 'it should not duplicate GetAccountInformation policy if already present',
225
+ async () => {
226
+ const exampleWithPolicy = `
227
+ service: svc-example
228
+
229
+ provider:
230
+ name: aws
231
+ runtime: nodejs16.x
232
+ iamRoleStatements:
233
+ # allow access inference from account name
234
+ - Effect: Allow
235
+ Action:
236
+ - account:GetAccountInformation
237
+ Resource: '*'
238
+ `.trim();
239
+ const fixed = await fix(exampleWithPolicy, {} as any);
240
+ const matches = (
241
+ fixed.contents?.match(/account:GetAccountInformation/g) || []
242
+ ).length;
243
+ expect(matches).toBe(1);
244
+ },
245
+ );
246
+ });
247
+
248
+ given('a sls.yaml whose service line carries an inline comment (D41)', () => {
249
+ const example = `
250
+ service: svc-example # the primary example service
251
+
252
+ provider:
253
+ name: aws
254
+ stage: \${opt:stage}
255
+ `.trim();
256
+
257
+ then('it should still insert the package artifact block', async () => {
258
+ const fixed = await fix(example, {} as any);
259
+ // teeth: the old /service: ([a-zA-Z0-9-]+)\\n\\n?provider:/ anchor failed on a commented
260
+ // service line, so this insert silently never landed.
261
+ expect(fixed.contents).toContain('artifact: .artifact/contents.zip');
262
+ });
263
+
264
+ then('it should still insert variablesResolutionMode', async () => {
265
+ const fixed = await fix(example, {} as any);
266
+ expect(fixed.contents).toContain('variablesResolutionMode: 20210326');
267
+ });
268
+
269
+ then('it should preserve the inline comment on the service line', async () => {
270
+ const fixed = await fix(example, {} as any);
271
+ expect(fixed.contents).toContain(
272
+ 'service: svc-example # the primary example service',
273
+ );
274
+ });
275
+ });
276
+
277
+ given('a sls.yaml whose service name carries an underscore (r7.n3)', () => {
278
+ // r7 i012 nitpick: the old anchor `/^service: [a-zA-Z0-9-]+/m` never matched a legal service
279
+ // name with an underscore (`svc_orders`), so variablesResolutionMode soft-skipped for a valid
280
+ // name. the widened `\\S[^\\n]*` name class matches ANY legal service name, so it converges.
281
+ const example = `
282
+ service: svc_orders
283
+
284
+ provider:
285
+ name: aws
286
+ stage: \${opt:stage}
287
+ `.trim();
288
+
289
+ then('it inserts variablesResolutionMode after an underscore service name', async () => {
290
+ // teeth: revert the anchor to [a-zA-Z0-9-]+ -> this reddens (svc_orders never matches)
291
+ const fixed = (await fix(example, {} as any)).contents ?? '';
292
+ expect(fixed).toContain('variablesResolutionMode: 20210326');
293
+ expect(fixed).toContain('service: svc_orders');
294
+ });
295
+ });
296
+
297
+ given(
298
+ 'a sls.yaml with a block between service: and provider:, no plugins block yet',
299
+ () => {
300
+ // r10/r11 i006 blocker: withPackageArtifact anchored on `service: ...\n\n?provider:`, so a
301
+ // block that sits between service: and provider: made it (and its paired withPrunePlugin) a
302
+ // silent no-op. this isolates the case the legacy fixture does not — a block between them AND
303
+ // no plugins block yet, so withPrunePlugin must CREATE one.
304
+ const example = `
305
+ service: svc-isolated
306
+
307
+ frameworkVersion: '3'
308
+
309
+ provider:
310
+ name: aws
311
+ stage: \${opt:stage}
312
+ `.trim();
313
+
314
+ then('it inserts the package artifact despite the block between', async () => {
315
+ const fixed = (await fix(example, {} as any)).contents ?? '';
316
+ // teeth: revert the provider:-anchor -> this reddens (the old regex could not fire here)
317
+ expect(fixed).toContain('package:\n artifact: .artifact/contents.zip');
318
+ });
319
+
320
+ then('it CREATES a plugins block with the prune plugin (none present)', async () => {
321
+ const fixed = (await fix(example, {} as any)).contents ?? '';
322
+ expect(fixed).toContain('plugins:\n - serverless-prune-plugin');
323
+ expect((fixed.match(/\nplugins:/g) || []).length).toBe(1);
324
+ });
325
+
326
+ then('a second apply is a no-op (fix(fix(x)) === fix(x))', async () => {
327
+ const once = await fix(example, {} as any);
328
+ const twice = await fix(once.contents!, {} as any);
329
+ expect(twice.contents).toEqual(once.contents);
330
+ });
331
+ },
332
+ );
333
+
334
+ given(
335
+ 'a sls.yaml whose package: block carries an extra key after artifact: (D41 prune anchor)',
336
+ () => {
337
+ // r11 i007 blocker: withPrunePlugin anchored on the literal bytes withPackageArtifact emits
338
+ // (` artifact: .artifact/contents.zip\n\nprovider:`), so a package: block with ANY other key
339
+ // after artifact: (individually:, patterns:, … — all common) silently defeated the anchor and
340
+ // the prune plugin was never inserted — the exact silent-no-op class i006 fixed for
341
+ // withPackageArtifact, reproduced one function over. the structural /\nprovider:/ anchor holds
342
+ // regardless of the package: block's shape.
343
+ const example = `
344
+ service: svc-extra
345
+
346
+ package:
347
+ artifact: .artifact/contents.zip
348
+ individually: true
349
+
350
+ provider:
351
+ name: aws
352
+ stage: \${opt:stage}
353
+ `.trim();
354
+
355
+ then('it still inserts the prune plugin despite the extra package key', async () => {
356
+ const fixed = (await fix(example, {} as any)).contents ?? '';
357
+ // teeth: revert withPrunePlugin's anchor to the literal-output coupled form -> this reddens
358
+ // (the old literal anchor cannot match past the `individually:` key)
359
+ expect(fixed).toContain('plugins:\n - serverless-prune-plugin');
360
+ expect((fixed.match(/\nplugins:/g) || []).length).toBe(1);
361
+ // the pre-existent package key survives untouched
362
+ expect(fixed).toContain('individually: true');
363
+ });
364
+
365
+ then('a second apply is a no-op (fix(fix(x)) === fix(x))', async () => {
366
+ const once = await fix(example, {} as any);
367
+ const twice = await fix(once.contents!, {} as any);
368
+ expect(twice.contents).toEqual(once.contents);
369
+ });
370
+ },
371
+ );
372
+
373
+ given('a sls.yaml with no provider: key at all (anchor-miss soft-skip)', () => {
374
+ // r7 i012 blocker: withInsertOnceBefore SOFT-SKIPS an anchor miss (returns the contents
375
+ // unchanged), it does not throw. a throw aborts the whole 14-transform fold, so a common
376
+ // arrival shape would block every unrelated repair. the un-inserted block is absent from the
377
+ // output, so the overall CONTAINS check (which requires it) reddens `declapract plan` — the
378
+ // signal. a file absent a provider: key gives withPackageArtifact's insert no anchor to land.
379
+ const example = `
380
+ service: svc-noprovider
381
+
382
+ frameworkVersion: '3'
383
+ `.trim();
384
+
385
+ then('the package artifact soft-skips (no provider: anchor to land before)', () => {
386
+ // teeth: give withInsertOnceBefore a throw-on-miss again -> the whole fix throws instead of
387
+ // a partial return; the soft-skip returns the contents with the block absent.
388
+ const fixed = fix(example, {} as any).contents ?? '';
389
+ expect(fixed).not.toContain('artifact: .artifact/contents.zip');
390
+ });
391
+
392
+ then('a peer transform whose anchor DOES match still lands (no chain abort)', () => {
393
+ // teeth: variablesResolutionMode anchors on the `service:` line (present), so it lands even
394
+ // though withPackageArtifact soft-skipped — proof one miss does not abort the fold.
395
+ const fixed = fix(example, {} as any).contents ?? '';
396
+ expect(fixed).toContain('variablesResolutionMode: 20210326');
397
+ });
398
+
399
+ then('a second apply is a no-op (fix(fix(x)) === fix(x))', async () => {
400
+ const once = await fix(example, {} as any);
401
+ const twice = await fix(once.contents!, {} as any);
402
+ expect(twice.contents).toEqual(once.contents);
403
+ });
404
+ });
405
+
406
+ given(
407
+ 'a legacy sls.yaml that already holds a section under different content (r7 clobber-refusal)',
408
+ () => {
409
+ // r5 i008 blocker (arch-hazards-behavior): the section-insert transformers guarded only on
410
+ // DECLARED CONTENT, so a consumer whose legacy file already holds a `package:` / `plugins:` /
411
+ // `custom:` block under DIFFERENT content got a SECOND top-level key inserted — a yaml
412
+ // last-wins clobber that silently drops the consumer's block while CONTAINS still passes.
413
+ // r7 i012 blocker: the decline of that duplicate must not THROW (a throw aborts the whole
414
+ // fold and blocks every peer repair). the `section` guard now SOFT-SKIPS the insert, so no
415
+ // second key lands (the consumer's block is never clobbered) AND the peer transforms still
416
+ // land; CONTAINS (which requires the declared block) reddens `plan` to surface the manual merge.
417
+
418
+ then('it declines a second package: block, and never clobbers the consumer key', () => {
419
+ const example = `
420
+ service: svc-haspackage
421
+
422
+ package:
423
+ individually: true
424
+
425
+ provider:
426
+ name: aws
427
+ stage: \${opt:stage}
428
+ `.trim();
429
+ // teeth: drop the `section: 'package'` guard -> a SECOND top-level package: key lands
430
+ // (a yaml last-wins clobber of `individually: true`); with the guard, exactly one remains.
431
+ const fixed = fix(example, {} as any).contents ?? '';
432
+ expect((fixed.match(/\npackage:/g) || []).length).toBe(1);
433
+ expect(fixed).toContain('individually: true');
434
+ });
435
+
436
+ then('it declines a second plugins: block, and never clobbers the consumer plugin', () => {
437
+ const example = `
438
+ service: svc-hasplugins
439
+
440
+ plugins:
441
+ - serverless-esbuild
442
+
443
+ provider:
444
+ name: aws
445
+ stage: \${opt:stage}
446
+ `.trim();
447
+ // teeth: drop the `section: 'plugins'` guard -> a SECOND top-level plugins: key lands, and
448
+ // yaml last-wins silently drops the consumer's serverless-esbuild plugin.
449
+ const fixed = fix(example, {} as any).contents ?? '';
450
+ expect((fixed.match(/\nplugins:/g) || []).length).toBe(1);
451
+ expect(fixed).toContain('serverless-esbuild');
452
+ });
453
+
454
+ then('it declines a second custom: block, and never clobbers the consumer custom', () => {
455
+ const example = `
456
+ service: svc-hascustom
457
+
458
+ custom:
459
+ domain: api.example.com
460
+
461
+ provider:
462
+ name: aws
463
+ stage: \${opt:stage}
464
+ `.trim();
465
+ // teeth: drop the `section: 'custom'` guard -> a SECOND top-level custom: key lands, and
466
+ // yaml last-wins silently drops the consumer's custom block.
467
+ const fixed = fix(example, {} as any).contents ?? '';
468
+ expect((fixed.match(/\ncustom:/g) || []).length).toBe(1);
469
+ expect(fixed).toContain('domain: api.example.com');
470
+ });
471
+
472
+ // .note = the marker is a COMPENSATION, not the endpoint: a consumer who runs `declapract
473
+ // plan` still reads only green/red, so the in-file marker text is the sole
474
+ // could-not-fire signal. the durable "could-not-fire vs passed" plan signal is owed
475
+ // upstream (ehmpathy/declapract#107); until it lands, the snapshot below clamps the
476
+ // marker text so a reword cannot silently drop the diagnostic.
477
+ then('the section soft-skip injects an actionable @declapract:review marker, not a silent stall', () => {
478
+ const example = `
479
+ service: svc-hascustom
480
+
481
+ custom:
482
+ domain: api.example.com
483
+
484
+ provider:
485
+ name: aws
486
+ stage: \${opt:stage}
487
+ `.trim();
488
+ const fixed = fix(example, {} as any).contents ?? '';
489
+ // r9 i022 blocker: the soft-skip must name the hand-merge, not return unchanged. the marker
490
+ // is injected above the extant custom: block and names the section to merge.
491
+ expect(fixed).toContain('@declapract:review');
492
+ expect(fixed).toContain('merge the declared `custom` keys');
493
+ expect(fixed).toContain('into your extant `custom:` block by hand');
494
+ // and CONTAINS stays red — the marker does NOT auto-satisfy the declared accessByStage key
495
+ expect(fixed).not.toContain('accessByStage:');
496
+ // teeth: a silent return (no marker) reddens this — the consumer would get no diagnostic
497
+ // snapshot the marker verbatim — it is user-faced output; a reword must redden a vibecheck,
498
+ // not slip past the toContain asserts above (rule.require.snapshots)
499
+ expect(fixed).toMatchSnapshot('section soft-skip custom clobber — review marker');
500
+ });
501
+
502
+ then('the marker injection is idempotent (a second fix adds no second marker)', () => {
503
+ const example = `
504
+ service: svc-hascustom
505
+
506
+ custom:
507
+ domain: api.example.com
508
+
509
+ provider:
510
+ name: aws
511
+ stage: \${opt:stage}
512
+ `.trim();
513
+ const once = fix(example, {} as any).contents ?? '';
514
+ const twice = fix(once, {} as any).contents ?? '';
515
+ // fixed point: a re-run over the marked file changes zero bytes
516
+ expect(twice).toEqual(once);
517
+ // exactly one marker, never a stack of them across runs
518
+ expect((twice.match(/@declapract:review — a `custom:`/g) || []).length).toBe(1);
519
+ });
520
+
521
+ then('a peer transform still lands despite the section soft-skip (no chain abort)', () => {
522
+ const example = `
523
+ service: svc-haspackage
524
+
525
+ package:
526
+ individually: true
527
+
528
+ provider:
529
+ name: aws
530
+ stage: \${opt:stage}
531
+ `.trim();
532
+ // teeth: variablesResolutionMode lands even though withPackageArtifact soft-skipped the
533
+ // clobber — proof the section soft-skip does not abort the fold.
534
+ const fixed = fix(example, {} as any).contents ?? '';
535
+ expect(fixed).toContain('variablesResolutionMode: 20210326');
536
+ });
537
+
538
+ then('it emits no ACCESS ref to custom.access when withAccessByStage soft-skipped (r7 b1 unresolvable-ref)', () => {
539
+ // r7 i030 blocker (arch-hazards-behavior): a legacy consumer with a pre-extant top-level
540
+ // `custom:` block makes withAccessByStage soft-skip its accessByStage/access insert (it only
541
+ // injects a review marker), so `custom.access` is never declared. withAccessCommitEnv,
542
+ // however, guarded only on `STAGE:` present + `ACCESS:` absent — so it still rewrote STAGE ->
543
+ // `ACCESS: ${self:custom.access}`, a ref to a var the output never declares (a
544
+ // caller-without-callee that fails serverless variable resolution at deploy). the new
545
+ // `!includes('accessByStage:')` guard soft-skips this rewrite until that block lands.
546
+ const example = `
547
+ service: svc-hascustom-stage
548
+
549
+ custom:
550
+ domain: api.example.com
551
+
552
+ provider:
553
+ name: aws
554
+ stage: \${opt:stage}
555
+ environment:
556
+ NODE_ENV: production
557
+ STAGE: \${self:provider.stage} # the deploy stage
558
+ `.trim();
559
+ const fixed = fix(example, {} as any).contents ?? '';
560
+ // the block that would declare custom.access did soft-skip (a custom: block already exists)
561
+ expect(fixed).not.toContain('accessByStage:');
562
+ // teeth: drop the `!includes('accessByStage:')` guard from withAccessCommitEnv -> the rewrite
563
+ // fires anyway and emits `ACCESS: ${self:custom.access}` against no declaration; this reddens.
564
+ expect(fixed).not.toContain('ACCESS: ${self:custom.access}');
565
+ // and the STAGE var is left intact for the human's later hand-merge + a subsequent fix pass
566
+ expect(fixed).toContain('STAGE: ${self:provider.stage}');
567
+ });
568
+
569
+ then('the unresolvable-ref soft-skip is idempotent (a second fix adds no ACCESS ref)', () => {
570
+ const example = `
571
+ service: svc-hascustom-stage
572
+
573
+ custom:
574
+ domain: api.example.com
575
+
576
+ provider:
577
+ name: aws
578
+ stage: \${opt:stage}
579
+ environment:
580
+ NODE_ENV: production
581
+ STAGE: \${self:provider.stage} # the deploy stage
582
+ `.trim();
583
+ const once = fix(example, {} as any).contents ?? '';
584
+ const twice = fix(once, {} as any).contents ?? '';
585
+ expect(twice).toEqual(once);
586
+ expect(twice).not.toContain('ACCESS: ${self:custom.access}');
587
+ });
588
+ },
589
+ );
590
+
591
+ given(
592
+ 'a sls.yaml whose environment block exists but the anchors miss (r7 soft-skip)',
593
+ () => {
594
+ // r7 i012 blocker: withUtcTimezone / withConnectionReuse anchored on exact byte sequences,
595
+ // and threw on a miss — an abort of the whole fold for a common shape (a var before NODE_ENV,
596
+ // or no deploymentBucket line). the throw was dropped: a miss now SOFT-SKIPS (returns unchanged),
597
+ // so a single miss never aborts the fold.
598
+ // i034 r008.b2 then CONVERGED withConnectionReuse: its anchor is now the NODE_ENV line ALONE,
599
+ // so the no-deploymentBucket shape lands the flag rather than a red-forever stall. withUtcTimezone
600
+ // still cannot land the line on a var-before-NODE_ENV shape (a convergent widen there risks a
601
+ // per-function `environment:` block, deferred to
602
+ // .dream/v2026_09_10.fix.serverless-soft-skip-convergence.md) — but i035 r009.b1 replaced its
603
+ // bare no-op with an actionable `@declapract:review` marker that names the shape to converge, so
604
+ // a live consumer sees WHICH shape failed rather than a silent stall while peers land.
605
+
606
+ then('withUtcTimezone emits an actionable review marker when NODE_ENV sits below another env var', () => {
607
+ // environment: exists, but STAGE precedes NODE_ENV, so `environment:\n NODE_ENV:` misses
608
+ const example = `
609
+ service: svc-shuffled
610
+
611
+ provider:
612
+ name: aws
613
+ environment:
614
+ STAGE: \${self:provider.stage}
615
+ NODE_ENV: production
616
+ `.trim();
617
+ const fixed = fix(example, {} as any).contents ?? '';
618
+ // the env line still cannot land on this shape (CONTAINS reddens the absent TZ line). the
619
+ // emitted env child carries a trailing comment, so match that exact form — the marker text
620
+ // itself names `TZ: UTC`, so a bare substring check would false-pass on the marker.
621
+ expect(fixed).not.toContain('TZ: UTC # guarantee');
622
+ // i035 r009.b1 teeth: the soft-skip is NOT silent — it emits a marker that names the line + why
623
+ // the auto-insert declined. revert withUtcTimezone's else-branch to a bare `.replace` no-op
624
+ // and this reddens (no marker), the non-convergent-with-no-diagnostic class the rule forbids.
625
+ expect(fixed).toContain('@declapract:review');
626
+ expect(fixed).toContain('add `TZ: UTC`'); // named inside the marker as the line to add by hand
627
+ // a peer transform still lands: STAGE -> ACCESS + COMMIT
628
+ expect(fixed).toContain('ACCESS:');
629
+ // snapshot the marker verbatim — user-faced output; a reword must redden a vibecheck, not
630
+ // slip past the toContain asserts above (rule.require.snapshots)
631
+ expect(fixed).toMatchSnapshot('withUtcTimezone shuffled-env — review marker');
632
+ });
633
+
634
+ then('the withUtcTimezone review marker is idempotent (a second apply adds no duplicate)', () => {
635
+ const example = `
636
+ service: svc-shuffled
637
+
638
+ provider:
639
+ name: aws
640
+ environment:
641
+ STAGE: \${self:provider.stage}
642
+ NODE_ENV: production
643
+ `.trim();
644
+ const once = fix(example, {} as any).contents ?? '';
645
+ const twice = fix(once, {} as any).contents ?? '';
646
+ expect(twice).toEqual(once);
647
+ // exactly one TZ marker, never a re-inserted or duplicated comment line (this shape now
648
+ // converges withConnectionReuse via the go-forward `NODE_ENV: production` anchor, so the TZ
649
+ // marker is the only one — assert its count is 1)
650
+ expect((twice.match(/could not auto-insert `TZ: UTC`/g) || []).length).toBe(1);
651
+ });
652
+
653
+ then('withConnectionReuse CONVERGES on a go-forward `NODE_ENV: production` file that lacks the flag (i035 r008.n3)', () => {
654
+ // an env block already on the go-forward `NODE_ENV: production` (not the legacy map) that
655
+ // lacks the flag — e.g. it was hand-edited out. the legacy anchor misses, but the go-forward
656
+ // anchor lands the flag on the next line, so the file CONVERGES rather than a marker-only red
657
+ // plan. TZ is already present so withUtcTimezone skips cleanly.
658
+ const example = `
659
+ service: svc-goforward
660
+
661
+ provider:
662
+ name: aws
663
+ environment:
664
+ TZ: UTC
665
+ NODE_ENV: production
666
+ `.trim();
667
+ const fixed = fix(example, {} as any).contents ?? '';
668
+ // teeth: the go-forward anchor lands the flag directly after the production line. remove the
669
+ // `NODE_ENV: production` go-forward branch in withConnectionReuse and this reddens (the flag
670
+ // never lands, and the shape falls back to a marker — the r008.n3 non-convergence class).
671
+ expect(fixed).toContain(
672
+ 'NODE_ENV: production\n AWS_NODEJS_CONNECTION_REUSE_ENABLED: true # https',
673
+ );
674
+ // no marker for the flag — it converged, not merely diagnosed
675
+ expect(fixed).not.toContain(
676
+ 'could not auto-insert `AWS_NODEJS_CONNECTION_REUSE_ENABLED: true`',
677
+ );
678
+ // idempotent: a second apply is a no-op (the includes-guard fires)
679
+ const twice = fix(fixed, {} as any).contents ?? '';
680
+ expect(twice).toEqual(fixed);
681
+ });
682
+
683
+ then('withConnectionReuse CONVERGES when there is no deploymentBucket line (i034 r008.b2)', () => {
684
+ // environment: exists with the NODE_ENV map, TZ already present (so withUtcTimezone skips),
685
+ // and NO deploymentBucket line. the anchor is now the NODE_ENV line ALONE (i034 r008.b2), so
686
+ // the flag lands regardless of what succeeds the environment block — no red-forever for the
687
+ // no-deploymentBucket shape.
688
+ const example = `
689
+ service: svc-nobucket
690
+
691
+ provider:
692
+ name: aws
693
+ environment:
694
+ TZ: UTC
695
+ NODE_ENV: \${self:custom.stageToNodeEnvMapping.\${self:provider.stage}}
696
+ `.trim();
697
+ // teeth: restore the old two-line anchor (require `\n deploymentBucket` after NODE_ENV) ->
698
+ // this reddens (the flag is never landed for a file with no deploymentBucket line).
699
+ const fixed = fix(example, {} as any).contents ?? '';
700
+ expect(fixed).toContain('AWS_NODEJS_CONNECTION_REUSE_ENABLED: true');
701
+ // the flag lands at env indent, directly after the NODE_ENV line. the full fix() pipeline
702
+ // runs withConnectionReuse (lands the flag after the legacy NODE_ENV line) THEN
703
+ // withNodeEnvProduction (rewrites that NODE_ENV line to the go-forward `production` literal),
704
+ // so the converged adjacency is `NODE_ENV: production` + the flag on the next env-indent line.
705
+ expect(fixed).toContain(
706
+ 'NODE_ENV: production # deploy with production optimizations of all resources, to make `prep` and `prod` stage deployments equivalent functionally (i.e., the same code paths in prep and prod)\n AWS_NODEJS_CONNECTION_REUSE_ENABLED: true',
707
+ );
708
+ // idempotent: a second apply is a no-op (the includes-guard fires)
709
+ const twice = fix(fixed, {} as any).contents ?? '';
710
+ expect(twice).toEqual(fixed);
711
+ });
712
+ },
713
+ );
714
+
715
+ given(
716
+ 'a sls.yaml whose ssm grant is list-form or an unmatched shape (r9 non-convergence)',
717
+ () => {
718
+ // r9 i011 blocker: withSsmGetParameter anchored ONLY on the inline `Action: 'ssm:GetParameters'`
719
+ // form, so a consumer on the list-item form (`Action:\n - ssm:GetParameters`) got a silent
720
+ // no-op — the singular grant was never added and CONTAINS stayed red. the transformer now
721
+ // handles BOTH plural shapes, and SOFT-SKIPS a third shape neither anchor matched.
722
+
723
+ then('it augments the list-item plural form with the singular', async () => {
724
+ const example = `
725
+ service: svc-listform
726
+
727
+ provider:
728
+ name: aws
729
+ iamRoleStatements:
730
+ - Effect: Allow
731
+ Action:
732
+ - ssm:GetParameters
733
+ Resource: arn:aws:ssm:\${aws:region}:\${aws:accountId}:parameter/*
734
+ `.trim();
735
+ // teeth: drop the list-form branch -> this reddens (the inline anchor misses the list form
736
+ // and the fix soft-skips, so the singular stays ungranted)
737
+ const fixed = (await fix(example, {} as any)).contents ?? '';
738
+ expect(fixed).toContain('- ssm:GetParameter\n');
739
+ expect(fixed).toContain('- ssm:GetParameters');
740
+ });
741
+
742
+ then('a second apply over the list-form fix is a no-op', async () => {
743
+ const example = `
744
+ service: svc-listform
745
+
746
+ provider:
747
+ name: aws
748
+ iamRoleStatements:
749
+ - Effect: Allow
750
+ Action:
751
+ - ssm:GetParameters
752
+ Resource: arn:aws:ssm:\${aws:region}:\${aws:accountId}:parameter/*
753
+ `.trim();
754
+ const once = await fix(example, {} as any);
755
+ const twice = await fix(once.contents!, {} as any);
756
+ expect(twice.contents).toEqual(once.contents);
757
+ });
758
+
759
+ then('it grants the singular to EVERY plural block, not just the first (global)', async () => {
760
+ // two separate statements each grant ssm:GetParameters; the fix must add the singular to
761
+ // BOTH — a first-only replace leaves the second block under-granted and CONTAINS red for it.
762
+ const example = `
763
+ service: svc-twoblocks
764
+
765
+ provider:
766
+ name: aws
767
+ iamRoleStatements:
768
+ - Effect: Allow
769
+ Action:
770
+ - ssm:GetParameters
771
+ Resource: arn:aws:ssm:\${aws:region}:\${aws:accountId}:parameter/one/*
772
+ - Effect: Allow
773
+ Action:
774
+ - ssm:GetParameters
775
+ Resource: arn:aws:ssm:\${aws:region}:\${aws:accountId}:parameter/two/*
776
+ `.trim();
777
+ // teeth: drop the /g flag from the list-form replace -> only the first block gains the
778
+ // singular -> this count assertion reddens (1, not 2).
779
+ const fixed = (await fix(example, {} as any)).contents ?? '';
780
+ expect((fixed.match(/- ssm:GetParameter\n/g) || []).length).toEqual(2);
781
+ // and a re-run stays a no-op across BOTH blocks (per-occurrence idempotency, global)
782
+ const twice = (await fix(fixed, {} as any)).contents ?? '';
783
+ expect(twice).toEqual(fixed);
784
+ });
785
+
786
+ then('it soft-skips when the plural sits in a shape neither anchor matched', () => {
787
+ // a double-quoted inline plural matches neither the single-quoted inline anchor nor the
788
+ // list-item anchor, so the singular cannot be granted automatically
789
+ const example = `
790
+ service: svc-quoted
791
+
792
+ provider:
793
+ name: aws
794
+ iamRoleStatements:
795
+ - Effect: Allow
796
+ Action: "ssm:GetParameters"
797
+ Resource: arn:aws:ssm:\${aws:region}:\${aws:accountId}:parameter/*
798
+ `.trim();
799
+ // teeth: give withSsmGetParameter a throw-on-miss -> the whole fix throws; the soft-skip
800
+ // leaves the singular ungranted (CONTAINS reddens plan) and preserves the plural verbatim.
801
+ const fixed = fix(example, {} as any).contents ?? '';
802
+ expect(fixed).not.toContain('- ssm:GetParameter\n');
803
+ expect(fixed).toContain('"ssm:GetParameters"');
804
+ });
805
+ },
806
+ );
807
+
808
+ given(
809
+ 'a legacy sls.yaml with a stage-keyed deploymentBucket (i031 r2.b1 non-convergence)',
810
+ () => {
811
+ // i031 r2 blocker (mech-failhides): #596 added `custom.deploymentBucketByStage` + a
812
+ // `provider.deploymentBucket` that reads the map to the template, governed by CONTAINS, plus a
813
+ // template clamp — but NO transform emitted either, so a legacy consumer (old
814
+ // `deploymentBucket: <base>-${self:provider.stage}` line, no map) ran `declapract fix`, the map
815
+ // was never added, and CONTAINS stayed RED forever with no diagnostic — a non-convergent fix
816
+ // (the row-1 class the wish forbids). worse, the stale stage-keyed line resolves to a
817
+ // nonexistent `-prep` bucket on a prep deploy (only -dev + -prod exist) — the #596 break itself.
818
+ // withDeploymentBucketByStage derives the bucket base from the consumer's own line (never a
819
+ // guess) and emits the map + rewrites the reference.
820
+
821
+ then('it emits the deploymentBucketByStage map, base derived from the consumer line (with ns)', async () => {
822
+ const example = `
823
+ service: svc-orders
824
+
825
+ provider:
826
+ name: aws
827
+ stage: \${opt:stage}
828
+ environment:
829
+ NODE_ENV: production
830
+ STAGE: \${self:provider.stage} # the deploy stage
831
+ deploymentBucket: serverless-deployment-orders-\${self:provider.stage}
832
+ `.trim();
833
+ // teeth: drop withDeploymentBucketByStage from the fold -> all three of these redden (the map
834
+ // is never emitted and the stale stage-keyed reference survives).
835
+ const fixed = (await fix(example, {} as any)).contents ?? '';
836
+ expect(fixed).toContain('deploymentBucketByStage:');
837
+ expect(fixed).toContain('dev: serverless-deployment-orders-dev');
838
+ expect(fixed).toContain('prep: serverless-deployment-orders-dev');
839
+ expect(fixed).toContain('prod: serverless-deployment-orders-prod');
840
+ });
841
+
842
+ then('it rewrites the stage-keyed reference to the map, no bare -${stage} name survives', async () => {
843
+ const example = `
844
+ service: svc-orders
845
+
846
+ provider:
847
+ name: aws
848
+ stage: \${opt:stage}
849
+ environment:
850
+ NODE_ENV: production
851
+ STAGE: \${self:provider.stage} # the deploy stage
852
+ deploymentBucket: serverless-deployment-orders-\${self:provider.stage}
853
+ `.trim();
854
+ const fixed = (await fix(example, {} as any)).contents ?? '';
855
+ expect(fixed).toContain(
856
+ "deploymentBucket: ${self:custom.deploymentBucketByStage.${opt:stage}, 'serverless-deployment-orders-dev'}",
857
+ );
858
+ // teeth: the stale stage-keyed provider line — the #596 break — is gone
859
+ expect(fixed).not.toContain(
860
+ 'deploymentBucket: serverless-deployment-orders-${self:provider.stage}',
861
+ );
862
+ });
863
+
864
+ then('it derives a base with no namespace segment too', async () => {
865
+ // the no-ns legacy shape `serverless-deployment-${self:provider.stage}` (the fixture used by
866
+ // the timezone + full-composed givens): base derives to `serverless-deployment`.
867
+ const example = `
868
+ service: svc-nons
869
+
870
+ provider:
871
+ name: aws
872
+ stage: \${opt:stage}
873
+ environment:
874
+ NODE_ENV: production
875
+ STAGE: \${self:provider.stage} # the deploy stage
876
+ deploymentBucket: serverless-deployment-\${self:provider.stage}
877
+ `.trim();
878
+ const fixed = (await fix(example, {} as any)).contents ?? '';
879
+ expect(fixed).toContain('dev: serverless-deployment-dev');
880
+ expect(fixed).toContain('prod: serverless-deployment-prod');
881
+ expect(fixed).toContain(
882
+ "deploymentBucket: ${self:custom.deploymentBucketByStage.${opt:stage}, 'serverless-deployment-dev'}",
883
+ );
884
+ });
885
+
886
+ then('a second apply is a no-op (fix(fix(x)) === fix(x))', async () => {
887
+ const example = `
888
+ service: svc-orders
889
+
890
+ provider:
891
+ name: aws
892
+ stage: \${opt:stage}
893
+ environment:
894
+ NODE_ENV: production
895
+ STAGE: \${self:provider.stage} # the deploy stage
896
+ deploymentBucket: serverless-deployment-orders-\${self:provider.stage}
897
+ `.trim();
898
+ const once = await fix(example, {} as any);
899
+ const twice = await fix(once.contents!, {} as any);
900
+ expect(twice.contents).toEqual(once.contents);
901
+ });
902
+
903
+ then('it emits no deploymentBucketByStage ref when withAccessByStage soft-skipped (caller-without-callee)', () => {
904
+ // a legacy consumer with a pre-extant top-level `custom:` block makes withAccessByStage
905
+ // soft-skip (a review marker, no accessByStage:), so custom.deploymentBucketByStage is never
906
+ // declared. teeth: drop the `!includes('accessByStage:')` guard -> the map-reference emits
907
+ // against no declaration (a caller-without-callee); this reddens.
908
+ const example = `
909
+ service: svc-hascustom-bucket
910
+
911
+ custom:
912
+ domain: api.example.com
913
+
914
+ provider:
915
+ name: aws
916
+ stage: \${opt:stage}
917
+ deploymentBucket: serverless-deployment-orders-\${self:provider.stage}
918
+ `.trim();
919
+ const fixed = fix(example, {} as any).contents ?? '';
920
+ expect(fixed).not.toContain('accessByStage:');
921
+ expect(fixed).not.toContain('deploymentBucketByStage:');
922
+ // the stale stage-keyed line is left intact for the human's hand-merge + a later fix pass
923
+ expect(fixed).toContain(
924
+ 'deploymentBucket: serverless-deployment-orders-${self:provider.stage}',
925
+ );
926
+ });
927
+
928
+ then('it soft-skips a consumer with no deploymentBucket line (no base to derive, no guess)', async () => {
929
+ // a value the fix cannot know is never invented: no bucket line -> no base -> soft-skip, and
930
+ // CONTAINS surfaces the residual as a red plan rather than a guessed namespace.
931
+ const example = `
932
+ service: svc-nobucket-at-all
933
+
934
+ provider:
935
+ name: aws
936
+ stage: \${opt:stage}
937
+ environment:
938
+ NODE_ENV: production
939
+ STAGE: \${self:provider.stage} # the deploy stage
940
+ `.trim();
941
+ const fixed = (await fix(example, {} as any)).contents ?? '';
942
+ // accessByStage still lands (its own transform fired) — proof the soft-skip is local
943
+ expect(fixed).toContain('accessByStage:');
944
+ // but no map is invented from a namespace the fix does not hold
945
+ expect(fixed).not.toContain('deploymentBucketByStage:');
946
+ // AND the silent soft-skip is truly silent: no review marker on a bucket-less file
947
+ expect(fixed).not.toContain('@declapract:review');
948
+ expect(fixed).not.toContain(
949
+ 'could not derive an account-scoped `deploymentBucketByStage`',
950
+ );
951
+ });
952
+
953
+ then('it emits a review marker when a deploymentBucket line exists but misses the legacy shape', async () => {
954
+ // r10 nitpick: a `deploymentBucket:` line present in a shape the fix cannot read (not the
955
+ // legacy `serverless-deployment...-${self:provider.stage}` pattern) gets a NAMED next step,
956
+ // in step with the env-insert soft-skips — not a silent no-op that reads as "no action owed".
957
+ const example = `
958
+ service: svc-odd-bucket
959
+
960
+ provider:
961
+ name: aws
962
+ stage: \${opt:stage}
963
+ deploymentBucket: my-custom-hardcoded-bucket
964
+ environment:
965
+ NODE_ENV: production
966
+ STAGE: \${self:provider.stage} # the deploy stage
967
+ `.trim();
968
+ const fixed = (await fix(example, {} as any)).contents ?? '';
969
+ // teeth: drop the `includes('deploymentBucket:')` guard's marker branch -> this reddens (a
970
+ // non-matching bucket line would then soft-skip silently, the exact silent no-op r10 flagged)
971
+ expect(fixed).toContain('@declapract:review');
972
+ expect(fixed).toContain(
973
+ 'could not derive an account-scoped `deploymentBucketByStage`',
974
+ );
975
+ // still no invented map (the base is unknowable) — the marker is the deliverable, not a guess
976
+ expect(fixed).not.toContain('deploymentBucketByStage:\n');
977
+ });
978
+ },
979
+ );
980
+
981
+ given(
982
+ 'a legacy sls.yaml whose accessByStage block lacks the anchored access: line (orphan-ref guard)',
983
+ () => {
984
+ // caller-without-callee guard: `withAccessByStage` runs before `withDeploymentBucketByStage`
985
+ // in the fold, so a consumer that already holds an `accessByStage:` map idempotent-skips that
986
+ // transform, and the canonical `access: ${self:custom.accessByStage...}` line the map-insert
987
+ // anchors on stays absent. the guard then soft-skips rather than rewrites the `deploymentBucket:`
988
+ // ref against an absent map — an orphan `${self:custom.deploymentBucketByStage...}` reference
989
+ // never lands (it would fail serverless variable resolution at deploy).
990
+ const example = `
991
+ service: svc-handedited-access
992
+
993
+ custom:
994
+ accessByStage:
995
+ dev: prep
996
+ prep: prep
997
+ prod: prod
998
+ access: prep # hand-edited to a literal, not the \${self:custom.accessByStage...} form the anchor reads
999
+
1000
+ provider:
1001
+ name: aws
1002
+ stage: \${opt:stage}
1003
+ deploymentBucket: serverless-deployment-orders-\${self:provider.stage}
1004
+ `.trim();
1005
+ then('it soft-skips: no orphan deploymentBucketByStage ref when the map insert missed', async () => {
1006
+ const fixed = (await fix(example, {} as any)).contents ?? '';
1007
+ // teeth: drop the `!withMap.includes('deploymentBucketByStage:')` guard -> the ref rewrite
1008
+ // fires against an absent map and this reddens (an orphan self-ref lands)
1009
+ expect(fixed).not.toContain('deploymentBucketByStage:');
1010
+ expect(fixed).not.toContain(
1011
+ 'deploymentBucket: ${self:custom.deploymentBucketByStage',
1012
+ );
1013
+ expect(fixed).toContain(
1014
+ 'deploymentBucket: serverless-deployment-orders-${self:provider.stage}',
1015
+ );
1016
+ });
1017
+ then('a second apply is a no-op (fix(fix(x)) === fix(x))', async () => {
1018
+ const once = await fix(example, {} as any);
1019
+ const twice = await fix(once.contents!, {} as any);
1020
+ expect(twice.contents).toEqual(once.contents);
1021
+ });
1022
+ },
1023
+ );
1024
+
1025
+ given(
1026
+ 'a sls.yaml checked out with crlf line endings (r10/r11 crlf non-convergence)',
1027
+ () => {
1028
+ // r10/r11 hazard, flagged since i001 and deferred every round: every transform anchors on a
1029
+ // literal `\n` (`environment:\n NODE_ENV:`, the insert regexes, …), so a consumer checked
1030
+ // out with crlf holds `\r\n` and every anchor misses — each transform soft-skips and
1031
+ // `declapract plan` stays RED forever with no diagnostic. withUnixNewlines runs first in the
1032
+ // fold and converts crlf -> lf, so every anchor matches and the file converges to the
1033
+ // lf-canonical template in one fix.
1034
+ const crlf = [
1035
+ 'service: svc-crlf',
1036
+ '',
1037
+ 'provider:',
1038
+ ' name: aws',
1039
+ ' stage: ${opt:stage}',
1040
+ ' environment:',
1041
+ ' NODE_ENV: production',
1042
+ ' STAGE: ${self:provider.stage} # the deploy stage',
1043
+ ' AWS_NODEJS_CONNECTION_REUSE_ENABLED: true',
1044
+ ].join('\r\n');
1045
+
1046
+ then('the declared blocks land despite crlf input (anchors converge on lf)', async () => {
1047
+ // teeth: drop withUnixNewlines from the fold -> every one of these reddens, because the
1048
+ // crlf `\r\n` bytes make every `\n`-anchored transform soft-skip.
1049
+ const fixed = (await fix(crlf, {} as any)).contents ?? '';
1050
+ expect(fixed).toContain('accessByStage:');
1051
+ expect(fixed).toContain('variablesResolutionMode: 20210326');
1052
+ expect(fixed).toContain('ACCESS:');
1053
+ expect(fixed).not.toContain('STAGE: ${self:provider.stage}');
1054
+ });
1055
+
1056
+ then('the output holds no crlf bytes (converged to lf-canonical)', async () => {
1057
+ const fixed = (await fix(crlf, {} as any)).contents ?? '';
1058
+ expect(fixed).not.toContain('\r\n');
1059
+ });
1060
+
1061
+ then('a second apply is a no-op (fix(fix(x)) === fix(x))', async () => {
1062
+ const once = await fix(crlf, {} as any);
1063
+ const twice = await fix(once.contents!, {} as any);
1064
+ expect(twice.contents).toEqual(once.contents);
1065
+ });
1066
+ },
1067
+ );
1068
+
1069
+ given(
1070
+ 'a legacy serverless.yml — the full composed fix (snapshot + idempotency)',
1071
+ () => {
1072
+ // a pristine "old" serverless.yml that trips many of the 15 chained transformers at once: old
1073
+ // runtime, deprecated plugins, #{AWS::*} pseudo-vars, ## comment headers, absent TZ +
1074
+ // connection-reuse, a stageToNodeEnvMapping NODE_ENV, timeout: 10, absent
1075
+ // variablesResolutionMode + accessByStage, ssm:GetParameters-only, and the obsolete
1076
+ // iam:ListAccountAliases access-inference grant.
1077
+ // .why = the decomposition into 15 with* functions has a real composed output; a full-output
1078
+ // snapshot + a fix(fix(x))===fix(x) case is the regression net that catches byte-level
1079
+ // drift across the whole chain (the pattern used 4x elsewhere this round), which
1080
+ // targeted .toContain assertions alone cannot.
1081
+ const legacy = `
1082
+ service: svc-orders # orders domain service
1083
+
1084
+ plugins:
1085
+ - serverless-offline # local invoke for dev
1086
+ - serverless-pseudo-parameters # obsolete once native vars land
1087
+ - serverless-prune-plugin
1088
+
1089
+ provider:
1090
+ name: aws
1091
+ runtime: nodejs18.x
1092
+ memorySize: 1024
1093
+ timeout: 10
1094
+ stage: \${opt:stage}
1095
+ environment:
1096
+ NODE_ENV: \${self:custom.stageToNodeEnvMapping.\${self:provider.stage}}
1097
+ deploymentBucket: serverless-deployment-\${self:provider.stage}
1098
+ iamRoleStatements:
1099
+ ## paramstore access
1100
+ - Effect: Allow
1101
+ Action: 'ssm:GetParameters'
1102
+ Resource: arn:aws:ssm:#{AWS::Region}:#{AWS::AccountId}:parameter/*
1103
+ # allow inferring access from account alias
1104
+ - Effect: Allow
1105
+ Action:
1106
+ - iam:ListAccountAliases
1107
+ Resource: '*'
1108
+ ## allow invocation of other lambdas
1109
+ - Effect: Allow
1110
+ Action:
1111
+ - lambda:InvokeFunction
1112
+ Resource: '*'
1113
+ `.trim();
1114
+
1115
+ then('the legacy input matches snapshot (before)', () => {
1116
+ expect(legacy).toMatchSnapshot('legacy serverless.yml — before');
1117
+ });
1118
+
1119
+ then('the full composed fix matches snapshot (after)', async () => {
1120
+ const fixed = await fix(legacy, {} as any);
1121
+ expect(fixed.contents).toMatchSnapshot('legacy serverless.yml — after');
1122
+ });
1123
+
1124
+ then('a second apply is a no-op (fix(fix(x)) === fix(x))', async () => {
1125
+ const once = await fix(legacy, {} as any);
1126
+ const twice = await fix(once.contents!, {} as any);
1127
+ expect(twice.contents).toEqual(once.contents);
1128
+ });
1129
+
1130
+ then('the composed fix trips the expected transformers', async () => {
1131
+ const fixed = (await fix(legacy, {} as any)).contents ?? '';
1132
+ // a spot-check across the chain, so a broken step reddens a named assertion,
1133
+ // not only the opaque snapshot diff
1134
+ expect(fixed).toContain('runtime: nodejs22.x');
1135
+ expect(fixed).not.toContain('serverless-offline');
1136
+ expect(fixed).not.toContain('serverless-pseudo-parameters ');
1137
+ expect(fixed).toContain('${aws:region}');
1138
+ expect(fixed).toContain('${aws:accountId}');
1139
+ expect(fixed).toContain('# parameter store access');
1140
+ expect(fixed).toContain('TZ: UTC');
1141
+ expect(fixed).toContain('AWS_NODEJS_CONNECTION_REUSE_ENABLED: true');
1142
+ // r7.b1 teeth: the legacy stageToNodeEnvMapping NODE_ENV is rewritten to the go-forward
1143
+ // literal, so the fix output never references a key its inserted custom: block lacks.
1144
+ expect(fixed).toContain('NODE_ENV: production');
1145
+ expect(fixed).not.toContain('stageToNodeEnvMapping');
1146
+ expect(fixed).toContain('timeout: 60');
1147
+ expect(fixed).toContain('variablesResolutionMode: 20210326');
1148
+ expect(fixed).toContain('accessByStage:');
1149
+ // the withPackageArtifact/withPrunePlugin anchor: a plugins block sits between service:
1150
+ // and provider: in this fixture, which the old service-anchored regex could not see — it
1151
+ // silently no-opped and the snapshot recorded the gap. the provider:-anchored insert now
1152
+ // fires no matter what precedes it. teeth: revert the anchor -> these redden.
1153
+ expect(fixed).toContain('package:\n artifact: .artifact/contents.zip');
1154
+ // the prune plugin already in the file survives and is NOT duplicated (presence guard),
1155
+ // and the one plugins block is not split into two
1156
+ expect((fixed.match(/serverless-prune-plugin/g) || []).length).toBe(1);
1157
+ expect((fixed.match(/\nplugins:/g) || []).length).toBe(1);
1158
+ expect(fixed).toContain('account:GetAccountInformation');
1159
+ expect(fixed).not.toContain('iam:ListAccountAliases');
1160
+ expect(fixed).toContain('- ssm:GetParameter\n');
1161
+ });
1162
+ },
1163
+ );
1164
+
1165
+ given('a legacy serverless.yml whose provider timeout is a non-default value', () => {
1166
+ // the default-timeout transform bumps a provider `timeout: 10` to `timeout: 60`. a consumer whose
1167
+ // provider timeout is some OTHER value (e.g. 30) is a deliberate operational choice — an auto-bump
1168
+ // to 60 would override it (the "a practice that emits a value" hazard). so on this shape the
1169
+ // transform emits an actionable `@declapract:review` marker instead of a silent no-op, the same
1170
+ // visibility terminus as withUtcTimezone. whether to FORCE 60 or RELAX the clamp is the
1171
+ // wisher-reserved fork (F-serverless-soft-skip-convergence).
1172
+ const example = `
1173
+ service: svc-slow-fn
1174
+
1175
+ provider:
1176
+ name: aws
1177
+ runtime: nodejs22.x
1178
+ timeout: 30
1179
+ stage: \${opt:stage}
1180
+ environment:
1181
+ NODE_ENV: production
1182
+ `.trim();
1183
+
1184
+ then('a non-default provider timeout emits a review marker, not a silent no-op', async () => {
1185
+ const fixed = (await fix(example, {} as any)).contents ?? '';
1186
+ // teeth: drop the non-default marker branch -> this reddens (a `timeout: 30` would then
1187
+ // soft-skip silently and CONTAINS(`timeout: 60`) stays red with NO diagnostic — the row-1
1188
+ // non-convergent-silent class the wish forbids)
1189
+ expect(fixed).toContain('@declapract:review');
1190
+ expect(fixed).toContain('provider `timeout:` is not the 60s default');
1191
+ // it does NOT override the consumer's deliberate value (the wisher-reserved fork)
1192
+ expect(fixed).toContain('timeout: 30');
1193
+ expect(fixed).not.toContain('timeout: 60\n');
1194
+ });
1195
+
1196
+ then('a second apply is a no-op (the marker is idempotent)', async () => {
1197
+ const once = await fix(example, {} as any);
1198
+ const twice = await fix(once.contents!, {} as any);
1199
+ expect(twice.contents).toEqual(once.contents);
1200
+ });
1201
+
1202
+ then('a four-space function-level timeout: 100 is NOT clobbered by the two-space anchor', async () => {
1203
+ const withFnTimeout = `
1204
+ service: svc-fn-timeout
1205
+
1206
+ provider:
1207
+ name: aws
1208
+ runtime: nodejs22.x
1209
+ timeout: 60
1210
+ stage: \${opt:stage}
1211
+
1212
+ functions:
1213
+ slowOne:
1214
+ handler: src/handler.slowOne
1215
+ timeout: 100
1216
+ `.trim();
1217
+ const fixed = (await fix(withFnTimeout, {} as any)).contents ?? '';
1218
+ // the provider default (60) idempotent-skips; the function-level 100 (four-space) is untouched
1219
+ expect(fixed).toContain(' timeout: 100');
1220
+ expect(fixed).not.toContain('@declapract:review');
1221
+ });
1222
+ });
1223
+
1224
+ given(
1225
+ 'the fix output converges with the real template under CONTAINS (r11 i067 b1)',
1226
+ () => {
1227
+ // r11 i067 blocker (arch-defects): declapract governs this file with CONTAINS, which runs
1228
+ // `expect(foundContents).toContain(declaredFileContents)` — the WHOLE hydrated template as one
1229
+ // contiguous span (the check-contains source + containsCheck, verified in node_modules/declapract).
1230
+ // so a migrated consumer's fix output must reproduce the template's accessByStage +
1231
+ // deploymentBucketByStage prose VERBATIM, or the toContain match fails and `declapract plan`
1232
+ // stays red forever — a non-convergent fix, the row-1 class the wish forbids. no prior test
1233
+ // round-trips fix() output against the real template; this clamp does, with no third copy of the
1234
+ // prose: it lifts the template's own `custom:` region + deploymentBucket ref and asserts the fix
1235
+ // reproduces each byte-for-byte. a reword of EITHER the template or the fix reddens CI here,
1236
+ // rather than a migrated consumer's plan.
1237
+ const template = readFileSync(
1238
+ join(__dirname, 'best-practice', 'serverless.yml'),
1239
+ 'utf-8',
1240
+ );
1241
+ // hydrate the one placeholder the two blocks carry to a known namespace, so the bucket base the
1242
+ // fix derives from the consumer line (`serverless-deployment-orders`) equals the template base.
1243
+ const hydrated = template.replace(
1244
+ /@declapract\{variable\.infrastructureNamespaceId\}/g,
1245
+ 'orders',
1246
+ );
1247
+ const example = `
1248
+ service: svc-orders
1249
+
1250
+ provider:
1251
+ name: aws
1252
+ stage: \${opt:stage}
1253
+ environment:
1254
+ NODE_ENV: production
1255
+ deploymentBucket: serverless-deployment-orders-\${self:provider.stage}
1256
+ `.trim();
1257
+
1258
+ then(
1259
+ 'the fix reproduces the template custom: region (accessByStage + deploymentBucketByStage) as a contiguous span',
1260
+ async () => {
1261
+ const fixed = (await fix(example, {} as any)).contents ?? '';
1262
+ const customRegion = hydrated.slice(
1263
+ hydrated.indexOf('custom:'),
1264
+ hydrated.indexOf('\nprovider:'),
1265
+ );
1266
+ // teeth: reword any comment in the template accessByStage/deploymentBucketByStage block, or
1267
+ // in the fix's accessByStageCustom / withDeploymentBucketByStage emit, and this reddens.
1268
+ expect(fixed).toContain(customRegion);
1269
+ },
1270
+ );
1271
+
1272
+ then(
1273
+ 'the fix reproduces the template deploymentBucket reference line byte-for-byte',
1274
+ async () => {
1275
+ const fixed = (await fix(example, {} as any)).contents ?? '';
1276
+ const bucketRef = hydrated
1277
+ .split('\n')
1278
+ .find((line) => line.trimStart().startsWith('deploymentBucket:'));
1279
+ expect(bucketRef).toBeDefined();
1280
+ expect(fixed).toContain(bucketRef!);
1281
+ },
1282
+ );
1283
+ },
1284
+ );
1285
+ });