Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ dist
coverage
cache

**/*.generate.*
**/*.generate.*
**/*.generate
9 changes: 6 additions & 3 deletions docs/en/v0/guide/plugins/codeGenerator.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@ next:
<!--@include: @/examples/v0/guide/plugins/codeGenerator/hub.ts-->
```

To generate typing for all your routes, use the `codeGeneratorPlugin` function from `@duplojs/http/codeGenerator` in the `Hub` and start with the environment variable set to `DEV` or `BUILD`.
To generate typings for all your routes, use the `codeGeneratorPlugin` function from `@duplojs/http/codeGenerator` in the `Hub`, then start with the environment variable set to `DEV` or `BUILD`.

The `outputFile` parameter lets you define which file the code will be written to.
- The `outputFile` parameter defines the file where route typings will be written.
- The `generateDataParser.outputFolder` parameter defines the folder where identified data parsers will be generated.
- The `generateDataParser.disabledFromRoute` parameter disables data parser generation from routes.
- The `generateDataParser.dataParsers` parameter lets you provide a list of data parsers to generate. In that case, only identified data parsers will be generated.

::: warning
You must have an HTTP server implementation, because the plugin hooks into `beforeStartServer`, which only runs via interface functions like `createHttpServer`. Run with the `Hub` configured in `BUILD` mode so the HTTP server doesn’t start.
You must have an HTTP server implementation, because the plugin hooks into `beforeStartServer`, which only runs through interface functions such as `createHttpServer`. Run with the `Hub` configured in `BUILD` mode to avoid starting the HTTP server.
:::
6 changes: 4 additions & 2 deletions docs/examples/v0/guide/features/formData/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { controlBodyAsFormData, ResponseContract, useRouteBuilder } from "@duplojs/http";
import { SDPE } from "@duplojs/server-utils";
import { SDP, SDPE } from "@duplojs/server-utils";
import { A, asyncPipe, DPE, E, Path } from "@duplojs/utils";

useRouteBuilder("POST", "/documents", {
Expand All @@ -10,7 +10,9 @@ useRouteBuilder("POST", "/documents", {
userId: DPE.coerce.number(),
files: DPE.object({
alt: DPE.string(),
file: SDPE.file().mimeType(["image/png", "image/jpeg"]),
file: SDPE.file().addChecker(
SDP.checkerFileMimeType(["image/png", "image/jpeg"]),
),
description: DPE.string(),
}).array(),
},
Expand Down
5 changes: 4 additions & 1 deletion docs/examples/v0/guide/plugins/codeGenerator/hub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import { codeGeneratorPlugin } from "@duplojs/http/codeGenerator";

const hub = createHub({ environment: "DEV" })
.register(routeStore.getAll())
.plug(codeGeneratorPlugin({ outputFile: "types.d.ts" }));
.plug(codeGeneratorPlugin({
outputFile: "types.d.ts",
generateDataParser: { outputFolder: "dataParsers" },
}));

await createHttpServer(
hub,
Expand Down
9 changes: 6 additions & 3 deletions docs/fr/v0/guide/plugins/codeGenerator.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@ next:
<!--@include: @/examples/v0/guide/plugins/codeGenerator/hub.ts-->
```

Pour générer le typage de toutes vos routes, il suffit d'utiliser la fonction `codeGeneratorPlugin` depuis `@duplojs/http/codeGenerator` dans le `Hub` et de démarrer avec la variable d'environnement sur `DEV` ou sur `BUILD`.
Pour générer le typage de toutes vos routes, utilisez la fonction `codeGeneratorPlugin` depuis `@duplojs/http/codeGenerator` dans le `Hub`, puis démarrez avec la variable d'environnement définie sur `DEV` ou `BUILD`.

Le paramètre `outputFile` vous permet de définir dans quel fichier sera écrit le code.
- Le paramètre `outputFile` permet de définir le fichier dans lequel le typage des routes sera écrit.
- Le paramètre `generateDataParser.outputFolder` définit le dossier dans lequel les data parsers identifiés seront générés.
- Le paramètre `generateDataParser.disabledFromRoute` désactive la génération de data parsers à partir des routes.
- Le paramètre `generateDataParser.dataParsers` permet de fournir une liste de data parsers à générer. Dans ce cas, seuls les data parsers identifiés seront générés.

::: warning
Vous êtes obligé d'avoir une implémentation de serveur HTTP, car le plugin se lie au hook `beforeStartServer` qui se lance uniquement via des fonctions d'interfaçage comme `createHttpServer`. Lancez avec le `Hub` configuré en mode `BUILD` pour que le serveur HTTP ne se lance pas.
Vous devez disposer d'une implémentation de serveur HTTP, car le plugin s'attache au hook `beforeStartServer`, qui n'est exécuté que via des fonctions d'interfaçage comme `createHttpServer`. Lancez avec un `Hub` configuré en mode `BUILD` pour éviter de démarrer le serveur HTTP.
:::
2 changes: 1 addition & 1 deletion docs/libs/v0/client/unexpectedResponseError.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export interface RequestErrorContent {
}
declare const UnexpectedInformationResponseError_base: new (params: {
"@DuplojsHttpClient/unexpected-information-response-error"?: unknown;
}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => import("@duplojs/utils").Kind<import("@duplojs/utils").KindDefinition<"@DuplojsHttpClient/unexpected-information-response-error", unknown>, unknown> & import("@duplojs/utils").Kind<import("@duplojs/utils").KindDefinition<"unexpected-information-response-error", unknown>, unknown> & Error;
}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & import("@duplojs/utils").Kind<import("@duplojs/utils").KindDefinition<"@DuplojsHttpClient/unexpected-information-response-error", unknown>, unknown> & import("@duplojs/utils").Kind<import("@duplojs/utils").KindDefinition<"unexpected-information-response-error", unknown>, unknown>;
export declare class UnexpectedInformationResponseError extends UnexpectedInformationResponseError_base {
information: string | string[];
response: RequestErrorContent | ClientResponse;
Expand Down
7 changes: 6 additions & 1 deletion docs/libs/v0/core/builders/route/extract.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ import { type DP, type ObjectEntry, type O, type SimplifyTopLevel, type NeverCoa
import { type ClientErrorResponseCode, type ResponseContract } from "../../response";
import { type Request } from "../../request";
import { type Metadata } from "../../metadata";
import { type ExtractParamsKeyFromPath } from "../../types";
type HandleParamsInference<GenericShape extends ExtractShape, GenericPath extends string> = (GenericShape & {
params?: ExtractParamsKeyFromPath<GenericPath> extends infer InferredKey extends string ? (Partial<Record<InferredKey, DP.DataParser>> & Record<string, DP.DataParser> & Record<Exclude<keyof GenericShape["params"], InferredKey>, never>) : {};
});
declare module "./builder" {
interface RouteBuilder<GenericDefinition extends RouteDefinition = RouteDefinition, GenericFloor extends Floor = {}> {
extract<GenericShape extends ExtractShape<Request>, GenericResponseContract extends (ResponseContract.Contract<ClientErrorResponseCode, string, DP.DataParserEmpty> | undefined) = never, const GenericMetadata extends readonly Metadata[] = readonly []>(shape: GenericShape, responseContract?: GenericResponseContract, ...metadata: GenericMetadata): RouteBuilder<O.AssignObjects<GenericDefinition, {
extract<GenericShape extends ExtractShape<Request>, GenericResponseContract extends (ResponseContract.Contract<ClientErrorResponseCode, string, DP.DataParserEmpty> | undefined) = never, const GenericMetadata extends readonly Metadata[] = readonly []>(shape: HandleParamsInference<GenericShape, GenericDefinition["paths"][number]>, responseContract?: GenericResponseContract, ...metadata: GenericMetadata): RouteBuilder<O.AssignObjects<GenericDefinition, {
readonly steps: readonly [
...GenericDefinition["steps"],
ExtractStep<{
Expand All @@ -25,3 +29,4 @@ declare module "./builder" {
}> : never>>;
}
}
export {};
25 changes: 7 additions & 18 deletions docs/libs/v0/core/clean/constraint.cjs
Original file line number Diff line number Diff line change
@@ -1,24 +1,13 @@
'use strict';

var utils = require('@duplojs/utils');
var clean = require('@duplojs/utils/clean');
require('@duplojs/utils/clean');

clean.createConstraint.overrideHandler.setMethod("toExtractParser", (self) => {
const dataParserWithCheckers = self
.primitiveHandler
.dataParser
.addChecker(...self.checkers);
const valueContainer = clean.constrainedTypeKind.setTo({}, { [self.name]: null });
const dataParser = utils.DPE.transform(dataParserWithCheckers, (input) => ({
...valueContainer,
[utils.keyWrappedValue]: input,
}));
return dataParser;
utils.C.createConstraint.overrideHandler.setMethod("toExtractParser", (self, params) => {
const innerDataParser = utils.C.toMapDataParser(self, params);
return utils.DPE.lazy(() => innerDataParser);
});
clean.createConstraint.overrideHandler.setMethod("toEndpointSchema", (self) => {
const dataParser = self
.primitiveHandler
.dataParser
.addChecker(...self.checkers);
return utils.DPE.lazy(() => dataParser);
utils.C.createConstraint.overrideHandler.setMethod("toEndpointSchema", (self) => {
const innerDataParser = self.internal.dataParser;
return utils.DPE.lazy(() => innerDataParser);
});
14 changes: 9 additions & 5 deletions docs/libs/v0/core/clean/constraint.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { type DP, DPE } from "@duplojs/utils";
import { type ConstrainedType, type EligiblePrimitive } from "@duplojs/utils/clean";
import { type DP, DPE, C } from "@duplojs/utils";
import "@duplojs/utils/clean";
interface ToExtractParserParams {
coerce?: boolean;
}
declare module "@duplojs/utils/clean" {
interface ConstraintHandler<GenericName extends string = string, GenericPrimitiveValue extends EligiblePrimitive = EligiblePrimitive, GenericCheckers extends readonly DP.DataParserChecker[] = readonly DP.DataParserChecker[]> {
toExtractParser(): DPE.ContractExtended<ConstrainedType<GenericName, GenericPrimitiveValue>, unknown>;
toEndpointSchema(): DPE.ContractExtended<GenericPrimitiveValue>;
interface ConstraintHandler<GenericName extends string = string, GenericPrimitiveValue extends C.EligiblePrimitive = C.EligiblePrimitive, GenericCheckers extends readonly DP.DataParserChecker[] = readonly DP.DataParserChecker[]> {
toExtractParser(params?: ToExtractParserParams): DPE.DataParserExtended<C.ConstrainedType<GenericName, GenericPrimitiveValue>, unknown>;
toEndpointSchema(): DPE.DataParserExtended<GenericPrimitiveValue>;
}
}
export {};
27 changes: 8 additions & 19 deletions docs/libs/v0/core/clean/constraint.mjs
Original file line number Diff line number Diff line change
@@ -1,22 +1,11 @@
import { DPE, keyWrappedValue } from '@duplojs/utils';
import { createConstraint, constrainedTypeKind } from '@duplojs/utils/clean';
import { C, DPE } from '@duplojs/utils';
import '@duplojs/utils/clean';

createConstraint.overrideHandler.setMethod("toExtractParser", (self) => {
const dataParserWithCheckers = self
.primitiveHandler
.dataParser
.addChecker(...self.checkers);
const valueContainer = constrainedTypeKind.setTo({}, { [self.name]: null });
const dataParser = DPE.transform(dataParserWithCheckers, (input) => ({
...valueContainer,
[keyWrappedValue]: input,
}));
return dataParser;
C.createConstraint.overrideHandler.setMethod("toExtractParser", (self, params) => {
const innerDataParser = C.toMapDataParser(self, params);
return DPE.lazy(() => innerDataParser);
});
createConstraint.overrideHandler.setMethod("toEndpointSchema", (self) => {
const dataParser = self
.primitiveHandler
.dataParser
.addChecker(...self.checkers);
return DPE.lazy(() => dataParser);
C.createConstraint.overrideHandler.setMethod("toEndpointSchema", (self) => {
const innerDataParser = self.internal.dataParser;
return DPE.lazy(() => innerDataParser);
});
28 changes: 7 additions & 21 deletions docs/libs/v0/core/clean/constraintsSet.cjs
Original file line number Diff line number Diff line change
@@ -1,27 +1,13 @@
'use strict';

var utils = require('@duplojs/utils');
var clean = require('@duplojs/utils/clean');
require('@duplojs/utils/clean');

clean.createConstraintsSet.overrideHandler.setMethod("toExtractParser", (self) => {
const checkers = utils.A.flatMap(self.constraints, ({ checkers }) => checkers);
const dataParserWithCheckers = self
.primitiveHandler
.dataParser
.addChecker(...checkers);
const constraintsKindValue = utils.pipe(self.constraints, utils.A.map(({ name }) => utils.O.entry(name, null)), utils.O.fromEntries);
const valueContainer = clean.constrainedTypeKind.setTo({}, constraintsKindValue);
const dataParser = utils.DPE.transform(dataParserWithCheckers, (input) => ({
...valueContainer,
[utils.keyWrappedValue]: input,
}));
return dataParser;
utils.C.createConstraintsSet.overrideHandler.setMethod("toExtractParser", (self, params) => {
const innerDataParser = utils.C.toMapDataParser(self, params);
return utils.DPE.lazy(() => innerDataParser);
});
clean.createConstraintsSet.overrideHandler.setMethod("toEndpointSchema", (self) => {
const checkers = utils.A.flatMap(self.constraints, ({ checkers }) => checkers);
const dataParserWithCheckers = self
.primitiveHandler
.dataParser
.addChecker(...checkers);
return utils.DPE.lazy(() => dataParserWithCheckers);
utils.C.createConstraintsSet.overrideHandler.setMethod("toEndpointSchema", (self) => {
const innerDataParser = self.internal.dataParser;
return utils.DPE.lazy(() => innerDataParser);
});
14 changes: 9 additions & 5 deletions docs/libs/v0/core/clean/constraintsSet.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { DPE, type UnionToIntersection } from "@duplojs/utils";
import { type EligiblePrimitive, type GetConstraint, type Primitive } from "@duplojs/utils/clean";
import { DPE, type UnionToIntersection, C } from "@duplojs/utils";
import "@duplojs/utils/clean";
interface ToExtractParserParams {
coerce?: boolean;
}
declare module "@duplojs/utils/clean" {
interface ConstraintsSetHandler<GenericPrimitiveValue extends EligiblePrimitive = EligiblePrimitive, GenericConstraintsHandler extends readonly ConstraintHandler[] = readonly []> {
toExtractParser(): DPE.ContractExtended<(Primitive<GenericPrimitiveValue> & UnionToIntersection<GenericConstraintsHandler[number] extends infer InferredConstraint ? InferredConstraint extends ConstraintHandler ? GetConstraint<InferredConstraint> : never : never>), unknown>;
toEndpointSchema(): DPE.ContractExtended<GenericPrimitiveValue>;
interface ConstraintsSetHandler<GenericPrimitiveValue extends C.EligiblePrimitive = C.EligiblePrimitive, GenericConstraintsHandler extends readonly ConstraintHandler[] = readonly []> {
toExtractParser(params?: ToExtractParserParams): DPE.DataParserExtended<(C.Primitive<GenericPrimitiveValue> & UnionToIntersection<GenericConstraintsHandler[number] extends infer InferredConstraint ? InferredConstraint extends ConstraintHandler ? C.GetConstraint<InferredConstraint> : never : never>), unknown>;
toEndpointSchema(): DPE.DataParserExtended<GenericPrimitiveValue>;
}
}
export {};
30 changes: 8 additions & 22 deletions docs/libs/v0/core/clean/constraintsSet.mjs
Original file line number Diff line number Diff line change
@@ -1,25 +1,11 @@
import { A, pipe, O, DPE, keyWrappedValue } from '@duplojs/utils';
import { createConstraintsSet, constrainedTypeKind } from '@duplojs/utils/clean';
import { C, DPE } from '@duplojs/utils';
import '@duplojs/utils/clean';

createConstraintsSet.overrideHandler.setMethod("toExtractParser", (self) => {
const checkers = A.flatMap(self.constraints, ({ checkers }) => checkers);
const dataParserWithCheckers = self
.primitiveHandler
.dataParser
.addChecker(...checkers);
const constraintsKindValue = pipe(self.constraints, A.map(({ name }) => O.entry(name, null)), O.fromEntries);
const valueContainer = constrainedTypeKind.setTo({}, constraintsKindValue);
const dataParser = DPE.transform(dataParserWithCheckers, (input) => ({
...valueContainer,
[keyWrappedValue]: input,
}));
return dataParser;
C.createConstraintsSet.overrideHandler.setMethod("toExtractParser", (self, params) => {
const innerDataParser = C.toMapDataParser(self, params);
return DPE.lazy(() => innerDataParser);
});
createConstraintsSet.overrideHandler.setMethod("toEndpointSchema", (self) => {
const checkers = A.flatMap(self.constraints, ({ checkers }) => checkers);
const dataParserWithCheckers = self
.primitiveHandler
.dataParser
.addChecker(...checkers);
return DPE.lazy(() => dataParserWithCheckers);
C.createConstraintsSet.overrideHandler.setMethod("toEndpointSchema", (self) => {
const innerDataParser = self.internal.dataParser;
return DPE.lazy(() => innerDataParser);
});
6 changes: 3 additions & 3 deletions docs/libs/v0/core/clean/entity.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
var utils = require('@duplojs/utils');
require('@duplojs/utils/clean');

utils.C.createEntity.overrideHandler.setMethod("toExtractParser", (self, keys) => {
utils.C.createEntity.overrideHandler.setMethod("toExtractParser", (self, keys, params) => {
if (typeof keys === "string") {
return utils.C.entityPropertyDefinitionToDataParser(self.propertiesDefinition[keys], (newTypeHandler) => newTypeHandler.toExtractParser());
return utils.C.entityPropertyDefinitionToDataParser(self.propertiesDefinition[keys], (newTypeHandler) => newTypeHandler.toExtractParser(params));
}
return utils.pipe(self.propertiesDefinition, utils.O.entries, utils.A.filter(([key]) => keys === undefined || utils.A.includes(keys, key)), utils.A.map(([key, value]) => utils.O.entry(key, utils.C.entityPropertyDefinitionToDataParser(value, (newTypeHandler) => newTypeHandler.toExtractParser()))), utils.O.fromEntries, utils.DPE.object);
return utils.pipe(self.propertiesDefinition, utils.O.entries, utils.A.filter(([key]) => keys === undefined || utils.A.includes(keys, key)), utils.A.map(([key, value]) => utils.O.entry(key, utils.C.entityPropertyDefinitionToDataParser(value, (newTypeHandler) => newTypeHandler.toExtractParser(params)))), utils.O.fromEntries, utils.DPE.object);
});
utils.C.createEntity.overrideHandler.setMethod("toEndpointSchema", (self, keys, params) => {
if (typeof keys === "string") {
Expand Down
Loading
Loading