plugin-git-manager 1.0.3 → 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +108 -0
- package/dist/client/228.7588a0707cb3694a.js +10 -0
- package/dist/client/498.dd1184272d8038d4.js +10 -0
- package/dist/client/ai-context.d.ts +8 -0
- package/dist/client/components/AIEmployeeSelect.d.ts +13 -0
- package/dist/client/components/MarkdownView.d.ts +10 -0
- package/dist/client/components/MergeRequests.d.ts +2 -0
- package/dist/client/components/PollingStatus.d.ts +2 -0
- package/dist/client/components/ReviewFlows.d.ts +2 -0
- package/dist/client/components/ReviewHistory.d.ts +4 -0
- package/dist/client/components/RunReviewButton.d.ts +31 -0
- package/dist/client/index.js +1 -1
- package/dist/externalVersion.js +4 -4
- package/dist/locale/en-US.json +137 -1
- package/dist/locale/vi-VN.json +137 -1
- package/dist/node_modules/zod/LICENSE +21 -0
- package/dist/node_modules/zod/index.cjs +1 -0
- package/dist/node_modules/zod/index.d.cts +4 -0
- package/dist/node_modules/zod/index.d.ts +4 -0
- package/dist/node_modules/zod/index.js +4 -0
- package/dist/node_modules/zod/locales/index.cjs +17 -0
- package/dist/node_modules/zod/locales/index.d.cts +1 -0
- package/dist/node_modules/zod/locales/index.d.ts +1 -0
- package/dist/node_modules/zod/locales/index.js +1 -0
- package/dist/node_modules/zod/locales/package.json +6 -0
- package/dist/node_modules/zod/mini/index.cjs +17 -0
- package/dist/node_modules/zod/mini/index.d.cts +1 -0
- package/dist/node_modules/zod/mini/index.d.ts +1 -0
- package/dist/node_modules/zod/mini/index.js +1 -0
- package/dist/node_modules/zod/mini/package.json +6 -0
- package/dist/node_modules/zod/package.json +1 -0
- package/dist/node_modules/zod/src/index.ts +4 -0
- package/dist/node_modules/zod/src/locales/index.ts +1 -0
- package/dist/node_modules/zod/src/mini/index.ts +1 -0
- package/dist/node_modules/zod/src/v3/ZodError.ts +330 -0
- package/dist/node_modules/zod/src/v3/benchmarks/datetime.ts +58 -0
- package/dist/node_modules/zod/src/v3/benchmarks/discriminatedUnion.ts +80 -0
- package/dist/node_modules/zod/src/v3/benchmarks/index.ts +59 -0
- package/dist/node_modules/zod/src/v3/benchmarks/ipv4.ts +57 -0
- package/dist/node_modules/zod/src/v3/benchmarks/object.ts +69 -0
- package/dist/node_modules/zod/src/v3/benchmarks/primitives.ts +162 -0
- package/dist/node_modules/zod/src/v3/benchmarks/realworld.ts +63 -0
- package/dist/node_modules/zod/src/v3/benchmarks/string.ts +55 -0
- package/dist/node_modules/zod/src/v3/benchmarks/union.ts +80 -0
- package/dist/node_modules/zod/src/v3/errors.ts +13 -0
- package/dist/node_modules/zod/src/v3/external.ts +6 -0
- package/dist/node_modules/zod/src/v3/helpers/enumUtil.ts +17 -0
- package/dist/node_modules/zod/src/v3/helpers/errorUtil.ts +8 -0
- package/dist/node_modules/zod/src/v3/helpers/parseUtil.ts +176 -0
- package/dist/node_modules/zod/src/v3/helpers/partialUtil.ts +34 -0
- package/dist/node_modules/zod/src/v3/helpers/typeAliases.ts +2 -0
- package/dist/node_modules/zod/src/v3/helpers/util.ts +224 -0
- package/dist/node_modules/zod/src/v3/index.ts +4 -0
- package/dist/node_modules/zod/src/v3/locales/en.ts +124 -0
- package/dist/node_modules/zod/src/v3/standard-schema.ts +113 -0
- package/dist/node_modules/zod/src/v3/tests/Mocker.ts +54 -0
- package/dist/node_modules/zod/src/v3/tests/all-errors.test.ts +157 -0
- package/dist/node_modules/zod/src/v3/tests/anyunknown.test.ts +28 -0
- package/dist/node_modules/zod/src/v3/tests/array.test.ts +71 -0
- package/dist/node_modules/zod/src/v3/tests/async-parsing.test.ts +388 -0
- package/dist/node_modules/zod/src/v3/tests/async-refinements.test.ts +46 -0
- package/dist/node_modules/zod/src/v3/tests/base.test.ts +29 -0
- package/dist/node_modules/zod/src/v3/tests/bigint.test.ts +55 -0
- package/dist/node_modules/zod/src/v3/tests/branded.test.ts +53 -0
- package/dist/node_modules/zod/src/v3/tests/catch.test.ts +220 -0
- package/dist/node_modules/zod/src/v3/tests/coerce.test.ts +133 -0
- package/dist/node_modules/zod/src/v3/tests/complex.test.ts +70 -0
- package/dist/node_modules/zod/src/v3/tests/custom.test.ts +31 -0
- package/dist/node_modules/zod/src/v3/tests/date.test.ts +32 -0
- package/dist/node_modules/zod/src/v3/tests/deepmasking.test.ts +186 -0
- package/dist/node_modules/zod/src/v3/tests/default.test.ts +112 -0
- package/dist/node_modules/zod/src/v3/tests/description.test.ts +33 -0
- package/dist/node_modules/zod/src/v3/tests/discriminated-unions.test.ts +315 -0
- package/dist/node_modules/zod/src/v3/tests/enum.test.ts +80 -0
- package/dist/node_modules/zod/src/v3/tests/error.test.ts +551 -0
- package/dist/node_modules/zod/src/v3/tests/firstparty.test.ts +87 -0
- package/dist/node_modules/zod/src/v3/tests/firstpartyschematypes.test.ts +21 -0
- package/dist/node_modules/zod/src/v3/tests/function.test.ts +261 -0
- package/dist/node_modules/zod/src/v3/tests/generics.test.ts +48 -0
- package/dist/node_modules/zod/src/v3/tests/instanceof.test.ts +37 -0
- package/dist/node_modules/zod/src/v3/tests/intersection.test.ts +110 -0
- package/dist/node_modules/zod/src/v3/tests/language-server.source.ts +76 -0
- package/dist/node_modules/zod/src/v3/tests/language-server.test.ts +207 -0
- package/dist/node_modules/zod/src/v3/tests/literal.test.ts +36 -0
- package/dist/node_modules/zod/src/v3/tests/map.test.ts +110 -0
- package/dist/node_modules/zod/src/v3/tests/masking.test.ts +4 -0
- package/dist/node_modules/zod/src/v3/tests/mocker.test.ts +19 -0
- package/dist/node_modules/zod/src/v3/tests/nan.test.ts +24 -0
- package/dist/node_modules/zod/src/v3/tests/nativeEnum.test.ts +87 -0
- package/dist/node_modules/zod/src/v3/tests/nullable.test.ts +42 -0
- package/dist/node_modules/zod/src/v3/tests/number.test.ts +176 -0
- package/dist/node_modules/zod/src/v3/tests/object-augmentation.test.ts +29 -0
- package/dist/node_modules/zod/src/v3/tests/object-in-es5-env.test.ts +29 -0
- package/dist/node_modules/zod/src/v3/tests/object.test.ts +434 -0
- package/dist/node_modules/zod/src/v3/tests/optional.test.ts +42 -0
- package/dist/node_modules/zod/src/v3/tests/parseUtil.test.ts +23 -0
- package/dist/node_modules/zod/src/v3/tests/parser.test.ts +41 -0
- package/dist/node_modules/zod/src/v3/tests/partials.test.ts +243 -0
- package/dist/node_modules/zod/src/v3/tests/pickomit.test.ts +111 -0
- package/dist/node_modules/zod/src/v3/tests/pipeline.test.ts +29 -0
- package/dist/node_modules/zod/src/v3/tests/preprocess.test.ts +186 -0
- package/dist/node_modules/zod/src/v3/tests/primitive.test.ts +440 -0
- package/dist/node_modules/zod/src/v3/tests/promise.test.ts +90 -0
- package/dist/node_modules/zod/src/v3/tests/readonly.test.ts +194 -0
- package/dist/node_modules/zod/src/v3/tests/record.test.ts +171 -0
- package/dist/node_modules/zod/src/v3/tests/recursive.test.ts +197 -0
- package/dist/node_modules/zod/src/v3/tests/refine.test.ts +313 -0
- package/dist/node_modules/zod/src/v3/tests/safeparse.test.ts +27 -0
- package/dist/node_modules/zod/src/v3/tests/set.test.ts +142 -0
- package/dist/node_modules/zod/src/v3/tests/standard-schema.test.ts +83 -0
- package/dist/node_modules/zod/src/v3/tests/string.test.ts +916 -0
- package/dist/node_modules/zod/src/v3/tests/transformer.test.ts +233 -0
- package/dist/node_modules/zod/src/v3/tests/tuple.test.ts +90 -0
- package/dist/node_modules/zod/src/v3/tests/unions.test.ts +57 -0
- package/dist/node_modules/zod/src/v3/tests/validations.test.ts +133 -0
- package/dist/node_modules/zod/src/v3/tests/void.test.ts +15 -0
- package/dist/node_modules/zod/src/v3/types.ts +5138 -0
- package/dist/node_modules/zod/src/v4/classic/checks.ts +32 -0
- package/dist/node_modules/zod/src/v4/classic/coerce.ts +27 -0
- package/dist/node_modules/zod/src/v4/classic/compat.ts +70 -0
- package/dist/node_modules/zod/src/v4/classic/errors.ts +82 -0
- package/dist/node_modules/zod/src/v4/classic/external.ts +51 -0
- package/dist/node_modules/zod/src/v4/classic/from-json-schema.ts +643 -0
- package/dist/node_modules/zod/src/v4/classic/index.ts +5 -0
- package/dist/node_modules/zod/src/v4/classic/iso.ts +90 -0
- package/dist/node_modules/zod/src/v4/classic/parse.ts +82 -0
- package/dist/node_modules/zod/src/v4/classic/schemas.ts +2409 -0
- package/dist/node_modules/zod/src/v4/classic/tests/anyunknown.test.ts +26 -0
- package/dist/node_modules/zod/src/v4/classic/tests/apply.test.ts +59 -0
- package/dist/node_modules/zod/src/v4/classic/tests/array.test.ts +264 -0
- package/dist/node_modules/zod/src/v4/classic/tests/assignability.test.ts +210 -0
- package/dist/node_modules/zod/src/v4/classic/tests/async-parsing.test.ts +381 -0
- package/dist/node_modules/zod/src/v4/classic/tests/async-refinements.test.ts +68 -0
- package/dist/node_modules/zod/src/v4/classic/tests/base.test.ts +7 -0
- package/dist/node_modules/zod/src/v4/classic/tests/bigint.test.ts +54 -0
- package/dist/node_modules/zod/src/v4/classic/tests/brand.test.ts +106 -0
- package/dist/node_modules/zod/src/v4/classic/tests/catch.test.ts +276 -0
- package/dist/node_modules/zod/src/v4/classic/tests/coalesce.test.ts +20 -0
- package/dist/node_modules/zod/src/v4/classic/tests/codec-examples.test.ts +573 -0
- package/dist/node_modules/zod/src/v4/classic/tests/codec.test.ts +562 -0
- package/dist/node_modules/zod/src/v4/classic/tests/coerce.test.ts +160 -0
- package/dist/node_modules/zod/src/v4/classic/tests/continuability.test.ts +374 -0
- package/dist/node_modules/zod/src/v4/classic/tests/custom.test.ts +40 -0
- package/dist/node_modules/zod/src/v4/classic/tests/date.test.ts +62 -0
- package/dist/node_modules/zod/src/v4/classic/tests/datetime.test.ts +302 -0
- package/dist/node_modules/zod/src/v4/classic/tests/default.test.ts +365 -0
- package/dist/node_modules/zod/src/v4/classic/tests/describe-meta-checks.test.ts +27 -0
- package/dist/node_modules/zod/src/v4/classic/tests/description.test.ts +32 -0
- package/dist/node_modules/zod/src/v4/classic/tests/discriminated-unions.test.ts +661 -0
- package/dist/node_modules/zod/src/v4/classic/tests/enum.test.ts +285 -0
- package/dist/node_modules/zod/src/v4/classic/tests/error-utils.test.ts +595 -0
- package/dist/node_modules/zod/src/v4/classic/tests/error.test.ts +711 -0
- package/dist/node_modules/zod/src/v4/classic/tests/file.test.ts +96 -0
- package/dist/node_modules/zod/src/v4/classic/tests/firstparty.test.ts +179 -0
- package/dist/node_modules/zod/src/v4/classic/tests/fix-json-issue.test.ts +26 -0
- package/dist/node_modules/zod/src/v4/classic/tests/from-json-schema.test.ts +734 -0
- package/dist/node_modules/zod/src/v4/classic/tests/function.test.ts +360 -0
- package/dist/node_modules/zod/src/v4/classic/tests/generics.test.ts +72 -0
- package/dist/node_modules/zod/src/v4/classic/tests/hash.test.ts +68 -0
- package/dist/node_modules/zod/src/v4/classic/tests/index.test.ts +939 -0
- package/dist/node_modules/zod/src/v4/classic/tests/instanceof.test.ts +60 -0
- package/dist/node_modules/zod/src/v4/classic/tests/intersection.test.ts +198 -0
- package/dist/node_modules/zod/src/v4/classic/tests/json.test.ts +109 -0
- package/dist/node_modules/zod/src/v4/classic/tests/lazy.test.ts +227 -0
- package/dist/node_modules/zod/src/v4/classic/tests/literal.test.ts +117 -0
- package/dist/node_modules/zod/src/v4/classic/tests/map.test.ts +330 -0
- package/dist/node_modules/zod/src/v4/classic/tests/nan.test.ts +21 -0
- package/dist/node_modules/zod/src/v4/classic/tests/nested-refine.test.ts +168 -0
- package/dist/node_modules/zod/src/v4/classic/tests/nonoptional.test.ts +101 -0
- package/dist/node_modules/zod/src/v4/classic/tests/nullable.test.ts +22 -0
- package/dist/node_modules/zod/src/v4/classic/tests/number.test.ts +270 -0
- package/dist/node_modules/zod/src/v4/classic/tests/object.test.ts +640 -0
- package/dist/node_modules/zod/src/v4/classic/tests/optional.test.ts +223 -0
- package/dist/node_modules/zod/src/v4/classic/tests/partial.test.ts +427 -0
- package/dist/node_modules/zod/src/v4/classic/tests/pickomit.test.ts +211 -0
- package/dist/node_modules/zod/src/v4/classic/tests/pipe.test.ts +101 -0
- package/dist/node_modules/zod/src/v4/classic/tests/prefault.test.ts +74 -0
- package/dist/node_modules/zod/src/v4/classic/tests/preprocess.test.ts +282 -0
- package/dist/node_modules/zod/src/v4/classic/tests/primitive.test.ts +175 -0
- package/dist/node_modules/zod/src/v4/classic/tests/promise.test.ts +81 -0
- package/dist/node_modules/zod/src/v4/classic/tests/prototypes.test.ts +23 -0
- package/dist/node_modules/zod/src/v4/classic/tests/readonly.test.ts +252 -0
- package/dist/node_modules/zod/src/v4/classic/tests/record.test.ts +600 -0
- package/dist/node_modules/zod/src/v4/classic/tests/recursive-types.test.ts +582 -0
- package/dist/node_modules/zod/src/v4/classic/tests/refine.test.ts +570 -0
- package/dist/node_modules/zod/src/v4/classic/tests/registries.test.ts +243 -0
- package/dist/node_modules/zod/src/v4/classic/tests/set.test.ts +181 -0
- package/dist/node_modules/zod/src/v4/classic/tests/standard-schema.test.ts +134 -0
- package/dist/node_modules/zod/src/v4/classic/tests/string-formats.test.ts +125 -0
- package/dist/node_modules/zod/src/v4/classic/tests/string.test.ts +1175 -0
- package/dist/node_modules/zod/src/v4/classic/tests/stringbool.test.ts +106 -0
- package/dist/node_modules/zod/src/v4/classic/tests/template-literal.test.ts +771 -0
- package/dist/node_modules/zod/src/v4/classic/tests/to-json-schema-methods.test.ts +438 -0
- package/dist/node_modules/zod/src/v4/classic/tests/to-json-schema.test.ts +2975 -0
- package/dist/node_modules/zod/src/v4/classic/tests/transform.test.ts +361 -0
- package/dist/node_modules/zod/src/v4/classic/tests/tuple.test.ts +183 -0
- package/dist/node_modules/zod/src/v4/classic/tests/union.test.ts +219 -0
- package/dist/node_modules/zod/src/v4/classic/tests/url.test.ts +13 -0
- package/dist/node_modules/zod/src/v4/classic/tests/validations.test.ts +283 -0
- package/dist/node_modules/zod/src/v4/classic/tests/void.test.ts +12 -0
- package/dist/node_modules/zod/src/v4/core/api.ts +1798 -0
- package/dist/node_modules/zod/src/v4/core/checks.ts +1293 -0
- package/dist/node_modules/zod/src/v4/core/config.ts +15 -0
- package/dist/node_modules/zod/src/v4/core/core.ts +138 -0
- package/dist/node_modules/zod/src/v4/core/doc.ts +44 -0
- package/dist/node_modules/zod/src/v4/core/errors.ts +448 -0
- package/dist/node_modules/zod/src/v4/core/index.ts +16 -0
- package/dist/node_modules/zod/src/v4/core/json-schema-generator.ts +126 -0
- package/dist/node_modules/zod/src/v4/core/json-schema-processors.ts +667 -0
- package/dist/node_modules/zod/src/v4/core/json-schema.ts +147 -0
- package/dist/node_modules/zod/src/v4/core/parse.ts +195 -0
- package/dist/node_modules/zod/src/v4/core/regexes.ts +183 -0
- package/dist/node_modules/zod/src/v4/core/registries.ts +105 -0
- package/dist/node_modules/zod/src/v4/core/schemas.ts +4543 -0
- package/dist/node_modules/zod/src/v4/core/standard-schema.ts +159 -0
- package/dist/node_modules/zod/src/v4/core/tests/extend.test.ts +59 -0
- package/dist/node_modules/zod/src/v4/core/tests/index.test.ts +46 -0
- package/dist/node_modules/zod/src/v4/core/tests/locales/be.test.ts +124 -0
- package/dist/node_modules/zod/src/v4/core/tests/locales/en.test.ts +22 -0
- package/dist/node_modules/zod/src/v4/core/tests/locales/es.test.ts +181 -0
- package/dist/node_modules/zod/src/v4/core/tests/locales/he.test.ts +379 -0
- package/dist/node_modules/zod/src/v4/core/tests/locales/nl.test.ts +46 -0
- package/dist/node_modules/zod/src/v4/core/tests/locales/ru.test.ts +128 -0
- package/dist/node_modules/zod/src/v4/core/tests/locales/tr.test.ts +69 -0
- package/dist/node_modules/zod/src/v4/core/tests/locales/uz.test.ts +83 -0
- package/dist/node_modules/zod/src/v4/core/tests/record-constructor.test.ts +67 -0
- package/dist/node_modules/zod/src/v4/core/tests/recursive-tuples.test.ts +45 -0
- package/dist/node_modules/zod/src/v4/core/to-json-schema.ts +613 -0
- package/dist/node_modules/zod/src/v4/core/util.ts +966 -0
- package/dist/node_modules/zod/src/v4/core/versions.ts +5 -0
- package/dist/node_modules/zod/src/v4/core/zsf.ts +323 -0
- package/dist/node_modules/zod/src/v4/index.ts +4 -0
- package/dist/node_modules/zod/src/v4/locales/ar.ts +115 -0
- package/dist/node_modules/zod/src/v4/locales/az.ts +111 -0
- package/dist/node_modules/zod/src/v4/locales/be.ts +176 -0
- package/dist/node_modules/zod/src/v4/locales/bg.ts +128 -0
- package/dist/node_modules/zod/src/v4/locales/ca.ts +116 -0
- package/dist/node_modules/zod/src/v4/locales/cs.ts +118 -0
- package/dist/node_modules/zod/src/v4/locales/da.ts +123 -0
- package/dist/node_modules/zod/src/v4/locales/de.ts +116 -0
- package/dist/node_modules/zod/src/v4/locales/en.ts +119 -0
- package/dist/node_modules/zod/src/v4/locales/eo.ts +118 -0
- package/dist/node_modules/zod/src/v4/locales/es.ts +141 -0
- package/dist/node_modules/zod/src/v4/locales/fa.ts +126 -0
- package/dist/node_modules/zod/src/v4/locales/fi.ts +121 -0
- package/dist/node_modules/zod/src/v4/locales/fr-CA.ts +116 -0
- package/dist/node_modules/zod/src/v4/locales/fr.ts +116 -0
- package/dist/node_modules/zod/src/v4/locales/he.ts +246 -0
- package/dist/node_modules/zod/src/v4/locales/hu.ts +117 -0
- package/dist/node_modules/zod/src/v4/locales/hy.ts +164 -0
- package/dist/node_modules/zod/src/v4/locales/id.ts +115 -0
- package/dist/node_modules/zod/src/v4/locales/index.ts +49 -0
- package/dist/node_modules/zod/src/v4/locales/is.ts +119 -0
- package/dist/node_modules/zod/src/v4/locales/it.ts +116 -0
- package/dist/node_modules/zod/src/v4/locales/ja.ts +114 -0
- package/dist/node_modules/zod/src/v4/locales/ka.ts +123 -0
- package/dist/node_modules/zod/src/v4/locales/kh.ts +7 -0
- package/dist/node_modules/zod/src/v4/locales/km.ts +119 -0
- package/dist/node_modules/zod/src/v4/locales/ko.ts +121 -0
- package/dist/node_modules/zod/src/v4/locales/lt.ts +239 -0
- package/dist/node_modules/zod/src/v4/locales/mk.ts +118 -0
- package/dist/node_modules/zod/src/v4/locales/ms.ts +115 -0
- package/dist/node_modules/zod/src/v4/locales/nl.ts +121 -0
- package/dist/node_modules/zod/src/v4/locales/no.ts +116 -0
- package/dist/node_modules/zod/src/v4/locales/ota.ts +117 -0
- package/dist/node_modules/zod/src/v4/locales/pl.ts +118 -0
- package/dist/node_modules/zod/src/v4/locales/ps.ts +126 -0
- package/dist/node_modules/zod/src/v4/locales/pt.ts +116 -0
- package/dist/node_modules/zod/src/v4/locales/ru.ts +176 -0
- package/dist/node_modules/zod/src/v4/locales/sl.ts +118 -0
- package/dist/node_modules/zod/src/v4/locales/sv.ts +119 -0
- package/dist/node_modules/zod/src/v4/locales/ta.ts +118 -0
- package/dist/node_modules/zod/src/v4/locales/th.ts +119 -0
- package/dist/node_modules/zod/src/v4/locales/tr.ts +111 -0
- package/dist/node_modules/zod/src/v4/locales/ua.ts +7 -0
- package/dist/node_modules/zod/src/v4/locales/uk.ts +117 -0
- package/dist/node_modules/zod/src/v4/locales/ur.ts +119 -0
- package/dist/node_modules/zod/src/v4/locales/uz.ts +116 -0
- package/dist/node_modules/zod/src/v4/locales/vi.ts +117 -0
- package/dist/node_modules/zod/src/v4/locales/yo.ts +124 -0
- package/dist/node_modules/zod/src/v4/locales/zh-CN.ts +116 -0
- package/dist/node_modules/zod/src/v4/locales/zh-TW.ts +115 -0
- package/dist/node_modules/zod/src/v4/mini/checks.ts +32 -0
- package/dist/node_modules/zod/src/v4/mini/coerce.ts +27 -0
- package/dist/node_modules/zod/src/v4/mini/external.ts +40 -0
- package/dist/node_modules/zod/src/v4/mini/index.ts +3 -0
- package/dist/node_modules/zod/src/v4/mini/iso.ts +66 -0
- package/dist/node_modules/zod/src/v4/mini/parse.ts +14 -0
- package/dist/node_modules/zod/src/v4/mini/schemas.ts +1916 -0
- package/dist/node_modules/zod/src/v4/mini/tests/apply.test.ts +24 -0
- package/dist/node_modules/zod/src/v4/mini/tests/assignability.test.ts +129 -0
- package/dist/node_modules/zod/src/v4/mini/tests/brand.test.ts +94 -0
- package/dist/node_modules/zod/src/v4/mini/tests/checks.test.ts +144 -0
- package/dist/node_modules/zod/src/v4/mini/tests/codec.test.ts +529 -0
- package/dist/node_modules/zod/src/v4/mini/tests/computed.test.ts +36 -0
- package/dist/node_modules/zod/src/v4/mini/tests/error.test.ts +22 -0
- package/dist/node_modules/zod/src/v4/mini/tests/functions.test.ts +5 -0
- package/dist/node_modules/zod/src/v4/mini/tests/index.test.ts +963 -0
- package/dist/node_modules/zod/src/v4/mini/tests/number.test.ts +95 -0
- package/dist/node_modules/zod/src/v4/mini/tests/object.test.ts +227 -0
- package/dist/node_modules/zod/src/v4/mini/tests/prototypes.test.ts +43 -0
- package/dist/node_modules/zod/src/v4/mini/tests/recursive-types.test.ts +275 -0
- package/dist/node_modules/zod/src/v4/mini/tests/standard-schema.test.ts +50 -0
- package/dist/node_modules/zod/src/v4/mini/tests/string.test.ts +347 -0
- package/dist/node_modules/zod/src/v4-mini/index.ts +1 -0
- package/dist/node_modules/zod/v3/ZodError.cjs +138 -0
- package/dist/node_modules/zod/v3/ZodError.d.cts +164 -0
- package/dist/node_modules/zod/v3/ZodError.d.ts +164 -0
- package/dist/node_modules/zod/v3/ZodError.js +133 -0
- package/dist/node_modules/zod/v3/errors.cjs +17 -0
- package/dist/node_modules/zod/v3/errors.d.cts +5 -0
- package/dist/node_modules/zod/v3/errors.d.ts +5 -0
- package/dist/node_modules/zod/v3/errors.js +9 -0
- package/dist/node_modules/zod/v3/external.cjs +22 -0
- package/dist/node_modules/zod/v3/external.d.cts +6 -0
- package/dist/node_modules/zod/v3/external.d.ts +6 -0
- package/dist/node_modules/zod/v3/external.js +6 -0
- package/dist/node_modules/zod/v3/helpers/enumUtil.cjs +2 -0
- package/dist/node_modules/zod/v3/helpers/enumUtil.d.cts +8 -0
- package/dist/node_modules/zod/v3/helpers/enumUtil.d.ts +8 -0
- package/dist/node_modules/zod/v3/helpers/enumUtil.js +1 -0
- package/dist/node_modules/zod/v3/helpers/errorUtil.cjs +9 -0
- package/dist/node_modules/zod/v3/helpers/errorUtil.d.cts +9 -0
- package/dist/node_modules/zod/v3/helpers/errorUtil.d.ts +9 -0
- package/dist/node_modules/zod/v3/helpers/errorUtil.js +6 -0
- package/dist/node_modules/zod/v3/helpers/parseUtil.cjs +124 -0
- package/dist/node_modules/zod/v3/helpers/parseUtil.d.cts +78 -0
- package/dist/node_modules/zod/v3/helpers/parseUtil.d.ts +78 -0
- package/dist/node_modules/zod/v3/helpers/parseUtil.js +109 -0
- package/dist/node_modules/zod/v3/helpers/partialUtil.cjs +2 -0
- package/dist/node_modules/zod/v3/helpers/partialUtil.d.cts +8 -0
- package/dist/node_modules/zod/v3/helpers/partialUtil.d.ts +8 -0
- package/dist/node_modules/zod/v3/helpers/partialUtil.js +1 -0
- package/dist/node_modules/zod/v3/helpers/typeAliases.cjs +2 -0
- package/dist/node_modules/zod/v3/helpers/typeAliases.d.cts +2 -0
- package/dist/node_modules/zod/v3/helpers/typeAliases.d.ts +2 -0
- package/dist/node_modules/zod/v3/helpers/typeAliases.js +1 -0
- package/dist/node_modules/zod/v3/helpers/util.cjs +137 -0
- package/dist/node_modules/zod/v3/helpers/util.d.cts +85 -0
- package/dist/node_modules/zod/v3/helpers/util.d.ts +85 -0
- package/dist/node_modules/zod/v3/helpers/util.js +133 -0
- package/dist/node_modules/zod/v3/index.cjs +33 -0
- package/dist/node_modules/zod/v3/index.d.cts +4 -0
- package/dist/node_modules/zod/v3/index.d.ts +4 -0
- package/dist/node_modules/zod/v3/index.js +4 -0
- package/dist/node_modules/zod/v3/locales/en.cjs +112 -0
- package/dist/node_modules/zod/v3/locales/en.d.cts +3 -0
- package/dist/node_modules/zod/v3/locales/en.d.ts +3 -0
- package/dist/node_modules/zod/v3/locales/en.js +109 -0
- package/dist/node_modules/zod/v3/package.json +6 -0
- package/dist/node_modules/zod/v3/standard-schema.cjs +2 -0
- package/dist/node_modules/zod/v3/standard-schema.d.cts +102 -0
- package/dist/node_modules/zod/v3/standard-schema.d.ts +102 -0
- package/dist/node_modules/zod/v3/standard-schema.js +1 -0
- package/dist/node_modules/zod/v3/types.cjs +3777 -0
- package/dist/node_modules/zod/v3/types.d.cts +1034 -0
- package/dist/node_modules/zod/v3/types.d.ts +1034 -0
- package/dist/node_modules/zod/v3/types.js +3695 -0
- package/dist/node_modules/zod/v4/classic/checks.cjs +33 -0
- package/dist/node_modules/zod/v4/classic/checks.d.cts +1 -0
- package/dist/node_modules/zod/v4/classic/checks.d.ts +1 -0
- package/dist/node_modules/zod/v4/classic/checks.js +1 -0
- package/dist/node_modules/zod/v4/classic/coerce.cjs +47 -0
- package/dist/node_modules/zod/v4/classic/coerce.d.cts +17 -0
- package/dist/node_modules/zod/v4/classic/coerce.d.ts +17 -0
- package/dist/node_modules/zod/v4/classic/coerce.js +17 -0
- package/dist/node_modules/zod/v4/classic/compat.cjs +61 -0
- package/dist/node_modules/zod/v4/classic/compat.d.cts +50 -0
- package/dist/node_modules/zod/v4/classic/compat.d.ts +50 -0
- package/dist/node_modules/zod/v4/classic/compat.js +31 -0
- package/dist/node_modules/zod/v4/classic/errors.cjs +74 -0
- package/dist/node_modules/zod/v4/classic/errors.d.cts +30 -0
- package/dist/node_modules/zod/v4/classic/errors.d.ts +30 -0
- package/dist/node_modules/zod/v4/classic/errors.js +48 -0
- package/dist/node_modules/zod/v4/classic/external.cjs +73 -0
- package/dist/node_modules/zod/v4/classic/external.d.cts +15 -0
- package/dist/node_modules/zod/v4/classic/external.d.ts +15 -0
- package/dist/node_modules/zod/v4/classic/external.js +20 -0
- package/dist/node_modules/zod/v4/classic/from-json-schema.cjs +610 -0
- package/dist/node_modules/zod/v4/classic/from-json-schema.d.cts +12 -0
- package/dist/node_modules/zod/v4/classic/from-json-schema.d.ts +12 -0
- package/dist/node_modules/zod/v4/classic/from-json-schema.js +584 -0
- package/dist/node_modules/zod/v4/classic/index.cjs +33 -0
- package/dist/node_modules/zod/v4/classic/index.d.cts +4 -0
- package/dist/node_modules/zod/v4/classic/index.d.ts +4 -0
- package/dist/node_modules/zod/v4/classic/index.js +4 -0
- package/dist/node_modules/zod/v4/classic/iso.cjs +60 -0
- package/dist/node_modules/zod/v4/classic/iso.d.cts +22 -0
- package/dist/node_modules/zod/v4/classic/iso.d.ts +22 -0
- package/dist/node_modules/zod/v4/classic/iso.js +30 -0
- package/dist/node_modules/zod/v4/classic/package.json +6 -0
- package/dist/node_modules/zod/v4/classic/parse.cjs +41 -0
- package/dist/node_modules/zod/v4/classic/parse.d.cts +31 -0
- package/dist/node_modules/zod/v4/classic/parse.d.ts +31 -0
- package/dist/node_modules/zod/v4/classic/parse.js +15 -0
- package/dist/node_modules/zod/v4/classic/schemas.cjs +1272 -0
- package/dist/node_modules/zod/v4/classic/schemas.d.cts +739 -0
- package/dist/node_modules/zod/v4/classic/schemas.d.ts +739 -0
- package/dist/node_modules/zod/v4/classic/schemas.js +1157 -0
- package/dist/node_modules/zod/v4/core/api.cjs +1222 -0
- package/dist/node_modules/zod/v4/core/api.d.cts +304 -0
- package/dist/node_modules/zod/v4/core/api.d.ts +304 -0
- package/dist/node_modules/zod/v4/core/api.js +1082 -0
- package/dist/node_modules/zod/v4/core/checks.cjs +601 -0
- package/dist/node_modules/zod/v4/core/checks.d.cts +278 -0
- package/dist/node_modules/zod/v4/core/checks.d.ts +278 -0
- package/dist/node_modules/zod/v4/core/checks.js +575 -0
- package/dist/node_modules/zod/v4/core/core.cjs +83 -0
- package/dist/node_modules/zod/v4/core/core.d.cts +70 -0
- package/dist/node_modules/zod/v4/core/core.d.ts +70 -0
- package/dist/node_modules/zod/v4/core/core.js +76 -0
- package/dist/node_modules/zod/v4/core/doc.cjs +39 -0
- package/dist/node_modules/zod/v4/core/doc.d.cts +14 -0
- package/dist/node_modules/zod/v4/core/doc.d.ts +14 -0
- package/dist/node_modules/zod/v4/core/doc.js +35 -0
- package/dist/node_modules/zod/v4/core/errors.cjs +213 -0
- package/dist/node_modules/zod/v4/core/errors.d.cts +220 -0
- package/dist/node_modules/zod/v4/core/errors.d.ts +220 -0
- package/dist/node_modules/zod/v4/core/errors.js +182 -0
- package/dist/node_modules/zod/v4/core/index.cjs +47 -0
- package/dist/node_modules/zod/v4/core/index.d.cts +16 -0
- package/dist/node_modules/zod/v4/core/index.d.ts +16 -0
- package/dist/node_modules/zod/v4/core/index.js +16 -0
- package/dist/node_modules/zod/v4/core/json-schema-generator.cjs +99 -0
- package/dist/node_modules/zod/v4/core/json-schema-generator.d.cts +65 -0
- package/dist/node_modules/zod/v4/core/json-schema-generator.d.ts +65 -0
- package/dist/node_modules/zod/v4/core/json-schema-generator.js +95 -0
- package/dist/node_modules/zod/v4/core/json-schema-processors.cjs +648 -0
- package/dist/node_modules/zod/v4/core/json-schema-processors.d.cts +49 -0
- package/dist/node_modules/zod/v4/core/json-schema-processors.d.ts +49 -0
- package/dist/node_modules/zod/v4/core/json-schema-processors.js +605 -0
- package/dist/node_modules/zod/v4/core/json-schema.cjs +2 -0
- package/dist/node_modules/zod/v4/core/json-schema.d.cts +88 -0
- package/dist/node_modules/zod/v4/core/json-schema.d.ts +88 -0
- package/dist/node_modules/zod/v4/core/json-schema.js +1 -0
- package/dist/node_modules/zod/v4/core/package.json +6 -0
- package/dist/node_modules/zod/v4/core/parse.cjs +131 -0
- package/dist/node_modules/zod/v4/core/parse.d.cts +49 -0
- package/dist/node_modules/zod/v4/core/parse.d.ts +49 -0
- package/dist/node_modules/zod/v4/core/parse.js +93 -0
- package/dist/node_modules/zod/v4/core/regexes.cjs +166 -0
- package/dist/node_modules/zod/v4/core/regexes.d.cts +79 -0
- package/dist/node_modules/zod/v4/core/regexes.d.ts +79 -0
- package/dist/node_modules/zod/v4/core/regexes.js +133 -0
- package/dist/node_modules/zod/v4/core/registries.cjs +56 -0
- package/dist/node_modules/zod/v4/core/registries.d.cts +35 -0
- package/dist/node_modules/zod/v4/core/registries.d.ts +35 -0
- package/dist/node_modules/zod/v4/core/registries.js +51 -0
- package/dist/node_modules/zod/v4/core/schemas.cjs +2126 -0
- package/dist/node_modules/zod/v4/core/schemas.d.cts +1146 -0
- package/dist/node_modules/zod/v4/core/schemas.d.ts +1146 -0
- package/dist/node_modules/zod/v4/core/schemas.js +2095 -0
- package/dist/node_modules/zod/v4/core/standard-schema.cjs +2 -0
- package/dist/node_modules/zod/v4/core/standard-schema.d.cts +126 -0
- package/dist/node_modules/zod/v4/core/standard-schema.d.ts +126 -0
- package/dist/node_modules/zod/v4/core/standard-schema.js +1 -0
- package/dist/node_modules/zod/v4/core/to-json-schema.cjs +446 -0
- package/dist/node_modules/zod/v4/core/to-json-schema.d.cts +114 -0
- package/dist/node_modules/zod/v4/core/to-json-schema.d.ts +114 -0
- package/dist/node_modules/zod/v4/core/to-json-schema.js +437 -0
- package/dist/node_modules/zod/v4/core/util.cjs +710 -0
- package/dist/node_modules/zod/v4/core/util.d.cts +199 -0
- package/dist/node_modules/zod/v4/core/util.d.ts +199 -0
- package/dist/node_modules/zod/v4/core/util.js +651 -0
- package/dist/node_modules/zod/v4/core/versions.cjs +8 -0
- package/dist/node_modules/zod/v4/core/versions.d.cts +5 -0
- package/dist/node_modules/zod/v4/core/versions.d.ts +5 -0
- package/dist/node_modules/zod/v4/core/versions.js +5 -0
- package/dist/node_modules/zod/v4/index.cjs +22 -0
- package/dist/node_modules/zod/v4/index.d.cts +3 -0
- package/dist/node_modules/zod/v4/index.d.ts +3 -0
- package/dist/node_modules/zod/v4/index.js +3 -0
- package/dist/node_modules/zod/v4/locales/ar.cjs +133 -0
- package/dist/node_modules/zod/v4/locales/ar.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/ar.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/ar.js +106 -0
- package/dist/node_modules/zod/v4/locales/az.cjs +132 -0
- package/dist/node_modules/zod/v4/locales/az.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/az.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/az.js +105 -0
- package/dist/node_modules/zod/v4/locales/be.cjs +183 -0
- package/dist/node_modules/zod/v4/locales/be.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/be.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/be.js +156 -0
- package/dist/node_modules/zod/v4/locales/bg.cjs +147 -0
- package/dist/node_modules/zod/v4/locales/bg.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/bg.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/bg.js +120 -0
- package/dist/node_modules/zod/v4/locales/ca.cjs +134 -0
- package/dist/node_modules/zod/v4/locales/ca.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/ca.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/ca.js +107 -0
- package/dist/node_modules/zod/v4/locales/cs.cjs +138 -0
- package/dist/node_modules/zod/v4/locales/cs.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/cs.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/cs.js +111 -0
- package/dist/node_modules/zod/v4/locales/da.cjs +142 -0
- package/dist/node_modules/zod/v4/locales/da.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/da.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/da.js +115 -0
- package/dist/node_modules/zod/v4/locales/de.cjs +135 -0
- package/dist/node_modules/zod/v4/locales/de.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/de.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/de.js +108 -0
- package/dist/node_modules/zod/v4/locales/en.cjs +136 -0
- package/dist/node_modules/zod/v4/locales/en.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/en.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/en.js +109 -0
- package/dist/node_modules/zod/v4/locales/eo.cjs +136 -0
- package/dist/node_modules/zod/v4/locales/eo.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/eo.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/eo.js +109 -0
- package/dist/node_modules/zod/v4/locales/es.cjs +159 -0
- package/dist/node_modules/zod/v4/locales/es.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/es.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/es.js +132 -0
- package/dist/node_modules/zod/v4/locales/fa.cjs +141 -0
- package/dist/node_modules/zod/v4/locales/fa.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/fa.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/fa.js +114 -0
- package/dist/node_modules/zod/v4/locales/fi.cjs +139 -0
- package/dist/node_modules/zod/v4/locales/fi.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/fi.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/fi.js +112 -0
- package/dist/node_modules/zod/v4/locales/fr-CA.cjs +134 -0
- package/dist/node_modules/zod/v4/locales/fr-CA.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/fr-CA.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/fr-CA.js +107 -0
- package/dist/node_modules/zod/v4/locales/fr.cjs +135 -0
- package/dist/node_modules/zod/v4/locales/fr.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/fr.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/fr.js +108 -0
- package/dist/node_modules/zod/v4/locales/he.cjs +241 -0
- package/dist/node_modules/zod/v4/locales/he.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/he.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/he.js +214 -0
- package/dist/node_modules/zod/v4/locales/hu.cjs +135 -0
- package/dist/node_modules/zod/v4/locales/hu.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/hu.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/hu.js +108 -0
- package/dist/node_modules/zod/v4/locales/hy.cjs +174 -0
- package/dist/node_modules/zod/v4/locales/hy.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/hy.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/hy.js +147 -0
- package/dist/node_modules/zod/v4/locales/id.cjs +133 -0
- package/dist/node_modules/zod/v4/locales/id.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/id.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/id.js +106 -0
- package/dist/node_modules/zod/v4/locales/index.cjs +104 -0
- package/dist/node_modules/zod/v4/locales/index.d.cts +49 -0
- package/dist/node_modules/zod/v4/locales/index.d.ts +49 -0
- package/dist/node_modules/zod/v4/locales/index.js +49 -0
- package/dist/node_modules/zod/v4/locales/is.cjs +136 -0
- package/dist/node_modules/zod/v4/locales/is.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/is.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/is.js +109 -0
- package/dist/node_modules/zod/v4/locales/it.cjs +135 -0
- package/dist/node_modules/zod/v4/locales/it.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/it.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/it.js +108 -0
- package/dist/node_modules/zod/v4/locales/ja.cjs +134 -0
- package/dist/node_modules/zod/v4/locales/ja.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/ja.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/ja.js +107 -0
- package/dist/node_modules/zod/v4/locales/ka.cjs +139 -0
- package/dist/node_modules/zod/v4/locales/ka.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/ka.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/ka.js +112 -0
- package/dist/node_modules/zod/v4/locales/kh.cjs +12 -0
- package/dist/node_modules/zod/v4/locales/kh.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/kh.d.ts +5 -0
- package/dist/node_modules/zod/v4/locales/kh.js +5 -0
- package/dist/node_modules/zod/v4/locales/km.cjs +137 -0
- package/dist/node_modules/zod/v4/locales/km.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/km.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/km.js +110 -0
- package/dist/node_modules/zod/v4/locales/ko.cjs +138 -0
- package/dist/node_modules/zod/v4/locales/ko.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/ko.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/ko.js +111 -0
- package/dist/node_modules/zod/v4/locales/lt.cjs +230 -0
- package/dist/node_modules/zod/v4/locales/lt.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/lt.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/lt.js +203 -0
- package/dist/node_modules/zod/v4/locales/mk.cjs +136 -0
- package/dist/node_modules/zod/v4/locales/mk.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/mk.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/mk.js +109 -0
- package/dist/node_modules/zod/v4/locales/ms.cjs +134 -0
- package/dist/node_modules/zod/v4/locales/ms.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/ms.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/ms.js +107 -0
- package/dist/node_modules/zod/v4/locales/nl.cjs +137 -0
- package/dist/node_modules/zod/v4/locales/nl.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/nl.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/nl.js +110 -0
- package/dist/node_modules/zod/v4/locales/no.cjs +135 -0
- package/dist/node_modules/zod/v4/locales/no.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/no.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/no.js +108 -0
- package/dist/node_modules/zod/v4/locales/ota.cjs +136 -0
- package/dist/node_modules/zod/v4/locales/ota.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/ota.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/ota.js +109 -0
- package/dist/node_modules/zod/v4/locales/package.json +6 -0
- package/dist/node_modules/zod/v4/locales/pl.cjs +136 -0
- package/dist/node_modules/zod/v4/locales/pl.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/pl.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/pl.js +109 -0
- package/dist/node_modules/zod/v4/locales/ps.cjs +141 -0
- package/dist/node_modules/zod/v4/locales/ps.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/ps.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/ps.js +114 -0
- package/dist/node_modules/zod/v4/locales/pt.cjs +135 -0
- package/dist/node_modules/zod/v4/locales/pt.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/pt.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/pt.js +108 -0
- package/dist/node_modules/zod/v4/locales/ru.cjs +183 -0
- package/dist/node_modules/zod/v4/locales/ru.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/ru.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/ru.js +156 -0
- package/dist/node_modules/zod/v4/locales/sl.cjs +136 -0
- package/dist/node_modules/zod/v4/locales/sl.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/sl.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/sl.js +109 -0
- package/dist/node_modules/zod/v4/locales/sv.cjs +137 -0
- package/dist/node_modules/zod/v4/locales/sv.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/sv.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/sv.js +110 -0
- package/dist/node_modules/zod/v4/locales/ta.cjs +137 -0
- package/dist/node_modules/zod/v4/locales/ta.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/ta.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/ta.js +110 -0
- package/dist/node_modules/zod/v4/locales/th.cjs +137 -0
- package/dist/node_modules/zod/v4/locales/th.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/th.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/th.js +110 -0
- package/dist/node_modules/zod/v4/locales/tr.cjs +132 -0
- package/dist/node_modules/zod/v4/locales/tr.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/tr.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/tr.js +105 -0
- package/dist/node_modules/zod/v4/locales/ua.cjs +12 -0
- package/dist/node_modules/zod/v4/locales/ua.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/ua.d.ts +5 -0
- package/dist/node_modules/zod/v4/locales/ua.js +5 -0
- package/dist/node_modules/zod/v4/locales/uk.cjs +135 -0
- package/dist/node_modules/zod/v4/locales/uk.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/uk.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/uk.js +108 -0
- package/dist/node_modules/zod/v4/locales/ur.cjs +137 -0
- package/dist/node_modules/zod/v4/locales/ur.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/ur.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/ur.js +110 -0
- package/dist/node_modules/zod/v4/locales/uz.cjs +136 -0
- package/dist/node_modules/zod/v4/locales/uz.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/uz.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/uz.js +109 -0
- package/dist/node_modules/zod/v4/locales/vi.cjs +135 -0
- package/dist/node_modules/zod/v4/locales/vi.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/vi.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/vi.js +108 -0
- package/dist/node_modules/zod/v4/locales/yo.cjs +134 -0
- package/dist/node_modules/zod/v4/locales/yo.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/yo.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/yo.js +107 -0
- package/dist/node_modules/zod/v4/locales/zh-CN.cjs +136 -0
- package/dist/node_modules/zod/v4/locales/zh-CN.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/zh-CN.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/zh-CN.js +109 -0
- package/dist/node_modules/zod/v4/locales/zh-TW.cjs +134 -0
- package/dist/node_modules/zod/v4/locales/zh-TW.d.cts +5 -0
- package/dist/node_modules/zod/v4/locales/zh-TW.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/zh-TW.js +107 -0
- package/dist/node_modules/zod/v4/mini/checks.cjs +34 -0
- package/dist/node_modules/zod/v4/mini/checks.d.cts +1 -0
- package/dist/node_modules/zod/v4/mini/checks.d.ts +1 -0
- package/dist/node_modules/zod/v4/mini/checks.js +1 -0
- package/dist/node_modules/zod/v4/mini/coerce.cjs +52 -0
- package/dist/node_modules/zod/v4/mini/coerce.d.cts +7 -0
- package/dist/node_modules/zod/v4/mini/coerce.d.ts +7 -0
- package/dist/node_modules/zod/v4/mini/coerce.js +22 -0
- package/dist/node_modules/zod/v4/mini/external.cjs +63 -0
- package/dist/node_modules/zod/v4/mini/external.d.cts +12 -0
- package/dist/node_modules/zod/v4/mini/external.d.ts +12 -0
- package/dist/node_modules/zod/v4/mini/external.js +14 -0
- package/dist/node_modules/zod/v4/mini/index.cjs +32 -0
- package/dist/node_modules/zod/v4/mini/index.d.cts +3 -0
- package/dist/node_modules/zod/v4/mini/index.d.ts +3 -0
- package/dist/node_modules/zod/v4/mini/index.js +3 -0
- package/dist/node_modules/zod/v4/mini/iso.cjs +64 -0
- package/dist/node_modules/zod/v4/mini/iso.d.cts +22 -0
- package/dist/node_modules/zod/v4/mini/iso.d.ts +22 -0
- package/dist/node_modules/zod/v4/mini/iso.js +34 -0
- package/dist/node_modules/zod/v4/mini/package.json +6 -0
- package/dist/node_modules/zod/v4/mini/parse.cjs +16 -0
- package/dist/node_modules/zod/v4/mini/parse.d.cts +1 -0
- package/dist/node_modules/zod/v4/mini/parse.d.ts +1 -0
- package/dist/node_modules/zod/v4/mini/parse.js +1 -0
- package/dist/node_modules/zod/v4/mini/schemas.cjs +1046 -0
- package/dist/node_modules/zod/v4/mini/schemas.d.cts +427 -0
- package/dist/node_modules/zod/v4/mini/schemas.d.ts +427 -0
- package/dist/node_modules/zod/v4/mini/schemas.js +925 -0
- package/dist/node_modules/zod/v4/package.json +6 -0
- package/dist/node_modules/zod/v4-mini/index.cjs +17 -0
- package/dist/node_modules/zod/v4-mini/index.d.cts +1 -0
- package/dist/node_modules/zod/v4-mini/index.d.ts +1 -0
- package/dist/node_modules/zod/v4-mini/index.js +1 -0
- package/dist/node_modules/zod/v4-mini/package.json +6 -0
- package/dist/server/actions/git-actions.js +43 -23
- package/dist/server/actions/gitlab-api.d.ts +4 -0
- package/dist/server/actions/gitlab-api.js +376 -0
- package/dist/server/actions/poller.d.ts +8 -0
- package/dist/server/actions/poller.js +55 -0
- package/dist/server/actions/review.d.ts +37 -0
- package/dist/server/actions/review.js +620 -0
- package/dist/server/ai-tools.d.ts +10 -0
- package/dist/server/ai-tools.js +278 -0
- package/dist/server/collections/gitCodeReviews.d.ts +2 -0
- package/dist/server/collections/gitCodeReviews.js +221 -0
- package/dist/server/collections/gitRepositories.d.ts +1 -1
- package/dist/server/collections/gitRepositories.js +22 -1
- package/dist/server/collections/gitReviewFlows.d.ts +2 -0
- package/dist/server/collections/gitReviewFlows.js +138 -0
- package/dist/server/plugin.d.ts +2 -0
- package/dist/server/plugin.js +69 -3
- package/dist/server/poller.d.ts +30 -0
- package/dist/server/poller.js +317 -0
- package/dist/server/utils/gitlab-url.d.ts +21 -0
- package/dist/server/utils/gitlab-url.js +47 -0
- package/dist/server/utils/redact.d.ts +13 -0
- package/dist/server/utils/redact.js +49 -0
- package/package.json +6 -1
- package/src/client/ai-context.tsx +114 -0
- package/src/client/components/AIEmployeeSelect.tsx +63 -0
- package/src/client/components/CommitHistory.tsx +14 -0
- package/src/client/components/GitManagerSettings.tsx +44 -1
- package/src/client/components/MarkdownView.tsx +83 -0
- package/src/client/components/MergeRequests.tsx +681 -0
- package/src/client/components/PollingStatus.tsx +194 -0
- package/src/client/components/RepositoryConfig.tsx +38 -3
- package/src/client/components/ReviewFlows.tsx +255 -0
- package/src/client/components/ReviewHistory.tsx +517 -0
- package/src/client/components/RunReviewButton.tsx +278 -0
- package/src/client/index.tsx +12 -0
- package/src/locale/en-US.json +137 -1
- package/src/locale/vi-VN.json +137 -1
- package/src/server/actions/git-actions.ts +56 -23
- package/src/server/actions/gitlab-api.ts +379 -0
- package/src/server/actions/poller.ts +26 -0
- package/src/server/actions/review.ts +751 -0
- package/src/server/ai-tools.ts +263 -0
- package/src/server/collections/gitCodeReviews.ts +191 -0
- package/src/server/collections/gitRepositories.ts +22 -1
- package/src/server/collections/gitReviewFlows.ts +108 -0
- package/src/server/plugin.ts +72 -0
- package/src/server/poller.ts +344 -0
- package/src/server/utils/gitlab-url.ts +35 -0
- package/src/server/utils/redact.ts +24 -0
- package/dist/client/100.e08d760e0b01997c.js +0 -10
|
@@ -0,0 +1,751 @@
|
|
|
1
|
+
import { Context } from '@nocobase/actions';
|
|
2
|
+
import type { Application } from '@nocobase/server';
|
|
3
|
+
import { parseGitLabProject } from '../utils/gitlab-url';
|
|
4
|
+
import { redactPat } from '../utils/redact';
|
|
5
|
+
|
|
6
|
+
interface TriggerArgs {
|
|
7
|
+
flowId?: number | null;
|
|
8
|
+
repositoryId: number;
|
|
9
|
+
targetType: 'mr' | 'commit' | 'branch';
|
|
10
|
+
mrIid?: number | null;
|
|
11
|
+
commitSha?: string | null;
|
|
12
|
+
branch?: string | null;
|
|
13
|
+
headSha?: string | null;
|
|
14
|
+
extraInstructions?: string;
|
|
15
|
+
triggeredBy?: 'manual' | 'poll';
|
|
16
|
+
userId?: number | string | null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Per-target mutex to prevent two concurrent calls to
|
|
21
|
+
* `triggerReviewInternal` for the same MR / commit / branch from racing
|
|
22
|
+
* `findOne` → `create` and producing two duplicate review rows or
|
|
23
|
+
* scheduling two `runReview`s.
|
|
24
|
+
*
|
|
25
|
+
* Uses `app.lockManager` so the same code path covers both single-node
|
|
26
|
+
* (in-memory `async-mutex`) and HA cluster (Redis-backed Redlock when
|
|
27
|
+
* `plugin-cluster-manager` is active and `LOCK_ADAPTER_DEFAULT=redis`).
|
|
28
|
+
* The locked region only does an upsert + setImmediate (a few ms), so a
|
|
29
|
+
* 30s TTL is generous and auto-releases if the process crashes.
|
|
30
|
+
*/
|
|
31
|
+
function targetKey(args: TriggerArgs): string {
|
|
32
|
+
if (args.targetType === 'mr') return `${args.repositoryId}:mr:${args.mrIid}`;
|
|
33
|
+
if (args.targetType === 'commit') return `${args.repositoryId}:commit:${args.commitSha}`;
|
|
34
|
+
return `${args.repositoryId}:branch:${args.branch}`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const TRIGGER_LOCK_TTL_MS = 30_000;
|
|
38
|
+
|
|
39
|
+
async function withTriggerLock<T>(app: Application, key: string, fn: () => Promise<T>): Promise<T> {
|
|
40
|
+
const lockKey = `git-review:trigger:${key}`;
|
|
41
|
+
return app.lockManager.runExclusive(lockKey, fn, TRIGGER_LOCK_TTL_MS);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Trigger an AI-driven code review for an MR / commit / branch.
|
|
46
|
+
* The review record is upserted synchronously, then AIEmployee.invoke runs in
|
|
47
|
+
* the background. The action returns immediately with the reviewId.
|
|
48
|
+
*/
|
|
49
|
+
export async function triggerReview(ctx: Context, next: () => Promise<void>) {
|
|
50
|
+
const params = { ...ctx.action.params, ...ctx.action.params?.values, ...( (ctx.request.body as any) || {} ) };
|
|
51
|
+
const {
|
|
52
|
+
flowId,
|
|
53
|
+
repositoryId,
|
|
54
|
+
targetType,
|
|
55
|
+
mrIid,
|
|
56
|
+
commitSha,
|
|
57
|
+
branch,
|
|
58
|
+
extraInstructions,
|
|
59
|
+
} = params;
|
|
60
|
+
|
|
61
|
+
if (!repositoryId) ctx.throw(400, 'repositoryId is required');
|
|
62
|
+
if (!targetType) ctx.throw(400, 'targetType is required');
|
|
63
|
+
if (!['mr', 'commit', 'branch'].includes(targetType)) ctx.throw(400, 'invalid targetType');
|
|
64
|
+
if (targetType === 'mr' && !mrIid) ctx.throw(400, 'mrIid is required for MR review');
|
|
65
|
+
if (targetType === 'commit' && !commitSha) ctx.throw(400, 'commitSha is required for commit review');
|
|
66
|
+
if (targetType === 'branch' && !branch) ctx.throw(400, 'branch is required for branch review');
|
|
67
|
+
|
|
68
|
+
const userId = (ctx as any).state?.currentUser?.id;
|
|
69
|
+
try {
|
|
70
|
+
const reviewId = await triggerReviewInternal(ctx.app, {
|
|
71
|
+
flowId,
|
|
72
|
+
repositoryId: Number(repositoryId),
|
|
73
|
+
targetType,
|
|
74
|
+
mrIid: mrIid != null ? Number(mrIid) : null,
|
|
75
|
+
commitSha: commitSha || null,
|
|
76
|
+
branch: branch || null,
|
|
77
|
+
extraInstructions,
|
|
78
|
+
triggeredBy: 'manual',
|
|
79
|
+
userId,
|
|
80
|
+
});
|
|
81
|
+
ctx.body = { success: true, data: { reviewId } };
|
|
82
|
+
} catch (err: any) {
|
|
83
|
+
ctx.throw(err.status || 400, err.message || 'Failed to trigger review');
|
|
84
|
+
}
|
|
85
|
+
await next();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Programmatic entry point — used by manual action and by the poller.
|
|
90
|
+
* Returns the reviewId of the upserted record.
|
|
91
|
+
*/
|
|
92
|
+
export async function triggerReviewInternal(app: Application, args: TriggerArgs): Promise<number> {
|
|
93
|
+
return withTriggerLock(app, targetKey(args), () => triggerReviewInternalLocked(app, args));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function triggerReviewInternalLocked(app: Application, args: TriggerArgs): Promise<number> {
|
|
97
|
+
const db = app.db;
|
|
98
|
+
const flowsRepo = db.getRepository('gitReviewFlows');
|
|
99
|
+
|
|
100
|
+
// Resolve flow
|
|
101
|
+
let flow: any = null;
|
|
102
|
+
if (args.flowId) {
|
|
103
|
+
flow = await flowsRepo.findOne({ filterByTk: args.flowId });
|
|
104
|
+
if (!flow) throwHttp(404, 'Review flow not found');
|
|
105
|
+
if (!flow.get('enabled')) throwHttp(400, 'Review flow is disabled');
|
|
106
|
+
} else {
|
|
107
|
+
// Find flows scoped to repo or global, prefer repo-specific
|
|
108
|
+
const candidates = await flowsRepo.find({
|
|
109
|
+
filter: {
|
|
110
|
+
enabled: true,
|
|
111
|
+
$or: [{ repositoryId: args.repositoryId }, { repositoryId: null }],
|
|
112
|
+
},
|
|
113
|
+
sort: ['-repositoryId'],
|
|
114
|
+
});
|
|
115
|
+
flow = pickFlowMatchingBranch(candidates, args.branch || undefined);
|
|
116
|
+
if (!flow) throwHttp(400, 'No enabled review flow found for this repository');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Apply branchFilter even when flow is explicitly given (consistency)
|
|
120
|
+
if (args.branch && !branchMatches(flow, args.branch)) {
|
|
121
|
+
throwHttp(400, `Branch '${args.branch}' does not match flow's branchFilter`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const aiEmployeeUsername = flow.get('aiEmployeeUsername') as string;
|
|
125
|
+
if (!aiEmployeeUsername) throwHttp(400, 'Flow has no AI employee configured');
|
|
126
|
+
|
|
127
|
+
const repo = await db.getRepository('gitRepositories').findOne({ filterByTk: args.repositoryId });
|
|
128
|
+
if (!repo) throwHttp(404, 'Repository not found');
|
|
129
|
+
|
|
130
|
+
// For MR targets, ensure we know the head SHA so the "new commits" indicator
|
|
131
|
+
// works regardless of whether the trigger came from poller or manual UI.
|
|
132
|
+
let headSha = args.headSha || null;
|
|
133
|
+
if (args.targetType === 'mr' && !headSha && args.mrIid) {
|
|
134
|
+
headSha = await fetchMrHeadSha(repo, args.mrIid).catch(() => null);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Upsert review record (1 per MR/commit/branch target)
|
|
138
|
+
const reviewsRepo = db.getRepository('gitCodeReviews');
|
|
139
|
+
const targetFilter: any = {
|
|
140
|
+
repositoryId: args.repositoryId,
|
|
141
|
+
targetType: args.targetType,
|
|
142
|
+
};
|
|
143
|
+
if (args.targetType === 'mr') targetFilter.mrIid = args.mrIid;
|
|
144
|
+
else if (args.targetType === 'commit') targetFilter.commitSha = args.commitSha;
|
|
145
|
+
else if (args.targetType === 'branch') targetFilter.branch = args.branch;
|
|
146
|
+
|
|
147
|
+
const existing = await reviewsRepo.findOne({ filter: targetFilter });
|
|
148
|
+
// Preserve a poller-tracked latestSha if we don't have a fresher one.
|
|
149
|
+
const existingLatestSha = existing?.get('latestSha') as string | null | undefined;
|
|
150
|
+
const baseValues: any = {
|
|
151
|
+
flowId: flow.get('id'),
|
|
152
|
+
repositoryId: args.repositoryId,
|
|
153
|
+
targetType: args.targetType,
|
|
154
|
+
mrIid: args.targetType === 'mr' ? args.mrIid : null,
|
|
155
|
+
commitSha: args.targetType === 'commit' ? args.commitSha : null,
|
|
156
|
+
branch: args.branch || null,
|
|
157
|
+
headSha: headSha,
|
|
158
|
+
latestSha: headSha || existingLatestSha || null,
|
|
159
|
+
triggeredBy: args.triggeredBy || 'manual',
|
|
160
|
+
status: 'pending',
|
|
161
|
+
// Stamp startedAt synchronously so `recoverStuckReviews` can sweep rows
|
|
162
|
+
// that get stuck in `pending` (process died before runReview ran).
|
|
163
|
+
// runReview's own update will refresh this on actual start.
|
|
164
|
+
startedAt: new Date(),
|
|
165
|
+
finishedAt: null,
|
|
166
|
+
durationMs: null,
|
|
167
|
+
postStatus: flow.get('postMode') === 'disabled' ? 'skipped' : 'pending_approval',
|
|
168
|
+
error: null,
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
let reviewId: number;
|
|
172
|
+
if (existing) {
|
|
173
|
+
const st = existing.get('status');
|
|
174
|
+
// Treat `pending` the same as `running`: between this fn returning and
|
|
175
|
+
// the scheduled `runReview` flipping the row to `running`, a second
|
|
176
|
+
// caller would otherwise slip past and schedule a duplicate runReview.
|
|
177
|
+
// Stuck `pending` rows (process died before runReview ran) are swept
|
|
178
|
+
// by `recoverStuckReviews` on next startup.
|
|
179
|
+
if (st === 'running' || st === 'pending') {
|
|
180
|
+
return existing.get('id') as number;
|
|
181
|
+
}
|
|
182
|
+
await reviewsRepo.update({
|
|
183
|
+
filterByTk: existing.get('id'),
|
|
184
|
+
values: baseValues,
|
|
185
|
+
});
|
|
186
|
+
reviewId = existing.get('id') as number;
|
|
187
|
+
} else {
|
|
188
|
+
const review = await reviewsRepo.create({ values: baseValues });
|
|
189
|
+
reviewId = review.get('id') as number;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Run in background — do not await
|
|
193
|
+
setImmediate(() =>
|
|
194
|
+
runReview(app, {
|
|
195
|
+
reviewId,
|
|
196
|
+
flow,
|
|
197
|
+
repo,
|
|
198
|
+
targetType: args.targetType,
|
|
199
|
+
mrIid: args.targetType === 'mr' ? args.mrIid! : null,
|
|
200
|
+
commitSha: args.targetType === 'commit' ? args.commitSha! : null,
|
|
201
|
+
branch: args.branch || undefined,
|
|
202
|
+
headSha,
|
|
203
|
+
aiEmployeeUsername,
|
|
204
|
+
extraInstructions: args.extraInstructions,
|
|
205
|
+
userId: args.userId ?? null,
|
|
206
|
+
}).catch((err) => {
|
|
207
|
+
app.log?.error?.('runReview background error', err);
|
|
208
|
+
}),
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
return reviewId;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Mark a review as approved and post its content to GitLab as an MR note.
|
|
216
|
+
*/
|
|
217
|
+
export async function reviewApprovePost(ctx: Context, next: () => Promise<void>) {
|
|
218
|
+
const params = { ...ctx.action.params, ...ctx.action.params?.values, ...( (ctx.request.body as any) || {} ) };
|
|
219
|
+
const { reviewId, editedMarkdown } = params;
|
|
220
|
+
if (!reviewId) ctx.throw(400, 'reviewId is required');
|
|
221
|
+
|
|
222
|
+
const reviewsRepo = ctx.db.getRepository('gitCodeReviews');
|
|
223
|
+
const review = await reviewsRepo.findOne({ filterByTk: reviewId });
|
|
224
|
+
if (!review) ctx.throw(404, 'Review not found');
|
|
225
|
+
if (review.get('status') !== 'completed') ctx.throw(400, 'Review is not completed');
|
|
226
|
+
if (review.get('targetType') !== 'mr') ctx.throw(400, 'Only MR reviews can be posted');
|
|
227
|
+
|
|
228
|
+
const markdown = (editedMarkdown ?? review.get('reviewMarkdown')) as string;
|
|
229
|
+
if (!markdown) ctx.throw(400, 'No review content to post');
|
|
230
|
+
|
|
231
|
+
const repo = await ctx.db.getRepository('gitRepositories').findOne({
|
|
232
|
+
filterByTk: review.get('repositoryId'),
|
|
233
|
+
});
|
|
234
|
+
if (!repo) ctx.throw(404, 'Repository not found');
|
|
235
|
+
|
|
236
|
+
const noteId = await postNoteToGitLab(repo, Number(review.get('mrIid')), markdown);
|
|
237
|
+
|
|
238
|
+
const userId = (ctx as any).state?.currentUser?.id;
|
|
239
|
+
await reviewsRepo.update({
|
|
240
|
+
filterByTk: reviewId,
|
|
241
|
+
values: {
|
|
242
|
+
reviewMarkdown: markdown,
|
|
243
|
+
postStatus: 'posted',
|
|
244
|
+
postedNoteId: String(noteId),
|
|
245
|
+
approvedBy: userId ? String(userId) : null,
|
|
246
|
+
approvedAt: new Date(),
|
|
247
|
+
},
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
ctx.body = { success: true, data: { reviewId, postedNoteId: noteId } };
|
|
251
|
+
await next();
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Reject a pending review (do not post to GitLab).
|
|
256
|
+
*/
|
|
257
|
+
export async function reviewReject(ctx: Context, next: () => Promise<void>) {
|
|
258
|
+
const params = { ...ctx.action.params, ...ctx.action.params?.values, ...( (ctx.request.body as any) || {} ) };
|
|
259
|
+
const { reviewId, reason } = params;
|
|
260
|
+
if (!reviewId) ctx.throw(400, 'reviewId is required');
|
|
261
|
+
|
|
262
|
+
const reviewsRepo = ctx.db.getRepository('gitCodeReviews');
|
|
263
|
+
const review = await reviewsRepo.findOne({ filterByTk: reviewId });
|
|
264
|
+
if (!review) ctx.throw(404, 'Review not found');
|
|
265
|
+
|
|
266
|
+
const userId = (ctx as any).state?.currentUser?.id;
|
|
267
|
+
await reviewsRepo.update({
|
|
268
|
+
filterByTk: reviewId,
|
|
269
|
+
values: {
|
|
270
|
+
postStatus: 'rejected',
|
|
271
|
+
approvedBy: userId ? String(userId) : null,
|
|
272
|
+
approvedAt: new Date(),
|
|
273
|
+
error: reason ? `Rejected: ${reason}` : 'Rejected',
|
|
274
|
+
},
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
ctx.body = { success: true, data: { reviewId } };
|
|
278
|
+
await next();
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/* ───────── Helpers ───────── */
|
|
282
|
+
|
|
283
|
+
interface RunReviewArgs {
|
|
284
|
+
reviewId: number;
|
|
285
|
+
flow: any;
|
|
286
|
+
repo: any;
|
|
287
|
+
targetType: string;
|
|
288
|
+
mrIid: number | null;
|
|
289
|
+
commitSha: string | null;
|
|
290
|
+
branch?: string;
|
|
291
|
+
headSha?: string | null;
|
|
292
|
+
aiEmployeeUsername: string;
|
|
293
|
+
extraInstructions?: string;
|
|
294
|
+
userId?: number | string | null;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
async function runReview(app: Application, args: RunReviewArgs) {
|
|
298
|
+
const db = app.db;
|
|
299
|
+
const reviewsRepo = db.getRepository('gitCodeReviews');
|
|
300
|
+
const startedAt = new Date();
|
|
301
|
+
let sessionId: string | null = null;
|
|
302
|
+
|
|
303
|
+
try {
|
|
304
|
+
await reviewsRepo.update({
|
|
305
|
+
filterByTk: args.reviewId,
|
|
306
|
+
values: { status: 'running', startedAt },
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
const employeeRecord = await db.getRepository('aiEmployees').findOne({
|
|
310
|
+
filter: { username: args.aiEmployeeUsername },
|
|
311
|
+
});
|
|
312
|
+
if (!employeeRecord) {
|
|
313
|
+
throw new Error(`AI employee '${args.aiEmployeeUsername}' not found`);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const conversation = await db.getRepository('aiConversations').create({
|
|
317
|
+
values: {
|
|
318
|
+
userId: args.userId ?? null,
|
|
319
|
+
aiEmployee: { username: args.aiEmployeeUsername },
|
|
320
|
+
options: {},
|
|
321
|
+
thread: 1,
|
|
322
|
+
},
|
|
323
|
+
});
|
|
324
|
+
// aiConversations uses sessionId (uuid) as primary key — no `id` field exists.
|
|
325
|
+
sessionId = (conversation.get('sessionId') as string) || null;
|
|
326
|
+
if (!sessionId) {
|
|
327
|
+
throw new Error('Failed to resolve sessionId from created aiConversation');
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
await reviewsRepo.update({
|
|
331
|
+
filterByTk: args.reviewId,
|
|
332
|
+
values: { sessionId },
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
const prompt = buildReviewPrompt(args);
|
|
336
|
+
|
|
337
|
+
// Synthesize a minimal ctx-shaped object that AIEmployee accepts.
|
|
338
|
+
// It needs `app`, `db`, `state.currentUser`, `get(headerName)`, `req.headers`.
|
|
339
|
+
const syntheticCtx: any = {
|
|
340
|
+
app,
|
|
341
|
+
db,
|
|
342
|
+
state: { currentUser: args.userId ? { id: args.userId } : null },
|
|
343
|
+
req: { headers: { 'x-timezone': 'UTC', 'x-locale': 'en-US' } },
|
|
344
|
+
get(name: string) {
|
|
345
|
+
return this.req.headers[String(name).toLowerCase()];
|
|
346
|
+
},
|
|
347
|
+
getCurrentLocale() {
|
|
348
|
+
return 'en-US';
|
|
349
|
+
},
|
|
350
|
+
t(key: string) {
|
|
351
|
+
return key;
|
|
352
|
+
},
|
|
353
|
+
i18n: {
|
|
354
|
+
t(key: string) {
|
|
355
|
+
return key;
|
|
356
|
+
},
|
|
357
|
+
},
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
// H-3 fix: try multiple import paths for resilience against plugin-ai restructuring
|
|
361
|
+
let AIEmployee: any;
|
|
362
|
+
for (const importPath of [
|
|
363
|
+
'@nocobase/plugin-ai/dist/server/ai-employees/ai-employee.js',
|
|
364
|
+
'@nocobase/plugin-ai/dist/server/ai-employees/ai-employee',
|
|
365
|
+
'@nocobase/plugin-ai/server',
|
|
366
|
+
]) {
|
|
367
|
+
try {
|
|
368
|
+
const mod = await import(/* webpackIgnore: true */ importPath as any);
|
|
369
|
+
AIEmployee = (mod as any).AIEmployee || (mod as any).default?.AIEmployee;
|
|
370
|
+
if (AIEmployee) break;
|
|
371
|
+
} catch {
|
|
372
|
+
// try next path
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
if (!AIEmployee) throw new Error('AIEmployee class not found — plugin-ai may not be installed or its exports changed');
|
|
376
|
+
|
|
377
|
+
const llmService = args.flow.get('llmService') as string | null;
|
|
378
|
+
const model = args.flow.get('model') as string | null;
|
|
379
|
+
const modelRef = llmService && model ? { llmService, model } : undefined;
|
|
380
|
+
|
|
381
|
+
const aiEmployee = new AIEmployee(
|
|
382
|
+
syntheticCtx,
|
|
383
|
+
employeeRecord,
|
|
384
|
+
sessionId,
|
|
385
|
+
undefined,
|
|
386
|
+
undefined,
|
|
387
|
+
false,
|
|
388
|
+
modelRef,
|
|
389
|
+
false,
|
|
390
|
+
);
|
|
391
|
+
|
|
392
|
+
// H-4 fix: enforce a timeout on AI review execution to prevent stuck reviews
|
|
393
|
+
const REVIEW_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
|
|
394
|
+
const result = await Promise.race([
|
|
395
|
+
aiEmployee.invoke({
|
|
396
|
+
userMessages: [
|
|
397
|
+
{
|
|
398
|
+
role: 'user',
|
|
399
|
+
content: { type: 'text', content: prompt },
|
|
400
|
+
},
|
|
401
|
+
],
|
|
402
|
+
}),
|
|
403
|
+
new Promise<never>((_, reject) =>
|
|
404
|
+
setTimeout(() => reject(new Error('AI review timed out after 5 minutes')), REVIEW_TIMEOUT_MS),
|
|
405
|
+
),
|
|
406
|
+
]);
|
|
407
|
+
|
|
408
|
+
const content = extractLastAiMessageContent(result);
|
|
409
|
+
if (!content) {
|
|
410
|
+
throw new Error('AI employee returned empty review content');
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
const finishedAt = new Date();
|
|
414
|
+
const durationMs = finishedAt.getTime() - startedAt.getTime();
|
|
415
|
+
|
|
416
|
+
const postMode = args.flow.get('postMode') as string;
|
|
417
|
+
let postStatus = 'pending_approval';
|
|
418
|
+
let postedNoteId: string | null = null;
|
|
419
|
+
|
|
420
|
+
if (postMode === 'disabled') {
|
|
421
|
+
postStatus = 'skipped';
|
|
422
|
+
} else if (postMode === 'auto' && args.targetType === 'mr' && args.mrIid) {
|
|
423
|
+
try {
|
|
424
|
+
postedNoteId = String(await postNoteToGitLab(args.repo, args.mrIid, content));
|
|
425
|
+
postStatus = 'posted';
|
|
426
|
+
} catch (err: any) {
|
|
427
|
+
app.log?.error?.('Auto-post review note failed', err);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
await reviewsRepo.update({
|
|
432
|
+
filterByTk: args.reviewId,
|
|
433
|
+
values: {
|
|
434
|
+
status: 'completed',
|
|
435
|
+
reviewMarkdown: content,
|
|
436
|
+
rawOutput: JSON.stringify({
|
|
437
|
+
messageCount: result?.messages?.length ?? 0,
|
|
438
|
+
llmService: llmService || 'default',
|
|
439
|
+
model: model || 'default',
|
|
440
|
+
}),
|
|
441
|
+
durationMs,
|
|
442
|
+
finishedAt,
|
|
443
|
+
postStatus,
|
|
444
|
+
postedNoteId,
|
|
445
|
+
metadata: {
|
|
446
|
+
flowName: args.flow.get('name'),
|
|
447
|
+
aiEmployeeUsername: args.aiEmployeeUsername,
|
|
448
|
+
llmService,
|
|
449
|
+
model,
|
|
450
|
+
},
|
|
451
|
+
},
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
if (sessionId) {
|
|
455
|
+
db.getRepository('aiConversations')
|
|
456
|
+
.destroy({ filterByTk: sessionId })
|
|
457
|
+
.catch(() => undefined);
|
|
458
|
+
}
|
|
459
|
+
} catch (err: any) {
|
|
460
|
+
const finishedAt = new Date();
|
|
461
|
+
// Redact PAT before persisting the error — simple-git / fetch errors
|
|
462
|
+
// can echo back the authenticated remote URL in their messages.
|
|
463
|
+
const safeMessage = redactPat(err?.message || String(err));
|
|
464
|
+
await reviewsRepo.update({
|
|
465
|
+
filterByTk: args.reviewId,
|
|
466
|
+
values: {
|
|
467
|
+
status: 'failed',
|
|
468
|
+
error: safeMessage,
|
|
469
|
+
finishedAt,
|
|
470
|
+
durationMs: finishedAt.getTime() - startedAt.getTime(),
|
|
471
|
+
},
|
|
472
|
+
});
|
|
473
|
+
if (sessionId) {
|
|
474
|
+
db.getRepository('aiConversations')
|
|
475
|
+
.destroy({ filterByTk: sessionId })
|
|
476
|
+
.catch(() => undefined);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
function buildReviewPrompt(args: RunReviewArgs): string {
|
|
482
|
+
const lines: string[] = [];
|
|
483
|
+
lines.push(`You are performing a code review on repository "${args.repo.get('name')}" (id=${args.repo.get('id')}).`);
|
|
484
|
+
lines.push('');
|
|
485
|
+
|
|
486
|
+
if (args.targetType === 'mr') {
|
|
487
|
+
lines.push(`Target: Merge Request !${args.mrIid}.`);
|
|
488
|
+
lines.push(`Use the \`git_get_merge_request\` tool with repositoryId=${args.repo.get('id')} and mrIid=${args.mrIid} to fetch the diff and metadata.`);
|
|
489
|
+
lines.push('Optionally call `git_get_merge_request_notes` to avoid duplicating prior comments.');
|
|
490
|
+
} else if (args.targetType === 'commit') {
|
|
491
|
+
lines.push(`Target: Commit ${args.commitSha}.`);
|
|
492
|
+
lines.push(`Use the \`git_get_commit\` tool with repositoryId=${args.repo.get('id')} and commitHash=${args.commitSha} to fetch the diff.`);
|
|
493
|
+
} else {
|
|
494
|
+
lines.push(`Target: Branch ${args.branch}.`);
|
|
495
|
+
lines.push(`Use \`git_list_commits\`, \`git_get_diff\`, and \`git_get_file_content\` (with repositoryId=${args.repo.get('id')}) to inspect recent changes on this branch.`);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
lines.push('');
|
|
499
|
+
lines.push('Produce a thorough but concise code review report in Markdown. Required sections:');
|
|
500
|
+
lines.push('1. **Summary** — overall assessment.');
|
|
501
|
+
lines.push('2. **Findings** — issues grouped by severity (`Critical`, `High`, `Medium`, `Low`, `Info`). For each finding include the file path, line/range when possible, the problem, and a suggested fix.');
|
|
502
|
+
lines.push('3. **Suggestions** — non-blocking improvements.');
|
|
503
|
+
lines.push('4. **Verdict** — one of: `LGTM`, `Approve with comments`, `Request changes`, `Block`.');
|
|
504
|
+
lines.push('');
|
|
505
|
+
lines.push('Cite code snippets in fenced code blocks. Do not output anything outside the Markdown report.');
|
|
506
|
+
|
|
507
|
+
const flowInstructions = args.flow.get('instructions') as string;
|
|
508
|
+
if (flowInstructions) {
|
|
509
|
+
lines.push('');
|
|
510
|
+
lines.push('---');
|
|
511
|
+
lines.push('Additional instructions from the review flow:');
|
|
512
|
+
lines.push(flowInstructions);
|
|
513
|
+
}
|
|
514
|
+
if (args.extraInstructions) {
|
|
515
|
+
lines.push('');
|
|
516
|
+
lines.push('---');
|
|
517
|
+
lines.push('Additional instructions for this run:');
|
|
518
|
+
lines.push(args.extraInstructions);
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
return lines.join('\n');
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* Pick the AI's final reply out of a LangChain-style message list.
|
|
526
|
+
*
|
|
527
|
+
* The previous implementation relied solely on `constructor.name`, which is
|
|
528
|
+
* unsafe under bundling/minification (class names can be mangled to single
|
|
529
|
+
* letters) and after JSON serialisation (instances become plain objects).
|
|
530
|
+
* The new logic checks several signals in order: LangChain's `_getType()`,
|
|
531
|
+
* an explicit `role` field, then the constructor name as a last resort.
|
|
532
|
+
*/
|
|
533
|
+
function extractLastAiMessageContent(result: any): string {
|
|
534
|
+
const messages = result?.messages;
|
|
535
|
+
if (!Array.isArray(messages)) return '';
|
|
536
|
+
|
|
537
|
+
const isAiMessage = (msg: any): boolean => {
|
|
538
|
+
if (!msg) return false;
|
|
539
|
+
if (typeof msg._getType === 'function') {
|
|
540
|
+
try {
|
|
541
|
+
return msg._getType() === 'ai';
|
|
542
|
+
} catch {
|
|
543
|
+
// fall through to other signals
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
if (typeof msg.role === 'string') {
|
|
547
|
+
const r = msg.role.toLowerCase();
|
|
548
|
+
return r === 'assistant' || r === 'ai';
|
|
549
|
+
}
|
|
550
|
+
if (typeof msg.type === 'string' && msg.type.toLowerCase() === 'ai') return true;
|
|
551
|
+
const name = msg?.constructor?.name;
|
|
552
|
+
if (name === 'AIMessage' || name === 'AIMessageChunk') return true;
|
|
553
|
+
return false;
|
|
554
|
+
};
|
|
555
|
+
|
|
556
|
+
const getContent = (msg: any): string => {
|
|
557
|
+
if (typeof msg.content === 'string') return msg.content;
|
|
558
|
+
if (Array.isArray(msg.content)) {
|
|
559
|
+
const textBlock = msg.content.find((c: any) => c?.type === 'text');
|
|
560
|
+
if (typeof textBlock?.text === 'string') return textBlock.text;
|
|
561
|
+
}
|
|
562
|
+
return '';
|
|
563
|
+
};
|
|
564
|
+
|
|
565
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
566
|
+
const msg = messages[i];
|
|
567
|
+
if (!isAiMessage(msg)) continue;
|
|
568
|
+
const content = getContent(msg);
|
|
569
|
+
if (content) return content;
|
|
570
|
+
}
|
|
571
|
+
return '';
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
async function fetchMrHeadSha(repo: any, mrIid: number): Promise<string | null> {
|
|
575
|
+
const repoUrl = repo.get('repoUrl') as string;
|
|
576
|
+
const pat = repo.get('pat') as string;
|
|
577
|
+
if (!pat) return null;
|
|
578
|
+
const isGitHub = repoUrl.includes('github.com');
|
|
579
|
+
|
|
580
|
+
try {
|
|
581
|
+
if (isGitHub) {
|
|
582
|
+
const { projectPath } = parseGitLabProject(repoUrl);
|
|
583
|
+
const response = await fetch(`https://api.github.com/repos/${projectPath}/pulls/${mrIid}`, {
|
|
584
|
+
headers: { 'Authorization': `Bearer ${pat}`, Accept: 'application/vnd.github.v3+json' },
|
|
585
|
+
});
|
|
586
|
+
if (!response.ok) return null;
|
|
587
|
+
const data = await response.json();
|
|
588
|
+
return data?.head?.sha || null;
|
|
589
|
+
} else {
|
|
590
|
+
const { apiBase, encodedProject } = parseGitLabProject(repoUrl);
|
|
591
|
+
const response = await fetch(`${apiBase}/projects/${encodedProject}/merge_requests/${mrIid}`, {
|
|
592
|
+
headers: { 'PRIVATE-TOKEN': pat, Accept: 'application/json' },
|
|
593
|
+
});
|
|
594
|
+
if (!response.ok) return null;
|
|
595
|
+
const data = await response.json();
|
|
596
|
+
return (data?.sha as string) || (data?.diff_refs?.head_sha as string) || null;
|
|
597
|
+
}
|
|
598
|
+
} catch {
|
|
599
|
+
return null;
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
async function postNoteToGitLab(repo: any, mrIid: number, body: string): Promise<number | string> {
|
|
604
|
+
const repoUrl = repo.get('repoUrl') as string;
|
|
605
|
+
const pat = repo.get('pat') as string;
|
|
606
|
+
const isGitHub = repoUrl.includes('github.com');
|
|
607
|
+
|
|
608
|
+
if (isGitHub) {
|
|
609
|
+
if (!pat) throw new Error('Repository has no PAT configured');
|
|
610
|
+
const { projectPath } = parseGitLabProject(repoUrl);
|
|
611
|
+
|
|
612
|
+
const response = await fetch(`https://api.github.com/repos/${projectPath}/issues/${mrIid}/comments`, {
|
|
613
|
+
method: 'POST',
|
|
614
|
+
headers: {
|
|
615
|
+
'Authorization': `Bearer ${pat}`,
|
|
616
|
+
'Content-Type': 'application/json',
|
|
617
|
+
'Accept': 'application/vnd.github.v3+json',
|
|
618
|
+
},
|
|
619
|
+
body: JSON.stringify({ body }),
|
|
620
|
+
});
|
|
621
|
+
|
|
622
|
+
if (!response.ok) {
|
|
623
|
+
const text = await response.text().catch(() => '');
|
|
624
|
+
throw new Error(`GitHub note post failed ${response.status}: ${text}`);
|
|
625
|
+
}
|
|
626
|
+
const data = await response.json();
|
|
627
|
+
return data?.id;
|
|
628
|
+
} else {
|
|
629
|
+
if (!pat) throw new Error('Repository has no PAT configured');
|
|
630
|
+
|
|
631
|
+
const { apiBase, encodedProject } = parseGitLabProject(repoUrl);
|
|
632
|
+
|
|
633
|
+
const response = await fetch(`${apiBase}/projects/${encodedProject}/merge_requests/${mrIid}/notes`, {
|
|
634
|
+
method: 'POST',
|
|
635
|
+
headers: {
|
|
636
|
+
'PRIVATE-TOKEN': pat,
|
|
637
|
+
'Content-Type': 'application/json',
|
|
638
|
+
'Accept': 'application/json',
|
|
639
|
+
},
|
|
640
|
+
body: JSON.stringify({ body }),
|
|
641
|
+
});
|
|
642
|
+
if (!response.ok) {
|
|
643
|
+
const text = await response.text().catch(() => '');
|
|
644
|
+
throw new Error(`GitLab note post failed ${response.status}: ${text}`);
|
|
645
|
+
}
|
|
646
|
+
const data = await response.json();
|
|
647
|
+
return data?.id;
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
/* ───────── Flow matching helpers ───────── */
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* H-1 fix: guard against ReDoS by limiting regex length and wrapping
|
|
655
|
+
* execution in a try-catch.
|
|
656
|
+
*
|
|
657
|
+
* Fail-closed: an invalid or oversized pattern means "no branch matches".
|
|
658
|
+
* Reviewing all branches when a user explicitly configured a filter is more
|
|
659
|
+
* dangerous (auto-posts to GitLab, consumes LLM credits) than skipping a
|
|
660
|
+
* malformed flow. The poller logs once per process so misconfiguration is
|
|
661
|
+
* still observable.
|
|
662
|
+
*/
|
|
663
|
+
const MAX_BRANCH_FILTER_LENGTH = 200;
|
|
664
|
+
const loggedBadFilters = new Set<string>();
|
|
665
|
+
|
|
666
|
+
function warnInvalidBranchFilter(filter: string, reason: string) {
|
|
667
|
+
if (loggedBadFilters.has(filter)) return;
|
|
668
|
+
loggedBadFilters.add(filter);
|
|
669
|
+
console.warn(
|
|
670
|
+
`[plugin-git-manager] branchFilter rejected (${reason}): ${JSON.stringify(filter)}. Flow will not match any branch.`,
|
|
671
|
+
);
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
export function branchMatches(flow: any, branch: string): boolean {
|
|
675
|
+
const filter = flow.get('branchFilter') as string | null;
|
|
676
|
+
if (!filter) return true;
|
|
677
|
+
if (filter.length > MAX_BRANCH_FILTER_LENGTH) {
|
|
678
|
+
warnInvalidBranchFilter(filter, `too long (>${MAX_BRANCH_FILTER_LENGTH} chars)`);
|
|
679
|
+
return false;
|
|
680
|
+
}
|
|
681
|
+
try {
|
|
682
|
+
return new RegExp(filter).test(branch);
|
|
683
|
+
} catch (err: any) {
|
|
684
|
+
warnInvalidBranchFilter(filter, `invalid regex: ${err?.message || err}`);
|
|
685
|
+
return false;
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
export function pickFlowMatchingBranch(flows: any[], branch?: string): any | null {
|
|
690
|
+
if (!flows?.length) return null;
|
|
691
|
+
if (!branch) return flows[0];
|
|
692
|
+
for (const f of flows) {
|
|
693
|
+
if (branchMatches(f, branch)) return f;
|
|
694
|
+
}
|
|
695
|
+
return null;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
function throwHttp(status: number, message: string): never {
|
|
699
|
+
const err: any = new Error(message);
|
|
700
|
+
err.status = status;
|
|
701
|
+
throw err;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
/**
|
|
705
|
+
* Reviews are launched via `setImmediate` and tracked entirely in process
|
|
706
|
+
* memory. When the app restarts mid-run, the in-memory promise dies but the
|
|
707
|
+
* DB record stays in `status='running'` indefinitely. On startup we sweep
|
|
708
|
+
* any `running` review whose `startedAt` is older than the in-process
|
|
709
|
+
* timeout (5 min) plus a safety margin and mark it as failed.
|
|
710
|
+
*
|
|
711
|
+
* The cutoff is intentionally larger than the runtime timeout so concurrent
|
|
712
|
+
* reviews running on a *different* node in an HA cluster aren't clobbered.
|
|
713
|
+
*/
|
|
714
|
+
const STUCK_REVIEW_CUTOFF_MS = 10 * 60 * 1000; // 10 minutes
|
|
715
|
+
|
|
716
|
+
export async function recoverStuckReviews(app: Application): Promise<number> {
|
|
717
|
+
try {
|
|
718
|
+
const reviewsRepo = app.db.getRepository('gitCodeReviews');
|
|
719
|
+
const cutoff = new Date(Date.now() - STUCK_REVIEW_CUTOFF_MS);
|
|
720
|
+
// Sweep both `running` (interrupted mid-execution) and `pending`
|
|
721
|
+
// (interrupted between record creation and runReview's first update).
|
|
722
|
+
// Both have `startedAt` stamped at trigger time so the cutoff applies
|
|
723
|
+
// consistently.
|
|
724
|
+
const stuck = await reviewsRepo.find({
|
|
725
|
+
filter: {
|
|
726
|
+
status: { $in: ['running', 'pending'] },
|
|
727
|
+
startedAt: { $lt: cutoff },
|
|
728
|
+
},
|
|
729
|
+
});
|
|
730
|
+
if (!stuck?.length) return 0;
|
|
731
|
+
const finishedAt = new Date();
|
|
732
|
+
for (const review of stuck) {
|
|
733
|
+
const startedAt = review.get('startedAt') as Date | null;
|
|
734
|
+
const durationMs = startedAt ? finishedAt.getTime() - new Date(startedAt).getTime() : null;
|
|
735
|
+
await reviewsRepo.update({
|
|
736
|
+
filterByTk: review.get('id'),
|
|
737
|
+
values: {
|
|
738
|
+
status: 'failed',
|
|
739
|
+
error: 'Review interrupted by application restart',
|
|
740
|
+
finishedAt,
|
|
741
|
+
durationMs,
|
|
742
|
+
},
|
|
743
|
+
});
|
|
744
|
+
}
|
|
745
|
+
app.log?.info?.(`plugin-git-manager: marked ${stuck.length} stuck review(s) as failed after restart`);
|
|
746
|
+
return stuck.length;
|
|
747
|
+
} catch (err: any) {
|
|
748
|
+
app.log?.error?.(`plugin-git-manager: recoverStuckReviews failed: ${err?.message}`);
|
|
749
|
+
return 0;
|
|
750
|
+
}
|
|
751
|
+
}
|