@duplojs/agents-kit 0.0.0-stage → 0.1.0-beta.3
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 +73 -2
- package/dist/bin/index.d.ts +2 -0
- package/dist/bin/index.mjs +7 -0
- package/dist/bin/install/index.d.ts +2 -0
- package/dist/bin/install/index.mjs +25 -0
- package/dist/bin/install/skill.d.ts +28 -0
- package/dist/bin/install/skill.mjs +58 -0
- package/dist/bin/packagePath.d.ts +2 -0
- package/dist/bin/packagePath.mjs +12 -0
- package/dist/bin/setup/index.d.ts +12 -0
- package/dist/bin/setup/index.mjs +33 -0
- package/dist/bin/setup/instructions.d.ts +8 -0
- package/dist/bin/setup/instructions.mjs +27 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +0 -0
- package/docs/API/10-lang/10-array/10-at.ts +65 -0
- package/docs/API/10-lang/10-array/10-chunk.ts +42 -0
- package/docs/API/10-lang/10-array/10-coalescing.ts +19 -0
- package/docs/API/10-lang/10-array/10-concat.ts +34 -0
- package/docs/API/10-lang/10-array/10-copyWithin.ts +34 -0
- package/docs/API/10-lang/10-array/10-every.ts +25 -0
- package/docs/API/10-lang/10-array/10-fill.ts +34 -0
- package/docs/API/10-lang/10-array/10-fillAll.ts +34 -0
- package/docs/API/10-lang/10-array/10-filter.ts +43 -0
- package/docs/API/10-lang/10-array/10-find.ts +33 -0
- package/docs/API/10-lang/10-array/10-findAndReplace.ts +35 -0
- package/docs/API/10-lang/10-array/10-findAndSpliceDelete.ts +35 -0
- package/docs/API/10-lang/10-array/10-findAndSpliceInsert.ts +35 -0
- package/docs/API/10-lang/10-array/10-findAndSpliceReplace.ts +24 -0
- package/docs/API/10-lang/10-array/10-findDuplicates.ts +19 -0
- package/docs/API/10-lang/10-array/10-findIndex.ts +25 -0
- package/docs/API/10-lang/10-array/10-findLast.ts +33 -0
- package/docs/API/10-lang/10-array/10-findLastIndex.ts +25 -0
- package/docs/API/10-lang/10-array/10-first.ts +21 -0
- package/docs/API/10-lang/10-array/10-flat.ts +22 -0
- package/docs/API/10-lang/10-array/10-flatMap.ts +24 -0
- package/docs/API/10-lang/10-array/10-from.ts +25 -0
- package/docs/API/10-lang/10-array/10-group.ts +27 -0
- package/docs/API/10-lang/10-array/10-groupOutput.ts +30 -0
- package/docs/API/10-lang/10-array/10-includes.ts +24 -0
- package/docs/API/10-lang/10-array/10-indexOf.ts +24 -0
- package/docs/API/10-lang/10-array/10-insert.ts +34 -0
- package/docs/API/10-lang/10-array/10-is.ts +15 -0
- package/docs/API/10-lang/10-array/10-isLastIndex.ts +24 -0
- package/docs/API/10-lang/10-array/10-last.ts +21 -0
- package/docs/API/10-lang/10-array/10-lastIndexOf.ts +24 -0
- package/docs/API/10-lang/10-array/10-length.ts +28 -0
- package/docs/API/10-lang/10-array/10-lengthEqual.ts +39 -0
- package/docs/API/10-lang/10-array/10-map.ts +34 -0
- package/docs/API/10-lang/10-array/10-maxElements.ts +44 -0
- package/docs/API/10-lang/10-array/10-minElements.ts +44 -0
- package/docs/API/10-lang/10-array/10-notIncludes.ts +24 -0
- package/docs/API/10-lang/10-array/10-pop.ts +23 -0
- package/docs/API/10-lang/10-array/10-prepend.ts +34 -0
- package/docs/API/10-lang/10-array/10-push.ts +34 -0
- package/docs/API/10-lang/10-array/10-reduce.ts +28 -0
- package/docs/API/10-lang/10-array/10-reduceFrom.ts +16 -0
- package/docs/API/10-lang/10-array/10-reduceRight.ts +28 -0
- package/docs/API/10-lang/10-array/10-reverse.ts +25 -0
- package/docs/API/10-lang/10-array/10-select.ts +26 -0
- package/docs/API/10-lang/10-array/10-set.ts +24 -0
- package/docs/API/10-lang/10-array/10-shift.ts +23 -0
- package/docs/API/10-lang/10-array/10-slice.ts +24 -0
- package/docs/API/10-lang/10-array/10-some.ts +25 -0
- package/docs/API/10-lang/10-array/10-sort.ts +34 -0
- package/docs/API/10-lang/10-array/10-spliceDelete.ts +34 -0
- package/docs/API/10-lang/10-array/10-spliceInsert.ts +34 -0
- package/docs/API/10-lang/10-array/10-spliceReplace.ts +24 -0
- package/docs/API/10-lang/10-array/10-unshift.ts +34 -0
- package/docs/API/10-lang/10-array/index.llms.md +220 -0
- package/docs/API/10-lang/10-array/index.md +3 -0
- package/docs/API/10-lang/10-chrono/10-addDays.ts +25 -0
- package/docs/API/10-lang/10-chrono/10-addHours.ts +25 -0
- package/docs/API/10-lang/10-chrono/10-addMilliseconds.ts +25 -0
- package/docs/API/10-lang/10-chrono/10-addMinutes.ts +25 -0
- package/docs/API/10-lang/10-chrono/10-addMonths.ts +25 -0
- package/docs/API/10-lang/10-chrono/10-addSeconds.ts +25 -0
- package/docs/API/10-lang/10-chrono/10-addTime.ts +38 -0
- package/docs/API/10-lang/10-chrono/10-addWeeks.ts +25 -0
- package/docs/API/10-lang/10-chrono/10-addYears.ts +25 -0
- package/docs/API/10-lang/10-chrono/10-applyTimezone.ts +29 -0
- package/docs/API/10-lang/10-chrono/10-betweenThanDate.ts +27 -0
- package/docs/API/10-lang/10-chrono/10-betweenThanOrEqualDate.ts +27 -0
- package/docs/API/10-lang/10-chrono/10-betweenThanOrEqualTime.ts +27 -0
- package/docs/API/10-lang/10-chrono/10-betweenThanTime.ts +27 -0
- package/docs/API/10-lang/10-chrono/10-closestTo.ts +48 -0
- package/docs/API/10-lang/10-chrono/10-computeTime.ts +35 -0
- package/docs/API/10-lang/10-chrono/10-createDate.ts +122 -0
- package/docs/API/10-lang/10-chrono/10-createDateOrThrow.ts +39 -0
- package/docs/API/10-lang/10-chrono/10-createTime.ts +86 -0
- package/docs/API/10-lang/10-chrono/10-createTimeOrThrow.ts +28 -0
- package/docs/API/10-lang/10-chrono/10-eachDate.ts +67 -0
- package/docs/API/10-lang/10-chrono/10-equalDate.ts +26 -0
- package/docs/API/10-lang/10-chrono/10-equalTime.ts +26 -0
- package/docs/API/10-lang/10-chrono/10-formatDate.ts +43 -0
- package/docs/API/10-lang/10-chrono/10-formatTime.ts +37 -0
- package/docs/API/10-lang/10-chrono/10-getDayOfMonth.ts +37 -0
- package/docs/API/10-lang/10-chrono/10-getDayOfWeek.ts +30 -0
- package/docs/API/10-lang/10-chrono/10-getDayOfYear.ts +28 -0
- package/docs/API/10-lang/10-chrono/10-getDifference.ts +29 -0
- package/docs/API/10-lang/10-chrono/10-getFirstDayOfMonth.ts +24 -0
- package/docs/API/10-lang/10-chrono/10-getFirstDayOfWeek.ts +24 -0
- package/docs/API/10-lang/10-chrono/10-getHour.ts +28 -0
- package/docs/API/10-lang/10-chrono/10-getLastDayOfMonth.ts +24 -0
- package/docs/API/10-lang/10-chrono/10-getLastDayOfWeek.ts +24 -0
- package/docs/API/10-lang/10-chrono/10-getMilliseconds.ts +24 -0
- package/docs/API/10-lang/10-chrono/10-getMinute.ts +27 -0
- package/docs/API/10-lang/10-chrono/10-getMonth.ts +27 -0
- package/docs/API/10-lang/10-chrono/10-getSecond.ts +27 -0
- package/docs/API/10-lang/10-chrono/10-getTimezoneOffset.ts +28 -0
- package/docs/API/10-lang/10-chrono/10-getWeekOfYear.ts +27 -0
- package/docs/API/10-lang/10-chrono/10-getYear.ts +27 -0
- package/docs/API/10-lang/10-chrono/10-greaterThanDate.ts +26 -0
- package/docs/API/10-lang/10-chrono/10-greaterThanOrEqualDate.ts +26 -0
- package/docs/API/10-lang/10-chrono/10-greaterThanOrEqualTime.ts +26 -0
- package/docs/API/10-lang/10-chrono/10-greaterThanTime.ts +26 -0
- package/docs/API/10-lang/10-chrono/10-isDate.ts +23 -0
- package/docs/API/10-lang/10-chrono/10-isSafeTimeValue.ts +19 -0
- package/docs/API/10-lang/10-chrono/10-isSafeTimestamp.ts +19 -0
- package/docs/API/10-lang/10-chrono/10-isSerializedTheDate.ts +26 -0
- package/docs/API/10-lang/10-chrono/10-isSerializedTheTime.ts +26 -0
- package/docs/API/10-lang/10-chrono/10-isTime.ts +23 -0
- package/docs/API/10-lang/10-chrono/10-lessThanDate.ts +26 -0
- package/docs/API/10-lang/10-chrono/10-lessThanOrEqualDate.ts +26 -0
- package/docs/API/10-lang/10-chrono/10-lessThanOrEqualTime.ts +26 -0
- package/docs/API/10-lang/10-chrono/10-lessThanTime.ts +26 -0
- package/docs/API/10-lang/10-chrono/10-makeSafeTimeValue.ts +19 -0
- package/docs/API/10-lang/10-chrono/10-makeSafeTimestamp.ts +19 -0
- package/docs/API/10-lang/10-chrono/10-maxDate.ts +23 -0
- package/docs/API/10-lang/10-chrono/10-maxTime.ts +23 -0
- package/docs/API/10-lang/10-chrono/10-minDate.ts +23 -0
- package/docs/API/10-lang/10-chrono/10-minTime.ts +23 -0
- package/docs/API/10-lang/10-chrono/10-now.ts +13 -0
- package/docs/API/10-lang/10-chrono/10-round.ts +41 -0
- package/docs/API/10-lang/10-chrono/10-serialize.ts +23 -0
- package/docs/API/10-lang/10-chrono/10-sortDates.ts +32 -0
- package/docs/API/10-lang/10-chrono/10-sortTimes.ts +31 -0
- package/docs/API/10-lang/10-chrono/10-subtractDays.ts +25 -0
- package/docs/API/10-lang/10-chrono/10-subtractHours.ts +25 -0
- package/docs/API/10-lang/10-chrono/10-subtractMilliseconds.ts +25 -0
- package/docs/API/10-lang/10-chrono/10-subtractMinutes.ts +25 -0
- package/docs/API/10-lang/10-chrono/10-subtractMonths.ts +25 -0
- package/docs/API/10-lang/10-chrono/10-subtractSeconds.ts +25 -0
- package/docs/API/10-lang/10-chrono/10-subtractTime.ts +38 -0
- package/docs/API/10-lang/10-chrono/10-subtractWeeks.ts +25 -0
- package/docs/API/10-lang/10-chrono/10-subtractYears.ts +25 -0
- package/docs/API/10-lang/10-chrono/10-toDateISOString.ts +17 -0
- package/docs/API/10-lang/10-chrono/10-toNative.ts +25 -0
- package/docs/API/10-lang/10-chrono/10-toTimeValue.ts +17 -0
- package/docs/API/10-lang/10-chrono/10-toTimestamp.ts +17 -0
- package/docs/API/10-lang/10-chrono/10-today.ts +13 -0
- package/docs/API/10-lang/10-chrono/10-tomorrow.ts +13 -0
- package/docs/API/10-lang/10-chrono/10-yesterday.ts +13 -0
- package/docs/API/10-lang/10-chrono/index.llms.md +332 -0
- package/docs/API/10-lang/10-chrono/index.md +3 -0
- package/docs/API/10-lang/10-common/10-and.ts +45 -0
- package/docs/API/10-lang/10-common/10-asserts.ts +13 -0
- package/docs/API/10-lang/10-common/10-asyncInnerPipe.ts +23 -0
- package/docs/API/10-lang/10-common/10-asyncLoop.ts +25 -0
- package/docs/API/10-lang/10-common/10-asyncPipe.ts +21 -0
- package/docs/API/10-lang/10-common/10-callThen.ts +22 -0
- package/docs/API/10-lang/10-common/10-cast.ts +16 -0
- package/docs/API/10-lang/10-common/10-clone.ts +12 -0
- package/docs/API/10-lang/10-common/10-createAsyncRetry.ts +34 -0
- package/docs/API/10-lang/10-common/10-createBuilder.ts +19 -0
- package/docs/API/10-lang/10-common/10-createEnum.ts +25 -0
- package/docs/API/10-lang/10-common/10-createExternalPromise.ts +13 -0
- package/docs/API/10-lang/10-common/10-createFormData.ts +16 -0
- package/docs/API/10-lang/10-common/10-createInterpolation.ts +12 -0
- package/docs/API/10-lang/10-common/10-createQueue.ts +16 -0
- package/docs/API/10-lang/10-common/10-createTransformer.ts +16 -0
- package/docs/API/10-lang/10-common/10-detachObjectMethod.ts +20 -0
- package/docs/API/10-lang/10-common/10-equal.ts +31 -0
- package/docs/API/10-lang/10-common/10-escapeRegExp.ts +11 -0
- package/docs/API/10-lang/10-common/10-falsy.ts +12 -0
- package/docs/API/10-lang/10-common/10-forward.ts +11 -0
- package/docs/API/10-lang/10-common/10-forwardAsserts.ts +17 -0
- package/docs/API/10-lang/10-common/10-forwardLog.ts +11 -0
- package/docs/API/10-lang/10-common/10-infer.ts +16 -0
- package/docs/API/10-lang/10-common/10-innerPipe.ts +23 -0
- package/docs/API/10-lang/10-common/10-instanceOf.ts +23 -0
- package/docs/API/10-lang/10-common/10-isType.ts +29 -0
- package/docs/API/10-lang/10-common/10-justExec.ts +28 -0
- package/docs/API/10-lang/10-common/10-justReturn.ts +19 -0
- package/docs/API/10-lang/10-common/10-loop.ts +20 -0
- package/docs/API/10-lang/10-common/10-memo.ts +12 -0
- package/docs/API/10-lang/10-common/10-memoObject.ts +11 -0
- package/docs/API/10-lang/10-common/10-memoPromise.ts +16 -0
- package/docs/API/10-lang/10-common/10-or.ts +29 -0
- package/docs/API/10-lang/10-common/10-pipe.ts +21 -0
- package/docs/API/10-lang/10-common/10-pipeCall.ts +20 -0
- package/docs/API/10-lang/10-common/10-prepareAsyncPipe.ts +20 -0
- package/docs/API/10-lang/10-common/10-preparePipe.ts +20 -0
- package/docs/API/10-lang/10-common/10-promiseAll.ts +16 -0
- package/docs/API/10-lang/10-common/10-promiseObject.ts +22 -0
- package/docs/API/10-lang/10-common/10-removeConstraint.ts +13 -0
- package/docs/API/10-lang/10-common/10-shameOnYou.ts +20 -0
- package/docs/API/10-lang/10-common/10-simpleClone.ts +12 -0
- package/docs/API/10-lang/10-common/10-stringToBytes.ts +16 -0
- package/docs/API/10-lang/10-common/10-stringToMillisecond.ts +17 -0
- package/docs/API/10-lang/10-common/10-timeout.ts +11 -0
- package/docs/API/10-lang/10-common/10-toCurriedPredicate.ts +28 -0
- package/docs/API/10-lang/10-common/10-toJSON.ts +15 -0
- package/docs/API/10-lang/10-common/10-toNative.ts +15 -0
- package/docs/API/10-lang/10-common/10-toRegExp.ts +17 -0
- package/docs/API/10-lang/10-common/10-transformer.ts +21 -0
- package/docs/API/10-lang/10-common/10-truthy.ts +12 -0
- package/docs/API/10-lang/10-common/10-useAsyncRetry.ts +31 -0
- package/docs/API/10-lang/10-common/10-when.ts +27 -0
- package/docs/API/10-lang/10-common/10-whenElse.ts +28 -0
- package/docs/API/10-lang/10-common/10-whenNot.ts +26 -0
- package/docs/API/10-lang/10-common/index.llms.md +228 -0
- package/docs/API/10-lang/10-common/index.md +3 -0
- package/docs/API/10-lang/10-dataStructure/10-absolutePath.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-allowedCharacters.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-array.ts +23 -0
- package/docs/API/10-lang/10-dataStructure/10-arrayLengthEqual.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-betweenThan.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-betweenThanOrEqual.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-bigint.ts +22 -0
- package/docs/API/10-lang/10-dataStructure/10-boolean.ts +22 -0
- package/docs/API/10-lang/10-dataStructure/10-createCodec.ts +45 -0
- package/docs/API/10-lang/10-dataStructure/10-createCodecs.ts +134 -0
- package/docs/API/10-lang/10-dataStructure/10-createErrorInterpreter.ts +74 -0
- package/docs/API/10-lang/10-dataStructure/10-date.ts +23 -0
- package/docs/API/10-lang/10-dataStructure/10-email.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-endsWith.ts +24 -0
- package/docs/API/10-lang/10-dataStructure/10-even.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-extend.ts +27 -0
- package/docs/API/10-lang/10-dataStructure/10-greaterThan.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-greaterThanOrEqual.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-include.ts +24 -0
- package/docs/API/10-lang/10-dataStructure/10-integer.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-isNullStructure.ts +12 -0
- package/docs/API/10-lang/10-dataStructure/10-isNullable.ts +12 -0
- package/docs/API/10-lang/10-dataStructure/10-isOptional.ts +12 -0
- package/docs/API/10-lang/10-dataStructure/10-isUndefinedStructure.ts +12 -0
- package/docs/API/10-lang/10-dataStructure/10-lazy.ts +23 -0
- package/docs/API/10-lang/10-dataStructure/10-lessThan.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-lessThanOrEqual.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-literal.ts +19 -0
- package/docs/API/10-lang/10-dataStructure/10-maxCharacters.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-maxElements.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-minCharacters.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-minElements.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-multipleOf.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-negative.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-notEmpty.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-notZero.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-null.ts +22 -0
- package/docs/API/10-lang/10-dataStructure/10-nullable.ts +19 -0
- package/docs/API/10-lang/10-dataStructure/10-number.ts +22 -0
- package/docs/API/10-lang/10-dataStructure/10-numberInString.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-object.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-odd.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-optional.ts +19 -0
- package/docs/API/10-lang/10-dataStructure/10-partial.ts +23 -0
- package/docs/API/10-lang/10-dataStructure/10-path.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-positive.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-record.ts +22 -0
- package/docs/API/10-lang/10-dataStructure/10-refine.ts +27 -0
- package/docs/API/10-lang/10-dataStructure/10-regex.ts +24 -0
- package/docs/API/10-lang/10-dataStructure/10-required.ts +21 -0
- package/docs/API/10-lang/10-dataStructure/10-safe.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-segmentPath.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-startsWith.ts +24 -0
- package/docs/API/10-lang/10-dataStructure/10-strictNegative.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-strictPositive.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-string.ts +22 -0
- package/docs/API/10-lang/10-dataStructure/10-stringLengthEqual.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-time.ts +23 -0
- package/docs/API/10-lang/10-dataStructure/10-trimmed.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-typeStructureIdentifier.ts +33 -0
- package/docs/API/10-lang/10-dataStructure/10-undefined.ts +22 -0
- package/docs/API/10-lang/10-dataStructure/10-union.ts +24 -0
- package/docs/API/10-lang/10-dataStructure/10-unwrapLazy.ts +17 -0
- package/docs/API/10-lang/10-dataStructure/10-url.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/10-uuid.ts +25 -0
- package/docs/API/10-lang/10-dataStructure/index.llms.md +264 -0
- package/docs/API/10-lang/10-dataStructure/index.md +3 -0
- package/docs/API/10-lang/10-either/10-asyncGroup.ts +44 -0
- package/docs/API/10-lang/10-either/10-asyncSafeCallback.ts +23 -0
- package/docs/API/10-lang/10-either/10-error.ts +12 -0
- package/docs/API/10-lang/10-either/10-expect.ts +13 -0
- package/docs/API/10-lang/10-either/10-fail.ts +12 -0
- package/docs/API/10-lang/10-either/10-forwardAssertsSelection.ts +28 -0
- package/docs/API/10-lang/10-either/10-group.ts +58 -0
- package/docs/API/10-lang/10-either/10-hasInformation.ts +24 -0
- package/docs/API/10-lang/10-either/10-isLeft.ts +16 -0
- package/docs/API/10-lang/10-either/10-isRight.ts +16 -0
- package/docs/API/10-lang/10-either/10-isSelected.ts +29 -0
- package/docs/API/10-lang/10-either/10-keepAsRightByInformation.ts +29 -0
- package/docs/API/10-lang/10-either/10-keepAsRightSelection.ts +23 -0
- package/docs/API/10-lang/10-either/10-left.ts +13 -0
- package/docs/API/10-lang/10-either/10-matchInformation.ts +26 -0
- package/docs/API/10-lang/10-either/10-matchInformationOtherwise.ts +27 -0
- package/docs/API/10-lang/10-either/10-none.ts +12 -0
- package/docs/API/10-lang/10-either/10-ok.ts +12 -0
- package/docs/API/10-lang/10-either/10-result.ts +18 -0
- package/docs/API/10-lang/10-either/10-rewriteInformation.ts +24 -0
- package/docs/API/10-lang/10-either/10-right.ts +13 -0
- package/docs/API/10-lang/10-either/10-rightAsyncPipe.ts +69 -0
- package/docs/API/10-lang/10-either/10-rightPipe.ts +72 -0
- package/docs/API/10-lang/10-either/10-safeCallback.ts +29 -0
- package/docs/API/10-lang/10-either/10-some.ts +12 -0
- package/docs/API/10-lang/10-either/10-success.ts +12 -0
- package/docs/API/10-lang/10-either/10-toMaybe.ts +53 -0
- package/docs/API/10-lang/10-either/10-unwrapByInformation.ts +20 -0
- package/docs/API/10-lang/10-either/10-unwrapByInformationOrThrow.ts +19 -0
- package/docs/API/10-lang/10-either/10-unwrapLeft.ts +14 -0
- package/docs/API/10-lang/10-either/10-unwrapLeftOrThrow.ts +17 -0
- package/docs/API/10-lang/10-either/10-unwrapOr.ts +17 -0
- package/docs/API/10-lang/10-either/10-unwrapOtherwise.ts +20 -0
- package/docs/API/10-lang/10-either/10-unwrapRight.ts +14 -0
- package/docs/API/10-lang/10-either/10-unwrapRightOrThrow.ts +17 -0
- package/docs/API/10-lang/10-either/10-unwrapSelection.ts +26 -0
- package/docs/API/10-lang/10-either/10-unwrapSelectionOrThrow.ts +19 -0
- package/docs/API/10-lang/10-either/10-whenHasInformation.ts +35 -0
- package/docs/API/10-lang/10-either/10-whenHasInformationOtherwise.ts +29 -0
- package/docs/API/10-lang/10-either/10-whenIsLeft.ts +20 -0
- package/docs/API/10-lang/10-either/10-whenIsLeftOtherwise.ts +27 -0
- package/docs/API/10-lang/10-either/10-whenIsRight.ts +20 -0
- package/docs/API/10-lang/10-either/10-whenIsRightOtherwise.ts +26 -0
- package/docs/API/10-lang/10-either/10-whenIsSelected.ts +33 -0
- package/docs/API/10-lang/10-either/10-whenIsSelectedOtherwise.ts +35 -0
- package/docs/API/10-lang/10-either/index.llms.md +184 -0
- package/docs/API/10-lang/10-either/index.md +3 -0
- package/docs/API/10-lang/10-generator/10-asyncChunk.ts +55 -0
- package/docs/API/10-lang/10-generator/10-asyncConcat.ts +46 -0
- package/docs/API/10-lang/10-generator/10-asyncFilter.ts +41 -0
- package/docs/API/10-lang/10-generator/10-asyncFlat.ts +37 -0
- package/docs/API/10-lang/10-generator/10-asyncGroup.ts +65 -0
- package/docs/API/10-lang/10-generator/10-asyncLoop.ts +59 -0
- package/docs/API/10-lang/10-generator/10-asyncMap.ts +48 -0
- package/docs/API/10-lang/10-generator/10-asyncReduce.ts +63 -0
- package/docs/API/10-lang/10-generator/10-chunk.ts +44 -0
- package/docs/API/10-lang/10-generator/10-concat.ts +37 -0
- package/docs/API/10-lang/10-generator/10-createExternalAsyncGenerator.ts +29 -0
- package/docs/API/10-lang/10-generator/10-execute.ts +44 -0
- package/docs/API/10-lang/10-generator/10-filter.ts +35 -0
- package/docs/API/10-lang/10-generator/10-flat.ts +25 -0
- package/docs/API/10-lang/10-generator/10-group.ts +44 -0
- package/docs/API/10-lang/10-generator/10-groupOutput.ts +48 -0
- package/docs/API/10-lang/10-generator/10-loop.ts +55 -0
- package/docs/API/10-lang/10-generator/10-map.ts +35 -0
- package/docs/API/10-lang/10-generator/10-reduce.ts +51 -0
- package/docs/API/10-lang/10-generator/10-reduceFrom.ts +30 -0
- package/docs/API/10-lang/10-generator/index.llms.md +84 -0
- package/docs/API/10-lang/10-generator/index.md +3 -0
- package/docs/API/10-lang/index.md +3 -0
- package/docs/API/index.md +3 -0
- package/docs/API.llms.md +31 -0
- package/docs/concepts/01-fundamental/01-constraint/01-use.ts +22 -0
- package/docs/concepts/01-fundamental/01-constraint/10-built-in-constraint.ts +37 -0
- package/docs/concepts/01-fundamental/01-constraint/20-manipulation.ts +38 -0
- package/docs/concepts/01-fundamental/01-constraint/30-cast.ts +62 -0
- package/docs/concepts/01-fundamental/01-constraint/40-custom-constraint.ts +45 -0
- package/docs/concepts/01-fundamental/01-constraint/index.md +3 -0
- package/docs/concepts/01-fundamental/02-currying/01-use.ts +33 -0
- package/docs/concepts/01-fundamental/02-currying/10-built-in-function.ts +178 -0
- package/docs/concepts/01-fundamental/02-currying/20-inner-pipe.ts +39 -0
- package/docs/concepts/01-fundamental/02-currying/30-async-pipe.ts +42 -0
- package/docs/concepts/01-fundamental/02-currying/index.md +3 -0
- package/docs/concepts/01-fundamental/03-either/01-use.ts +21 -0
- package/docs/concepts/01-fundamental/03-either/10-discrimination.ts +79 -0
- package/docs/concepts/01-fundamental/03-either/20-exhaustive-handling.ts +73 -0
- package/docs/concepts/01-fundamental/03-either/30-composition.ts +72 -0
- package/docs/concepts/01-fundamental/03-either/40-result-adaptation.ts +40 -0
- package/docs/concepts/01-fundamental/03-either/50-external-results.ts +59 -0
- package/docs/concepts/01-fundamental/03-either/60-contextual-state.ts +40 -0
- package/docs/concepts/01-fundamental/03-either/index.md +3 -0
- package/docs/concepts/01-fundamental/04-data-structure/01-use.ts +22 -0
- package/docs/concepts/01-fundamental/04-data-structure/10-structure.ts +193 -0
- package/docs/concepts/01-fundamental/04-data-structure/20-constraint.ts +78 -0
- package/docs/concepts/01-fundamental/04-data-structure/30-validation.ts +100 -0
- package/docs/concepts/01-fundamental/04-data-structure/40-codecs.ts +151 -0
- package/docs/concepts/01-fundamental/04-data-structure/50-recursive.ts +48 -0
- package/docs/concepts/01-fundamental/04-data-structure/60-interpret-error.ts +123 -0
- package/docs/concepts/01-fundamental/04-data-structure/index.md +3 -0
- package/docs/concepts/01-fundamental/05-chrono/01-use.ts +14 -0
- package/docs/concepts/01-fundamental/05-chrono/10-creation.ts +59 -0
- package/docs/concepts/01-fundamental/05-chrono/20-manipulation.ts +94 -0
- package/docs/concepts/01-fundamental/05-chrono/30-serialized.ts +73 -0
- package/docs/concepts/01-fundamental/05-chrono/40-timezone.ts +81 -0
- package/docs/concepts/01-fundamental/05-chrono/index.md +3 -0
- package/docs/concepts/01-fundamental/06-modeling/10-new-type.ts +42 -0
- package/docs/concepts/01-fundamental/06-modeling/20-entity.ts +204 -0
- package/docs/concepts/01-fundamental/06-modeling/30-tagged-object.ts +181 -0
- package/docs/concepts/01-fundamental/06-modeling/40-entity-lifecycle.ts +275 -0
- package/docs/concepts/01-fundamental/06-modeling/50-evidence.ts +94 -0
- package/docs/concepts/01-fundamental/06-modeling/60-signed-function.ts +26 -0
- package/docs/concepts/01-fundamental/06-modeling/index.md +3 -0
- package/docs/concepts/01-fundamental/07-discrimination/10-entity.ts +104 -0
- package/docs/concepts/01-fundamental/07-discrimination/20-fact.ts +142 -0
- package/docs/concepts/01-fundamental/07-discrimination/30-tagged-object.ts +105 -0
- package/docs/concepts/01-fundamental/07-discrimination/40-error.ts +57 -0
- package/docs/concepts/01-fundamental/07-discrimination/50-literal.ts +87 -0
- package/docs/concepts/01-fundamental/07-discrimination/60-shape.ts +152 -0
- package/docs/concepts/01-fundamental/07-discrimination/70-predicate.ts +89 -0
- package/docs/concepts/01-fundamental/07-discrimination/index.md +3 -0
- package/docs/concepts/01-fundamental/index.md +1 -0
- package/docs/concepts/02-server/10-file/10-manipulation.ts +40 -0
- package/docs/concepts/02-server/10-file/20-path.ts +56 -0
- package/docs/concepts/02-server/10-file/index.md +3 -0
- package/docs/concepts/02-server/20-http/10-init.ts +31 -0
- package/docs/concepts/02-server/20-http/20-route.ts +174 -0
- package/docs/concepts/02-server/20-http/30-routine.ts +195 -0
- package/docs/concepts/02-server/20-http/40-jwt.ts +137 -0
- package/docs/concepts/02-server/20-http/50-codegen.ts +29 -0
- package/docs/concepts/02-server/20-http/index.md +3 -0
- package/docs/concepts/02-server/30-environment/10-platform.ts +38 -0
- package/docs/concepts/02-server/30-environment/20-variable.ts +41 -0
- package/docs/concepts/02-server/30-environment/index.md +3 -0
- package/docs/concepts/02-server/40-command/10-use.ts +112 -0
- package/docs/concepts/02-server/40-command/20-sub-command.ts +48 -0
- package/docs/concepts/02-server/40-command/index.md +3 -0
- package/docs/concepts/02-server/index.md +1 -0
- package/docs/concepts/03-client/10-http/10-init.ts +64 -0
- package/docs/concepts/03-client/10-http/20-request.ts +244 -0
- package/docs/concepts/03-client/10-http/30-hook.ts +139 -0
- package/docs/concepts/03-client/10-http/index.md +3 -0
- package/docs/concepts/03-client/20-form/10-init.ts +95 -0
- package/docs/concepts/03-client/20-form/20-input.ts +96 -0
- package/docs/concepts/03-client/20-form/30-layout.ts +160 -0
- package/docs/concepts/03-client/20-form/40-template.ts +89 -0
- package/docs/concepts/03-client/20-form/index.md +3 -0
- package/docs/concepts/03-client/index.md +1 -0
- package/docs/concepts/04-tests/01-unit/10-either.ts +136 -0
- package/docs/concepts/04-tests/01-unit/20-server-mocking.ts +53 -0
- package/docs/concepts/04-tests/01-unit/index.md +3 -0
- package/docs/concepts/04-tests/02-e2e/10-init.ts +80 -0
- package/docs/concepts/04-tests/02-e2e/20-architecture.ts +76 -0
- package/docs/concepts/04-tests/02-e2e/30-testing.ts +90 -0
- package/docs/concepts/04-tests/02-e2e/index.md +3 -0
- package/docs/concepts/04-tests/index.md +1 -0
- package/docs/concepts/05-type-driven-design/01-architecture/10-boundaries.md +41 -0
- package/docs/concepts/05-type-driven-design/01-architecture/index.md +3 -0
- package/docs/concepts/05-type-driven-design/02-domains/10-entities.md +58 -0
- package/docs/concepts/05-type-driven-design/02-domains/20-aggregates.md +49 -0
- package/docs/concepts/05-type-driven-design/02-domains/30-repositories.md +41 -0
- package/docs/concepts/05-type-driven-design/02-domains/index.md +3 -0
- package/docs/concepts/05-type-driven-design/03-applications/10-use-case.md +69 -0
- package/docs/concepts/05-type-driven-design/03-applications/index.md +3 -0
- package/docs/concepts/05-type-driven-design/04-infrastructure/10-implementation.md +56 -0
- package/docs/concepts/05-type-driven-design/04-infrastructure/index.md +3 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/applications/index.ts +2 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/applications/ports/book.ts +10 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/applications/ports/client.ts +10 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/applications/ports/email.ts +7 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/applications/ports/index.ts +3 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/applications/useCases/clientGiveBackBook.ts +27 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/applications/useCases/clientRentBook.ts +30 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/applications/useCases/createBook.ts +32 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/applications/useCases/index.ts +2 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/domains/aggregates/clientGiveBackBook.ts +15 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/domains/aggregates/clientRentBook.ts +16 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/domains/aggregates/createBook.ts +21 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/domains/aggregates/index.ts +3 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/domains/entities/book/facts/create.ts +34 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/domains/entities/book/facts/index.ts +3 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/domains/entities/book/facts/rental.ts +31 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/domains/entities/book/facts/returnBook.ts +30 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/domains/entities/book/index.ts +87 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/domains/entities/client/facts/giveBackBook.ts +33 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/domains/entities/client/facts/index.ts +2 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/domains/entities/client/facts/rentBook.ts +32 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/domains/entities/client/index.ts +82 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/domains/entities/index.ts +2 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/domains/index.ts +3 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/domains/repositories/book.ts +16 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/domains/repositories/client.ts +7 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/domains/repositories/email.ts +12 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/domains/repositories/index.ts +3 -0
- package/docs/concepts/05-type-driven-design/fixtures/business/index.ts +2 -0
- package/docs/concepts/05-type-driven-design/fixtures/infrastructure/command/clientRentBook.ts +62 -0
- package/docs/concepts/05-type-driven-design/fixtures/infrastructure/command/index.ts +11 -0
- package/docs/concepts/05-type-driven-design/fixtures/infrastructure/http/checkers/bookExist.ts +19 -0
- package/docs/concepts/05-type-driven-design/fixtures/infrastructure/http/checkers/clientExist.ts +19 -0
- package/docs/concepts/05-type-driven-design/fixtures/infrastructure/http/checkers/index.ts +2 -0
- package/docs/concepts/05-type-driven-design/fixtures/infrastructure/http/main.ts +19 -0
- package/docs/concepts/05-type-driven-design/fixtures/infrastructure/http/routes/clientGiveBackBook.ts +37 -0
- package/docs/concepts/05-type-driven-design/fixtures/infrastructure/http/routes/clientRentBook.ts +50 -0
- package/docs/concepts/05-type-driven-design/fixtures/infrastructure/http/routes/index.ts +2 -0
- package/docs/concepts/05-type-driven-design/fixtures/infrastructure/ports/book.ts +25 -0
- package/docs/concepts/05-type-driven-design/fixtures/infrastructure/ports/client.ts +7 -0
- package/docs/concepts/05-type-driven-design/fixtures/infrastructure/ports/email.ts +10 -0
- package/docs/concepts/05-type-driven-design/fixtures/infrastructure/ports/index.ts +3 -0
- package/docs/concepts/05-type-driven-design/fixtures/infrastructure/useCases/index.ts +12 -0
- package/docs/concepts/05-type-driven-design/index.md +3 -0
- package/docs/concepts.llms.md +475 -0
- package/instructions/coding-conventions.md +8 -0
- package/package.json +96 -3
- package/skills/command/SKILL.md +63 -0
- package/skills/command/references/examples/cli.ts +22 -0
- package/skills/command/references/examples/options-only.ts +27 -0
- package/skills/command/references/examples/preview-command.ts +57 -0
- package/skills/command/references/execution.md +31 -0
- package/skills/command/references/inputs.md +27 -0
- package/skills/fundamental/SKILL.md +80 -0
- package/skills/fundamental/references/composition.md +35 -0
- package/skills/fundamental/references/constraints-and-validation.md +61 -0
- package/skills/fundamental/references/examples/async-composition.ts +15 -0
- package/skills/fundamental/references/examples/cast.ts +18 -0
- package/skills/fundamental/references/examples/composition.ts +40 -0
- package/skills/fundamental/references/examples/environment-initialization.ts +19 -0
- package/skills/fundamental/references/examples/error-propagation.ts +24 -0
- package/skills/fundamental/references/examples/generic-inference.ts +31 -0
- package/skills/fundamental/references/examples/guaranteed-array-access.ts +31 -0
- package/skills/fundamental/references/examples/independent-inputs.ts +18 -0
- package/skills/fundamental/references/examples/infer.ts +21 -0
- package/skills/fundamental/references/examples/input-validation.ts +37 -0
- package/skills/fundamental/references/examples/safe-declarations.ts +25 -0
- package/skills/fundamental/references/results-and-errors.md +59 -0
- package/skills/http-client/SKILL.md +50 -0
- package/skills/http-client/references/configuration.md +9 -0
- package/skills/http-client/references/examples/client-expectations.ts +84 -0
- package/skills/http-client/references/examples/client-streams.ts +74 -0
- package/skills/http-client/references/examples/external-client.ts +78 -0
- package/skills/http-client/references/hooks.md +7 -0
- package/skills/http-client/references/responses.md +39 -0
- package/skills/http-client/references/streams.md +10 -0
- package/skills/http-server/SKILL.md +66 -0
- package/skills/http-server/references/code-generation.md +31 -0
- package/skills/http-server/references/examples/authentication.ts +42 -0
- package/skills/http-server/references/examples/contracts.ts +19 -0
- package/skills/http-server/references/examples/generate-sdk.ts +36 -0
- package/skills/http-server/references/examples/initialize.ts +29 -0
- package/skills/http-server/references/examples/minimal-route.ts +18 -0
- package/skills/http-server/references/examples/protected-route.ts +31 -0
- package/skills/http-server/references/examples/rename-user-route.ts +54 -0
- package/skills/http-server/references/examples/user-checker.ts +26 -0
- package/skills/http-server/references/examples/user-route.ts +38 -0
- package/skills/http-server/references/initialization.md +33 -0
- package/skills/http-server/references/reusable-flows.md +40 -0
- package/skills/http-server/references/routes-and-floor.md +38 -0
- package/skills/modeling/SKILL.md +76 -0
- package/skills/modeling/references/domain.md +33 -0
- package/skills/modeling/references/orchestration.md +36 -0
- package/skills/server/SKILL.md +55 -0
- package/skills/server/references/environment.md +30 -0
- package/skills/server/references/examples/environment.ts +41 -0
- package/skills/server/references/examples/file-structure.ts +26 -0
- package/skills/server/references/examples/files.ts +52 -0
- package/skills/server/references/files.md +38 -0
- package/skills/server/references/structures.md +15 -0
- package/skills/test/SKILL.md +70 -0
- package/skills/test/references/examples/results.ts +95 -0
- package/skills/test/references/examples/server.ts +59 -0
- package/skills/test/references/results.md +21 -0
- package/skills/test/references/server.md +17 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @title Composer avec les layouts
|
|
3
|
+
*
|
|
4
|
+
* Composition de la structure des données et des comportements d’un formulaire.
|
|
5
|
+
*/
|
|
6
|
+
import { createForm, useCheckLayout, useDisabledLayout, useMultiLayout, useRepeatLayout, useSectionLayout, useSlotLayout, useStepLayout, useUnionLayout } from "@duplojs/form/vue";
|
|
7
|
+
import { templateFormAddButton, templateFormNextButton, templateFormPreviousButton, templateFormRemoveButton, templateFormResetButton, templateFormSelect, useTextareaInput, useTextInput } from "@duplojs/form/vueDesignSystem";
|
|
8
|
+
import { createGridTemplates } from "@duplojs/form/vueGrid";
|
|
9
|
+
import * as DDataStructure from "@duplojs/lang/dataStructure";
|
|
10
|
+
import { ref } from "vue";
|
|
11
|
+
|
|
12
|
+
const gridTemplates = createGridTemplates({
|
|
13
|
+
repeat: {
|
|
14
|
+
addLabel: "Add another item",
|
|
15
|
+
removeLabel: "Remove this item",
|
|
16
|
+
addButton: templateFormAddButton,
|
|
17
|
+
removeButton: templateFormRemoveButton,
|
|
18
|
+
resetButton: templateFormResetButton,
|
|
19
|
+
},
|
|
20
|
+
step: {
|
|
21
|
+
nextLabel: "Continue",
|
|
22
|
+
previousLabel: "Back",
|
|
23
|
+
resetButton: templateFormResetButton,
|
|
24
|
+
nextButton: templateFormNextButton,
|
|
25
|
+
previousButton: templateFormPreviousButton,
|
|
26
|
+
},
|
|
27
|
+
union: { selectInputKind: templateFormSelect },
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const useForm = createForm(
|
|
31
|
+
gridTemplates.useTemplates(),
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
// Les layouts de structure modifient directement la forme de `currentValue`
|
|
35
|
+
// et la forme de la valeur retournée par `check`.
|
|
36
|
+
// Un layout reçoit un ou plusieurs champs et produit un nouveau `FormField`.
|
|
37
|
+
// Ici, les inputs sont composés dans des layouts, eux-mêmes imbriqués dans
|
|
38
|
+
// `useMultiLayout`, puis `useSectionLayout` fournit le champ racine à `useForm`.
|
|
39
|
+
const { check: checkStructureForm, component: StructureForm, currentValue: currentStructureValue } = useForm(
|
|
40
|
+
useSectionLayout(
|
|
41
|
+
useMultiLayout({
|
|
42
|
+
identity: useMultiLayout({
|
|
43
|
+
firstName: useTextInput({ label: "First name" }),
|
|
44
|
+
lastName: useTextInput({ label: "Last name" }),
|
|
45
|
+
}),
|
|
46
|
+
contacts: useRepeatLayout(
|
|
47
|
+
useTextInput({ label: "Email" }),
|
|
48
|
+
{
|
|
49
|
+
min: 1,
|
|
50
|
+
max: 3,
|
|
51
|
+
},
|
|
52
|
+
),
|
|
53
|
+
preferredContact: useUnionLayout(
|
|
54
|
+
[
|
|
55
|
+
["email", useTextInput({ label: "Email" })],
|
|
56
|
+
["phone", useTextInput({ label: "Phone" })],
|
|
57
|
+
],
|
|
58
|
+
{ defaultKind: "email" },
|
|
59
|
+
),
|
|
60
|
+
message: useSlotLayout(
|
|
61
|
+
"customMessage",
|
|
62
|
+
useTextareaInput({ label: "Message" }),
|
|
63
|
+
),
|
|
64
|
+
}),
|
|
65
|
+
{ title: "Profile" },
|
|
66
|
+
),
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
// Ref<{
|
|
70
|
+
// identity: {
|
|
71
|
+
// firstName: string;
|
|
72
|
+
// lastName: string;
|
|
73
|
+
// };
|
|
74
|
+
// contacts: [string, ...string[]];
|
|
75
|
+
// preferredContact: {
|
|
76
|
+
// readonly kind: "email" | "phone";
|
|
77
|
+
// value: string;
|
|
78
|
+
// updateKind(kind: "email" | "phone", value?: string): void;
|
|
79
|
+
// };
|
|
80
|
+
// message: string;
|
|
81
|
+
// }>
|
|
82
|
+
void currentStructureValue;
|
|
83
|
+
|
|
84
|
+
// DEither.Error<DetailsError> | DEither.Success<{
|
|
85
|
+
// identity: {
|
|
86
|
+
// firstName: string;
|
|
87
|
+
// lastName: string;
|
|
88
|
+
// };
|
|
89
|
+
// contacts: [string, ...string[]];
|
|
90
|
+
// preferredContact: {
|
|
91
|
+
// kind: "email" | "phone";
|
|
92
|
+
// value: string;
|
|
93
|
+
// };
|
|
94
|
+
// message: string | undefined;
|
|
95
|
+
// }>
|
|
96
|
+
const checkedStructureValue = await checkStructureForm();
|
|
97
|
+
|
|
98
|
+
void checkedStructureValue;
|
|
99
|
+
void StructureForm;
|
|
100
|
+
|
|
101
|
+
const hasCompany = ref(false);
|
|
102
|
+
|
|
103
|
+
// Les layouts de contrôle changent surtout le flux du formulaire.
|
|
104
|
+
// `step` impose une progression, `check` ajoute une validation autour d'un
|
|
105
|
+
// champ existant, et `disabled` retire temporairement un champ du rendu et
|
|
106
|
+
// de la valeur validée.
|
|
107
|
+
const { check: checkFlowForm, component: FlowForm, currentValue: currentFlowValue } = useForm(
|
|
108
|
+
useStepLayout(
|
|
109
|
+
[
|
|
110
|
+
useMultiLayout({
|
|
111
|
+
fullName: useTextInput({ label: "Full name" }),
|
|
112
|
+
email: useCheckLayout(
|
|
113
|
+
useTextInput({ label: "Email" }),
|
|
114
|
+
{
|
|
115
|
+
dataStructure: DDataStructure.string([DDataStructure.email()]),
|
|
116
|
+
},
|
|
117
|
+
),
|
|
118
|
+
}),
|
|
119
|
+
useMultiLayout({
|
|
120
|
+
company: useDisabledLayout(
|
|
121
|
+
useTextInput({ label: "Company" }),
|
|
122
|
+
{
|
|
123
|
+
isDisabled: () => !hasCompany.value,
|
|
124
|
+
},
|
|
125
|
+
),
|
|
126
|
+
notes: useTextareaInput({ label: "Notes" }),
|
|
127
|
+
}),
|
|
128
|
+
],
|
|
129
|
+
{
|
|
130
|
+
errorMessageNotAtLastStep: "Complete all steps before submitting.",
|
|
131
|
+
},
|
|
132
|
+
),
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
// Ref<{
|
|
136
|
+
// currentStep: 0 | 1;
|
|
137
|
+
// steps: [
|
|
138
|
+
// {
|
|
139
|
+
// fullName: string;
|
|
140
|
+
// email: string;
|
|
141
|
+
// },
|
|
142
|
+
// {
|
|
143
|
+
// company: string;
|
|
144
|
+
// notes: string;
|
|
145
|
+
// },
|
|
146
|
+
// ];
|
|
147
|
+
// }>
|
|
148
|
+
void currentFlowValue;
|
|
149
|
+
|
|
150
|
+
// DEither.Error<DetailsError> | DEither.Success<[
|
|
151
|
+
// {
|
|
152
|
+
// fullName: string;
|
|
153
|
+
// email: string & Email;
|
|
154
|
+
// },
|
|
155
|
+
// {
|
|
156
|
+
// company: string | undefined;
|
|
157
|
+
// notes: string;
|
|
158
|
+
// },
|
|
159
|
+
// ]>
|
|
160
|
+
const checkedFlowValue = await checkFlowForm();
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @title Personnaliser les templates
|
|
3
|
+
*
|
|
4
|
+
* Personnalisation globale ou locale du rendu Vue des formulaires et de leurs champs.
|
|
5
|
+
*/
|
|
6
|
+
import { createForm, createTemplate, useMultiLayout, type InputTemplateProperties, type VueComponent } from "@duplojs/form/vue";
|
|
7
|
+
import { templateFormAddButton, templateFormNextButton, templateFormPreviousButton, templateFormRemoveButton, templateFormResetButton, templateFormSelect, useTextareaInput, useTextInput } from "@duplojs/form/vueDesignSystem";
|
|
8
|
+
import { createGridTemplates } from "@duplojs/form/vueGrid";
|
|
9
|
+
|
|
10
|
+
// Un template transforme les props système et les slots en interface Vue.
|
|
11
|
+
// Il reste générique : la connaissance métier appartient au formulaire.
|
|
12
|
+
// Remplacer le template change le rendu ; la structure des champs, leurs
|
|
13
|
+
// validations et leurs valeurs restent définies par les inputs et les layouts.
|
|
14
|
+
interface HeroInputTemplateProperties {
|
|
15
|
+
props: (
|
|
16
|
+
& InputTemplateProperties["props"]
|
|
17
|
+
& {
|
|
18
|
+
tone?: "default" | "accent";
|
|
19
|
+
}
|
|
20
|
+
);
|
|
21
|
+
slots: InputTemplateProperties["slots"];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
declare const HeroInputTemplate: VueComponent<HeroInputTemplateProperties>;
|
|
25
|
+
|
|
26
|
+
// La clé `"input"` indique quelle partie du rendu est remplacée.
|
|
27
|
+
const useHeroInputTemplate = createTemplate(
|
|
28
|
+
"input",
|
|
29
|
+
HeroInputTemplate,
|
|
30
|
+
{
|
|
31
|
+
props: {
|
|
32
|
+
tone: "default",
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
// Les templates grid fournissent une base visuelle remplaçable globalement
|
|
38
|
+
// ou localement.
|
|
39
|
+
const gridTemplates = createGridTemplates({
|
|
40
|
+
repeat: {
|
|
41
|
+
addLabel: "Add another item",
|
|
42
|
+
removeLabel: "Remove this item",
|
|
43
|
+
addButton: templateFormAddButton,
|
|
44
|
+
removeButton: templateFormRemoveButton,
|
|
45
|
+
resetButton: templateFormResetButton,
|
|
46
|
+
},
|
|
47
|
+
step: {
|
|
48
|
+
nextLabel: "Continue",
|
|
49
|
+
previousLabel: "Back",
|
|
50
|
+
resetButton: templateFormResetButton,
|
|
51
|
+
nextButton: templateFormNextButton,
|
|
52
|
+
previousButton: templateFormPreviousButton,
|
|
53
|
+
},
|
|
54
|
+
union: { selectInputKind: templateFormSelect },
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// La surcharge globale s'applique à tous les champs concernés par ce formulaire.
|
|
58
|
+
const useForm = createForm({
|
|
59
|
+
...gridTemplates.useTemplates(),
|
|
60
|
+
input: useHeroInputTemplate({ tone: "accent" }),
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const { component: TheForm, currentValue } = useForm(
|
|
64
|
+
useMultiLayout({
|
|
65
|
+
title: useTextInput({
|
|
66
|
+
label: "Title",
|
|
67
|
+
}),
|
|
68
|
+
subtitle: useTextInput({
|
|
69
|
+
label: "Subtitle",
|
|
70
|
+
template: useHeroInputTemplate({ tone: "default" }),
|
|
71
|
+
}),
|
|
72
|
+
summary: useTextareaInput({
|
|
73
|
+
label: "Summary",
|
|
74
|
+
template: gridTemplates.useInputTemplate({
|
|
75
|
+
columns: 12,
|
|
76
|
+
}),
|
|
77
|
+
}),
|
|
78
|
+
}),
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
// `title` utilise le template global, `subtitle` le surcharge localement,
|
|
82
|
+
// `summary` revient au template grid.
|
|
83
|
+
//
|
|
84
|
+
// Ref<{
|
|
85
|
+
// title: string;
|
|
86
|
+
// subtitle: string;
|
|
87
|
+
// summary: string;
|
|
88
|
+
// }>
|
|
89
|
+
void currentValue;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Client
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @title Tester un résultat Either
|
|
3
|
+
*
|
|
4
|
+
* Vérification des branches, des valeurs et du typage d’un contrat Either.
|
|
5
|
+
*/
|
|
6
|
+
import * as DCommon from "@duplojs/lang/common";
|
|
7
|
+
import * as DEither from "@duplojs/lang/either";
|
|
8
|
+
|
|
9
|
+
// Dans les tests du monorepo, Vitest expose ces globals directement.
|
|
10
|
+
// Ces déclarations rendent uniquement l'exemple typable dans la documentation d'AgentKit.
|
|
11
|
+
declare const describe: (title: string, body: () => void) => void;
|
|
12
|
+
declare const it: (title: string, body: () => void | Promise<void>) => void;
|
|
13
|
+
declare const expect: (value: unknown) => {
|
|
14
|
+
toBe(expected: unknown): void;
|
|
15
|
+
toStrictEqual(expected: unknown): void;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
interface User {
|
|
19
|
+
id: number;
|
|
20
|
+
email: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
declare function findUserByEmail(
|
|
24
|
+
email: string,
|
|
25
|
+
): (
|
|
26
|
+
| DEither.Result<"user.found", User>
|
|
27
|
+
| DEither.Left<"user.notfound", string>
|
|
28
|
+
| DEither.Error<Error>
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
// L'unwrap exprime la branche attendue avant l'assertion sur la donnée.
|
|
32
|
+
// `unwrapByInformationOrThrow` sélectionne l’information visée et extrait sa
|
|
33
|
+
// valeur. Une information différente provoque une exception et fait échouer le test.
|
|
34
|
+
// L’assertion vérifie ensuite la donnée ; `ExpectType` vérifie son type à la compilation.
|
|
35
|
+
describe("findUserByEmail", () => {
|
|
36
|
+
it("returns the found user", () => {
|
|
37
|
+
const result = findUserByEmail("jane@duplo.dev");
|
|
38
|
+
|
|
39
|
+
const user = DEither.unwrapByInformationOrThrow(
|
|
40
|
+
result,
|
|
41
|
+
"user.found",
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
expect(user).toStrictEqual({
|
|
45
|
+
id: 1,
|
|
46
|
+
email: "jane@duplo.dev",
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
type _CheckUser = DCommon.ExpectType<
|
|
50
|
+
typeof user,
|
|
51
|
+
User,
|
|
52
|
+
"strict"
|
|
53
|
+
>;
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("returns the not found email", () => {
|
|
57
|
+
const result = findUserByEmail("missing@duplo.dev");
|
|
58
|
+
|
|
59
|
+
const email = DEither.unwrapByInformationOrThrow(
|
|
60
|
+
result,
|
|
61
|
+
"user.notfound",
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
expect(email).toBe("missing@duplo.dev");
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// La sélection rend explicites les branches acceptées par ce test.
|
|
69
|
+
// `unwrapSelectionOrThrow` lève aussi une exception si le résultat appartient
|
|
70
|
+
// à une branche exclue, ici `error`.
|
|
71
|
+
describe("findUserByEmail selection", () => {
|
|
72
|
+
it("accepts only the business results handled by this test", () => {
|
|
73
|
+
const result = findUserByEmail("jane@duplo.dev");
|
|
74
|
+
|
|
75
|
+
const value = DEither.unwrapSelectionOrThrow(
|
|
76
|
+
result,
|
|
77
|
+
{
|
|
78
|
+
"user.found": true,
|
|
79
|
+
"user.notfound": true,
|
|
80
|
+
error: false,
|
|
81
|
+
},
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
type _CheckValue = DCommon.ExpectType<
|
|
85
|
+
typeof value,
|
|
86
|
+
User | string,
|
|
87
|
+
"strict"
|
|
88
|
+
>;
|
|
89
|
+
|
|
90
|
+
if (typeof value === "string") {
|
|
91
|
+
expect(value).toBe("jane@duplo.dev");
|
|
92
|
+
} else {
|
|
93
|
+
expect(value).toStrictEqual({
|
|
94
|
+
id: 1,
|
|
95
|
+
email: "jane@duplo.dev",
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// `DEither.expect` matérialise dans le type qu'une valeur est déjà un `Either`.
|
|
102
|
+
describe("DEither.expect", () => {
|
|
103
|
+
it("keeps the exact either type", () => {
|
|
104
|
+
const input = DEither.success(42);
|
|
105
|
+
const result = DEither.expect(input);
|
|
106
|
+
|
|
107
|
+
expect(result).toBe(input);
|
|
108
|
+
|
|
109
|
+
type _CheckResult = DCommon.ExpectType<
|
|
110
|
+
typeof result,
|
|
111
|
+
DEither.Success<42>,
|
|
112
|
+
"strict"
|
|
113
|
+
>;
|
|
114
|
+
|
|
115
|
+
// @ts-expect-error input must be an Either
|
|
116
|
+
DEither.expect("plain value");
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Tester une API curifiée dans son contexte réel conserve l'inférence utile.
|
|
121
|
+
describe("curried Either helpers", () => {
|
|
122
|
+
it("preserves inference in a pipe", () => {
|
|
123
|
+
const result = DCommon.pipe(
|
|
124
|
+
findUserByEmail("jane@duplo.dev"),
|
|
125
|
+
DEither.unwrapByInformationOrThrow("user.found"),
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
expect(result.email).toBe("jane@duplo.dev");
|
|
129
|
+
|
|
130
|
+
type _CheckResult = DCommon.ExpectType<
|
|
131
|
+
typeof result,
|
|
132
|
+
User,
|
|
133
|
+
"strict"
|
|
134
|
+
>;
|
|
135
|
+
});
|
|
136
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @title Remplacer les implémentations serveur
|
|
3
|
+
*
|
|
4
|
+
* Contrôle de l'environnement et des fonctions serveur pour isoler les tests.
|
|
5
|
+
*/
|
|
6
|
+
import * as DEither from "@duplojs/lang/either";
|
|
7
|
+
// Ces deux outils sont des exports directs du package, sans sous-export dédié.
|
|
8
|
+
import { TESTImplementation, setEnvironment } from "@duplojs/server";
|
|
9
|
+
import * as DSCommand from "@duplojs/server/command";
|
|
10
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
11
|
+
|
|
12
|
+
// Pour les fonctions serveur exposées via `implementFunction`, privilégier
|
|
13
|
+
// ce mécanisme aux mocks de modules ou d'imports et aux spies sur les exports.
|
|
14
|
+
// `setEnvironment("TEST")` sélectionne les implémentations enregistrées avec
|
|
15
|
+
// `TESTImplementation.set` ; leur signature est vérifiée par TypeScript.
|
|
16
|
+
// Chaque fonction serveur effectivement appelée, même indirectement, doit être
|
|
17
|
+
// enregistrée : une implémentation absente lève une erreur, sans repli natif.
|
|
18
|
+
describe("command with controlled server dependencies", () => {
|
|
19
|
+
afterEach(() => {
|
|
20
|
+
// Le registre et l'environnement sont partagés. Nettoyer même si le test
|
|
21
|
+
// échoue ; ne pas exécuter ces tests concurremment.
|
|
22
|
+
TESTImplementation.clear();
|
|
23
|
+
// Cette suite Vitest tourne sous Node. Adapter l'environnement rétabli
|
|
24
|
+
// à celui attendu par la suite lorsqu'elle utilise Bun ou Deno.
|
|
25
|
+
setEnvironment("NODE");
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("reads the injected process arguments", async() => {
|
|
29
|
+
setEnvironment("TEST");
|
|
30
|
+
|
|
31
|
+
// `vi.fn` reste utile pour observer les appels de l'implémentation injectée.
|
|
32
|
+
const getProcessArgumentsSpy = vi.fn(() => ["--verbose"]);
|
|
33
|
+
TESTImplementation.set("getProcessArguments", getProcessArgumentsSpy);
|
|
34
|
+
const executeSpy = vi.fn(() => undefined);
|
|
35
|
+
|
|
36
|
+
const result = await DSCommand.exec(
|
|
37
|
+
{
|
|
38
|
+
displayName: "tool",
|
|
39
|
+
options: [DSCommand.createBooleanOption("verbose")],
|
|
40
|
+
},
|
|
41
|
+
executeSpy,
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
DEither.unwrapByInformationOrThrow(result, "ok");
|
|
45
|
+
expect(getProcessArgumentsSpy).toHaveBeenCalledTimes(1);
|
|
46
|
+
expect(executeSpy).toHaveBeenCalledWith({
|
|
47
|
+
options: { verbose: true },
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// Les autres dépendances sans ce mécanisme peuvent toujours être observées
|
|
53
|
+
// ou remplacées avec les outils de mock habituels du runner de tests.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @title Initialiser le client E2E
|
|
3
|
+
*
|
|
4
|
+
* Configuration de l’environnement de test et intégration du site aux fixtures Playwright.
|
|
5
|
+
*/
|
|
6
|
+
import * as DCommon from "@duplojs/lang/common";
|
|
7
|
+
import * as DDataStructure from "@duplojs/lang/dataStructure";
|
|
8
|
+
import * as DSCommon from "@duplojs/server/common";
|
|
9
|
+
import { createWebsite, type Website } from "@duplojs/playwright";
|
|
10
|
+
import test, { defineConfig, devices } from "playwright/test";
|
|
11
|
+
|
|
12
|
+
const envs = await DSCommon.environmentVariableOrThrow(
|
|
13
|
+
{
|
|
14
|
+
BASE_URL: DDataStructure.string([DDataStructure.url()]),
|
|
15
|
+
CI: DDataStructure.boolean(),
|
|
16
|
+
RETRIES: DDataStructure.number([DDataStructure.integer()]),
|
|
17
|
+
WORKERS: DDataStructure.number([DDataStructure.integer()]),
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
justRead: true,
|
|
21
|
+
includedEnvironmentFiles: [DCommon.infer(".env")],
|
|
22
|
+
},
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
// La configuration reste une configuration Playwright normale.
|
|
26
|
+
export default defineConfig({
|
|
27
|
+
testDir: "./tests",
|
|
28
|
+
fullyParallel: true,
|
|
29
|
+
forbidOnly: envs.CI,
|
|
30
|
+
retries: envs.RETRIES,
|
|
31
|
+
workers: envs.WORKERS,
|
|
32
|
+
reporter: [
|
|
33
|
+
[
|
|
34
|
+
"html",
|
|
35
|
+
{
|
|
36
|
+
open: "never",
|
|
37
|
+
outputFolder: "playwright-report",
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
["list"],
|
|
41
|
+
],
|
|
42
|
+
use: {
|
|
43
|
+
headless: true,
|
|
44
|
+
trace: "retain-on-failure",
|
|
45
|
+
screenshot: "only-on-failure",
|
|
46
|
+
},
|
|
47
|
+
projects: [
|
|
48
|
+
{
|
|
49
|
+
name: "chromium",
|
|
50
|
+
use: { ...devices["Desktop Chrome"] },
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
interface TestFixtures {
|
|
56
|
+
website: Website;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// La fixture ajoute `website` aux tests et centralise le contexte du site.
|
|
60
|
+
// Elle crée un `Website` par test à partir de la `page` et du `BrowserContext`
|
|
61
|
+
// fournis par Playwright. `baseUrl` fixe l’adresse du site ; le hook attend la
|
|
62
|
+
// fin du chargement réseau après chaque navigation.
|
|
63
|
+
export const testClient = test.extend<TestFixtures>({
|
|
64
|
+
async website({ page, context }, use) {
|
|
65
|
+
const website = createWebsite({
|
|
66
|
+
playwrightPage: page,
|
|
67
|
+
playwrightBrowserContext: context,
|
|
68
|
+
envConfig: {
|
|
69
|
+
baseUrl: envs.BASE_URL,
|
|
70
|
+
},
|
|
71
|
+
hooks: {
|
|
72
|
+
async afterNavigateOnPage() {
|
|
73
|
+
await page.waitForLoadState("networkidle");
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
await use(website);
|
|
79
|
+
},
|
|
80
|
+
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @title Architecturer une suite E2E
|
|
3
|
+
*
|
|
4
|
+
* Organisation d’une suite E2E selon les pages et les composants du site testé.
|
|
5
|
+
*/
|
|
6
|
+
import { createComponent, createPage } from "@duplojs/playwright";
|
|
7
|
+
|
|
8
|
+
// `Website` représente l’application et son contexte global, `Page` un écran
|
|
9
|
+
// navigable et `Component` une zone réutilisable de l’interface.
|
|
10
|
+
// Les locators sont déclarés dans ces objets ; les specs utilisent leurs
|
|
11
|
+
// éléments et leurs méthodes sans répéter les sélecteurs.
|
|
12
|
+
//
|
|
13
|
+
// tests/
|
|
14
|
+
// website.ts
|
|
15
|
+
// pages/
|
|
16
|
+
// home.page.ts
|
|
17
|
+
// search.page.ts
|
|
18
|
+
// components/
|
|
19
|
+
// newsletter.component.ts
|
|
20
|
+
// specs/
|
|
21
|
+
// home.spec.ts
|
|
22
|
+
|
|
23
|
+
// Un composant declare son element racine et les elements utiles au test.
|
|
24
|
+
export const newsletterComponent = createComponent(
|
|
25
|
+
"newsletter",
|
|
26
|
+
{
|
|
27
|
+
getMainElement({ body }) {
|
|
28
|
+
return body.locator("[data-newsletter]");
|
|
29
|
+
},
|
|
30
|
+
getElements({ mainElement }) {
|
|
31
|
+
return {
|
|
32
|
+
emailInput: mainElement.locator("input[type='email']"),
|
|
33
|
+
submitButton: mainElement.locator("button[type='submit']"),
|
|
34
|
+
feedback: mainElement.locator("[data-feedback]"),
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
// Une page ajoute un path et les composants disponibles sur cet ecran.
|
|
41
|
+
export const homePage = createPage(
|
|
42
|
+
"home",
|
|
43
|
+
{
|
|
44
|
+
makePath() {
|
|
45
|
+
return "/";
|
|
46
|
+
},
|
|
47
|
+
getMainElement({ body }) {
|
|
48
|
+
return body.locator("main[data-page='home']");
|
|
49
|
+
},
|
|
50
|
+
getElements({ mainElement }) {
|
|
51
|
+
return {
|
|
52
|
+
title: mainElement.locator("h1"),
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
components: [newsletterComponent],
|
|
56
|
+
},
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
// Les parametres d'URL restent avec la definition de l'ecran.
|
|
60
|
+
export const articlePage = createPage(
|
|
61
|
+
"article",
|
|
62
|
+
{
|
|
63
|
+
makePath(params: { slug: string }) {
|
|
64
|
+
return `/articles/${params.slug}`;
|
|
65
|
+
},
|
|
66
|
+
getMainElement({ body }) {
|
|
67
|
+
return body.locator("article");
|
|
68
|
+
},
|
|
69
|
+
getElements({ mainElement }) {
|
|
70
|
+
return {
|
|
71
|
+
title: mainElement.locator("h1"),
|
|
72
|
+
content: mainElement.locator("[data-content]"),
|
|
73
|
+
};
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
);
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @title Ecrire un parcours de test
|
|
3
|
+
*
|
|
4
|
+
* Scénarios utilisateur, interactions et vérifications avec les objets du site.
|
|
5
|
+
*/
|
|
6
|
+
import { Actions, Assertions, createComponent, createPage, type Website } from "@duplojs/playwright";
|
|
7
|
+
|
|
8
|
+
interface TestFixtures {
|
|
9
|
+
website: Website;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
declare const testClient: (title: string, body: (fixtures: TestFixtures) => Promise<void>) => void;
|
|
13
|
+
|
|
14
|
+
const newsletterComponent = createComponent(
|
|
15
|
+
"newsletter",
|
|
16
|
+
{
|
|
17
|
+
getMainElement({ body }) {
|
|
18
|
+
return body.locator("[data-newsletter]");
|
|
19
|
+
},
|
|
20
|
+
getElements({ mainElement }) {
|
|
21
|
+
return {
|
|
22
|
+
emailInput: mainElement.locator("input[type='email']"),
|
|
23
|
+
submitButton: mainElement.locator("button[type='submit']"),
|
|
24
|
+
feedback: mainElement.locator("[data-feedback]"),
|
|
25
|
+
};
|
|
26
|
+
},
|
|
27
|
+
getMethods({ elements }) {
|
|
28
|
+
return {
|
|
29
|
+
async subscribe(email: string) {
|
|
30
|
+
await elements!.emailInput.fill(email);
|
|
31
|
+
await elements!.submitButton.click();
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const homePage = createPage(
|
|
39
|
+
"home",
|
|
40
|
+
{
|
|
41
|
+
makePath() {
|
|
42
|
+
return "/";
|
|
43
|
+
},
|
|
44
|
+
getMainElement({ body }) {
|
|
45
|
+
return body.locator("main[data-page='home']");
|
|
46
|
+
},
|
|
47
|
+
getElements({ mainElement }) {
|
|
48
|
+
return {
|
|
49
|
+
title: mainElement.locator("h1"),
|
|
50
|
+
};
|
|
51
|
+
},
|
|
52
|
+
components: [newsletterComponent],
|
|
53
|
+
},
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
// Les actions parcourent l'interface, les assertions vérifient son état.
|
|
57
|
+
// Les clés passées aux helpers viennent des éléments nommés dans `getElements`.
|
|
58
|
+
// `Actions` et `Assertions` limitent ces clés aux éléments déclarés sur l’objet ciblé.
|
|
59
|
+
// Le scénario navigue vers une page, récupère son composant, agit sur ses
|
|
60
|
+
// éléments puis vérifie le résultat ; une méthode nommée peut regrouper les actions.
|
|
61
|
+
testClient("visitor subscribes to the newsletter", async({ website }) => {
|
|
62
|
+
const home = await website.iNavigateTo(homePage);
|
|
63
|
+
|
|
64
|
+
await website.iExpectTitleIs(/Home/);
|
|
65
|
+
await Assertions.toHaveText(home, "title", "Welcome");
|
|
66
|
+
|
|
67
|
+
const newsletter = await home.iWantToSeeComponent("newsletter");
|
|
68
|
+
|
|
69
|
+
await Assertions.toHaveText(newsletter, "feedback", "No email submitted yet.");
|
|
70
|
+
await Actions.fill(newsletter, "emailInput", "jane@duplo.dev");
|
|
71
|
+
await Actions.click(newsletter, "submitButton");
|
|
72
|
+
await Assertions.toContainText(newsletter, "feedback", "jane@duplo.dev");
|
|
73
|
+
await Assertions.toHaveValue(newsletter, "emailInput", "jane@duplo.dev");
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
testClient("visitor cannot submit an empty newsletter form", async({ website }) => {
|
|
77
|
+
const home = await website.iNavigateTo(homePage);
|
|
78
|
+
const newsletter = await home.iWantToSeeComponent("newsletter");
|
|
79
|
+
|
|
80
|
+
await Actions.click(newsletter, "submitButton");
|
|
81
|
+
await Assertions.toHaveText(newsletter, "feedback", "Email is required.");
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
testClient("component methods can express repeated intentions", async({ website }) => {
|
|
85
|
+
const home = await website.iNavigateTo(homePage);
|
|
86
|
+
const newsletter = await home.iWantToSeeComponent("newsletter");
|
|
87
|
+
|
|
88
|
+
await newsletter.methods.subscribe("jane@duplo.dev");
|
|
89
|
+
await Assertions.toContainText(newsletter, "feedback", "jane@duplo.dev");
|
|
90
|
+
});
|