@duplojs/agents-kit 0.1.0-beta.7 → 0.1.0-beta.9
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 +17 -9
- package/dist/bin/index.mjs +2 -2
- package/dist/bin/skills/index.d.ts +5 -0
- package/dist/bin/skills/index.mjs +11 -0
- package/dist/bin/{installSkill/index.d.ts → skills/install.d.ts} +1 -1
- package/dist/bin/{installSkill/index.mjs → skills/install.mjs} +2 -2
- package/dist/bin/{installSkill → skills}/skill.d.ts +7 -0
- package/dist/bin/{installSkill → skills}/skill.mjs +10 -8
- package/dist/bin/skills/update.d.ts +2 -0
- package/dist/bin/skills/update.mjs +19 -0
- package/docs/API/10-lang/10-common/10-asyncLoop.ts +4 -6
- package/docs/API/10-lang/10-common/10-asyncLoopAccumulator.ts +40 -0
- package/docs/API/10-lang/10-common/10-loop.ts +5 -7
- package/docs/API/10-lang/10-common/10-loopAccumulator.ts +35 -0
- package/docs/API/10-lang/10-common/10-loopAccumulatorFrom.ts +29 -0
- package/docs/API/10-lang/10-common/index.llms.md +14 -2
- package/docs/API/10-lang/10-generator/10-asyncLoop.ts +11 -20
- package/docs/API/10-lang/10-generator/10-asyncLoopAccumulator.ts +40 -0
- package/docs/API/10-lang/10-generator/10-loop.ts +11 -20
- package/docs/API/10-lang/10-generator/10-loopAccumulator.ts +33 -0
- package/docs/API/10-lang/10-generator/10-loopAccumulatorFrom.ts +30 -0
- package/docs/API/10-lang/10-generator/index.llms.md +14 -2
- package/docs/API/10-lang/10-object/10-discriminate.ts +84 -37
- package/docs/API/10-lang/10-object/index.llms.md +1 -5
- package/docs/API/20-server/10-file/10-appendFile.ts +50 -0
- package/docs/API/20-server/10-file/10-appendTextFile.ts +49 -0
- package/docs/API/20-server/10-file/10-copy.ts +50 -0
- package/docs/API/20-server/10-file/10-createEntryInterface.ts +13 -0
- package/docs/API/20-server/10-file/10-createFileInterface.ts +22 -0
- package/docs/API/20-server/10-file/10-createFolderInterface.ts +20 -0
- package/docs/API/20-server/10-file/10-createUnknownEntryInterface.ts +13 -0
- package/docs/API/20-server/10-file/10-ensureDirectory.ts +39 -0
- package/docs/API/20-server/10-file/10-ensureFile.ts +40 -0
- package/docs/API/20-server/10-file/10-exists.ts +36 -0
- package/docs/API/20-server/10-file/10-link.ts +51 -0
- package/docs/API/20-server/10-file/10-linkStat.ts +37 -0
- package/docs/API/20-server/10-file/10-makeDirectory.ts +41 -0
- package/docs/API/20-server/10-file/10-makeTemporaryDirectory.ts +35 -0
- package/docs/API/20-server/10-file/10-makeTemporaryFile.ts +40 -0
- package/docs/API/20-server/10-file/10-move.ts +51 -0
- package/docs/API/20-server/10-file/10-readDirectory.ts +52 -0
- package/docs/API/20-server/10-file/10-readFile.ts +38 -0
- package/docs/API/20-server/10-file/10-readJsonFile.ts +38 -0
- package/docs/API/20-server/10-file/10-readLink.ts +37 -0
- package/docs/API/20-server/10-file/10-readTextFile.ts +38 -0
- package/docs/API/20-server/10-file/10-realPath.ts +36 -0
- package/docs/API/20-server/10-file/10-relocate.ts +51 -0
- package/docs/API/20-server/10-file/10-remove.ts +40 -0
- package/docs/API/20-server/10-file/10-rename.ts +43 -0
- package/docs/API/20-server/10-file/10-setMode.ts +37 -0
- package/docs/API/20-server/10-file/10-setOwner.ts +38 -0
- package/docs/API/20-server/10-file/10-setTime.ts +42 -0
- package/docs/API/20-server/10-file/10-stat.ts +37 -0
- package/docs/API/20-server/10-file/10-symlink.ts +49 -0
- package/docs/API/20-server/10-file/10-truncate.ts +41 -0
- package/docs/API/20-server/10-file/10-walkDirectory.ts +75 -0
- package/docs/API/20-server/10-file/10-writeFile.ts +50 -0
- package/docs/API/20-server/10-file/10-writeJsonFile.ts +41 -0
- package/docs/API/20-server/10-file/10-writeTextFile.ts +49 -0
- package/docs/API/20-server/10-file/index.llms.md +144 -0
- package/docs/API/20-server/10-file/index.md +3 -0
- package/docs/API/20-server/20-common/10-environmentVariable.ts +57 -0
- package/docs/API/20-server/20-common/10-environmentVariableOrThrow.ts +21 -0
- package/docs/API/20-server/20-common/10-exitProcess.ts +9 -0
- package/docs/API/20-server/20-common/10-getCurrentDirectoryName.ts +10 -0
- package/docs/API/20-server/20-common/10-getCurrentWorkDirectory.ts +10 -0
- package/docs/API/20-server/20-common/10-getCurrentWorkDirectoryOrThrow.ts +10 -0
- package/docs/API/20-server/20-common/10-getProcessArguments.ts +10 -0
- package/docs/API/20-server/20-common/10-setCurrentWorkingDirectory.ts +14 -0
- package/docs/API/20-server/20-common/10-setCurrentWorkingDirectoryOrThrow.ts +12 -0
- package/docs/API/20-server/20-common/index.llms.md +40 -0
- package/docs/API/20-server/20-common/index.md +3 -0
- package/docs/API/20-server/30-dataStructure/10-file.ts +14 -0
- package/docs/API/20-server/30-dataStructure/10-fileExist.ts +27 -0
- package/docs/API/20-server/30-dataStructure/10-folder.ts +14 -0
- package/docs/API/20-server/30-dataStructure/10-folderExist.ts +14 -0
- package/docs/API/20-server/30-dataStructure/10-mimeType.ts +14 -0
- package/docs/API/20-server/30-dataStructure/10-size.ts +32 -0
- package/docs/API/20-server/30-dataStructure/index.llms.md +28 -0
- package/docs/API/20-server/30-dataStructure/index.md +3 -0
- package/docs/API/20-server/40-command/10-create.ts +39 -0
- package/docs/API/20-server/40-command/10-createArgument.ts +39 -0
- package/docs/API/20-server/40-command/10-createArrayOption.ts +36 -0
- package/docs/API/20-server/40-command/10-createBooleanOption.ts +28 -0
- package/docs/API/20-server/40-command/10-createOption.ts +46 -0
- package/docs/API/20-server/40-command/10-exec.ts +51 -0
- package/docs/API/20-server/40-command/10-execOptions.ts +30 -0
- package/docs/API/20-server/40-command/index.llms.md +32 -0
- package/docs/API/20-server/40-command/index.md +3 -0
- package/docs/API/20-server/index.md +3 -0
- package/docs/API.llms.md +20 -0
- package/package.json +14 -14
- package/skills/fundamental/SKILL.md +33 -33
- package/skills/fundamental/references/composition.md +9 -25
- package/skills/fundamental/references/constraints-and-validation.md +14 -51
- package/skills/fundamental/references/examples/iterations.ts +112 -0
- package/skills/fundamental/references/examples/result-selection.ts +65 -0
- package/skills/fundamental/references/iterations.md +24 -0
- package/skills/fundamental/references/results-and-errors.md +20 -45
- package/docs/API/10-lang/10-object/10-deepDiscriminate.ts +0 -63
|
@@ -24,7 +24,11 @@ Regrouper les valeurs d’un itérable asynchrone selon les sorties nommées d
|
|
|
24
24
|
|
|
25
25
|
### [DGenerator.asyncLoop](10-asyncLoop.ts)
|
|
26
26
|
|
|
27
|
-
Produire une séquence asynchrone
|
|
27
|
+
Produire une séquence asynchrone en distinguant les valeurs de `next` et celles de la sortie `exit`.
|
|
28
|
+
|
|
29
|
+
### [DGenerator.asyncLoopAccumulator](10-asyncLoopAccumulator.ts)
|
|
30
|
+
|
|
31
|
+
Produire une séquence asynchrone en mettant à jour un accumulateur à chaque itération.
|
|
28
32
|
|
|
29
33
|
### [DGenerator.asyncMap](10-asyncMap.ts)
|
|
30
34
|
|
|
@@ -68,7 +72,15 @@ Construire une sortie nommée destinée à la fonction de regroupement.
|
|
|
68
72
|
|
|
69
73
|
### [DGenerator.loop](10-loop.ts)
|
|
70
74
|
|
|
71
|
-
Produire une séquence
|
|
75
|
+
Produire une séquence synchrone en distinguant les valeurs de `next` et celles de la sortie `exit`.
|
|
76
|
+
|
|
77
|
+
### [DGenerator.loopAccumulator](10-loopAccumulator.ts)
|
|
78
|
+
|
|
79
|
+
Produire une séquence synchrone en mettant à jour un accumulateur à chaque itération.
|
|
80
|
+
|
|
81
|
+
### [DGenerator.loopAccumulatorFrom](10-loopAccumulatorFrom.ts)
|
|
82
|
+
|
|
83
|
+
Marquer une valeur initiale pour fixer précisément le type de l’accumulateur d’une boucle.
|
|
72
84
|
|
|
73
85
|
### [DGenerator.map](10-map.ts)
|
|
74
86
|
|
|
@@ -1,55 +1,102 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @title DObject.discriminate
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Tester une propriété avec un predicate et affiner l’objet par intersection.
|
|
5
5
|
*/
|
|
6
6
|
import * as DObject from "@duplojs/lang/object";
|
|
7
7
|
import * as DCommon from "@duplojs/lang/common";
|
|
8
|
+
import * as DNumber from "@duplojs/lang/number";
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
| {
|
|
15
|
-
type: "deleted";
|
|
16
|
-
id: number;
|
|
17
|
-
};
|
|
18
|
-
interface CreatedEvent {
|
|
19
|
-
type: "created";
|
|
20
|
-
id: string;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
interface DeletedEvent {
|
|
24
|
-
type: "deleted";
|
|
10
|
+
// Le predicate reçoit la valeur de la propriété. S’il affine cette valeur,
|
|
11
|
+
// l’objet conserve son type initial en intersection avec la propriété affinée.
|
|
12
|
+
declare const input: {
|
|
13
|
+
value: string | number;
|
|
25
14
|
id: number;
|
|
26
|
-
}
|
|
15
|
+
};
|
|
27
16
|
|
|
28
|
-
|
|
17
|
+
// Appel classique : affiner une propriété, même sans union d’objets.
|
|
18
|
+
if (DObject.discriminate(input, "value", DCommon.isType("string"))) {
|
|
19
|
+
type _CheckInput = DCommon.ExpectType<
|
|
20
|
+
typeof input,
|
|
21
|
+
{
|
|
22
|
+
value: string | number;
|
|
23
|
+
id: number;
|
|
24
|
+
} & { value: string },
|
|
25
|
+
"strict"
|
|
26
|
+
>;
|
|
27
|
+
const value = input.value;
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
type _CheckIfEvent = DCommon.ExpectType<typeof event, CreatedEvent, "strict">;
|
|
32
|
-
const id = event.id;
|
|
33
|
-
type _CheckIfId = DCommon.ExpectType<typeof id, string, "strict">;
|
|
29
|
+
type _CheckValue = DCommon.ExpectType<typeof value, string, "strict">;
|
|
34
30
|
}
|
|
35
31
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
type _CheckResult = DCommon.ExpectType<typeof result, boolean, "strict">;
|
|
40
|
-
|
|
41
|
-
// La forme curifiée est passée directement comme predicate à DCommon.when.
|
|
42
|
-
const id = DCommon.pipe(
|
|
43
|
-
event,
|
|
32
|
+
// Appel curifié : lire la chaîne si elle est présente, sinon conserver l’objet.
|
|
33
|
+
const result = DCommon.pipe(
|
|
34
|
+
input,
|
|
44
35
|
DCommon.when(
|
|
45
|
-
DObject.discriminate("
|
|
46
|
-
(
|
|
47
|
-
type
|
|
36
|
+
DObject.discriminate("value", DCommon.isType("string")),
|
|
37
|
+
(value) => {
|
|
38
|
+
type _CheckValue = DCommon.ExpectType<
|
|
39
|
+
typeof value,
|
|
40
|
+
{
|
|
41
|
+
value: string | number;
|
|
42
|
+
id: number;
|
|
43
|
+
} & { value: string },
|
|
44
|
+
"strict"
|
|
45
|
+
>;
|
|
48
46
|
|
|
49
|
-
return
|
|
47
|
+
return value.value;
|
|
50
48
|
},
|
|
51
49
|
),
|
|
52
50
|
);
|
|
53
51
|
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
type _CheckResult = DCommon.ExpectType<
|
|
53
|
+
typeof result,
|
|
54
|
+
string | {
|
|
55
|
+
value: string | number;
|
|
56
|
+
id: number;
|
|
57
|
+
},
|
|
58
|
+
"strict"
|
|
59
|
+
>;
|
|
60
|
+
|
|
61
|
+
// Les contraintes établies par le predicate sont portées par la propriété.
|
|
62
|
+
declare const person: {
|
|
63
|
+
age: number;
|
|
64
|
+
name: string;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
if (DObject.discriminate(person, "age", DNumber.greaterThan(18))) {
|
|
68
|
+
type _CheckPerson = DCommon.ExpectType<
|
|
69
|
+
typeof person,
|
|
70
|
+
{
|
|
71
|
+
age: number;
|
|
72
|
+
name: string;
|
|
73
|
+
} & { age: number & DNumber.GreaterThan<18> },
|
|
74
|
+
"strict"
|
|
75
|
+
>;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Composer les predicates pour une propriété imbriquée.
|
|
79
|
+
// DCommon.equal permet de conserver une vérification d’égalité.
|
|
80
|
+
declare const account: {
|
|
81
|
+
profile: { role: string };
|
|
82
|
+
id: number;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
if (DObject.discriminate(account, "profile", DObject.discriminate("role", DCommon.equal("admin")))) {
|
|
86
|
+
type _CheckAccount = DCommon.ExpectType<
|
|
87
|
+
typeof account,
|
|
88
|
+
{
|
|
89
|
+
profile: { role: string };
|
|
90
|
+
id: number;
|
|
91
|
+
} & { profile: { role: string } & { role: "admin" } },
|
|
92
|
+
"strict"
|
|
93
|
+
>;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Un predicate booléen reste accepté, sans affiner l’objet.
|
|
97
|
+
declare const threshold: number;
|
|
98
|
+
|
|
99
|
+
const isAboveThreshold = DObject.discriminate(person, "age", DNumber.greaterThan(threshold));
|
|
100
|
+
|
|
101
|
+
// true uniquement si l’âge dépasse le seuil fourni à l’exécution.
|
|
102
|
+
type _CheckIsAboveThreshold = DCommon.ExpectType<typeof isAboveThreshold, boolean, "strict">;
|
|
@@ -10,17 +10,13 @@ Fusionner les propriétés d’un objet dans une nouvelle valeur.
|
|
|
10
10
|
|
|
11
11
|
Compter les clés runtime d’un objet.
|
|
12
12
|
|
|
13
|
-
### [DObject.deepDiscriminate](10-deepDiscriminate.ts)
|
|
14
|
-
|
|
15
|
-
Discriminer une union d’objets à partir d’une propriété imbriquée.
|
|
16
|
-
|
|
17
13
|
### [DObject.deepOverride](10-deepOverride.ts)
|
|
18
14
|
|
|
19
15
|
Remplacer récursivement les valeurs définies d’un objet sans modifier la source.
|
|
20
16
|
|
|
21
17
|
### [DObject.discriminate](10-discriminate.ts)
|
|
22
18
|
|
|
23
|
-
|
|
19
|
+
Tester une propriété avec un predicate et affiner l’objet par intersection.
|
|
24
20
|
|
|
25
21
|
### [DObject.discriminateEntryKey](10-discriminateEntryKey.ts)
|
|
26
22
|
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @title DSFile.appendFile
|
|
3
|
+
*
|
|
4
|
+
* Ajouter des octets à un fichier.
|
|
5
|
+
*/
|
|
6
|
+
import * as DCommon from "@duplojs/lang/common";
|
|
7
|
+
import type * as DPath from "@duplojs/lang/path";
|
|
8
|
+
import * as DSFile from "@duplojs/server/file";
|
|
9
|
+
import * as DEither from "@duplojs/lang/either";
|
|
10
|
+
import * as DPattern from "@duplojs/lang/pattern";
|
|
11
|
+
|
|
12
|
+
declare const path: string & DPath.Path;
|
|
13
|
+
declare const bytes: Uint8Array;
|
|
14
|
+
|
|
15
|
+
// Appel direct
|
|
16
|
+
const result = await DSFile.appendFile(path, bytes);
|
|
17
|
+
|
|
18
|
+
// Forme curifiée
|
|
19
|
+
const pipedResult = await DCommon.pipe(
|
|
20
|
+
path,
|
|
21
|
+
DSFile.appendFile(bytes),
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
// Chaque résultat indique la réussite ou l'échec de l'écriture.
|
|
25
|
+
|
|
26
|
+
// L’information du Left identifie l’opération ; sa valeur précise la cause.
|
|
27
|
+
if (DEither.isLeft(result)) {
|
|
28
|
+
const error = DEither.unwrapLeft(result);
|
|
29
|
+
|
|
30
|
+
const diagnosis = DPattern.matchWithErrorOtherwise(
|
|
31
|
+
error,
|
|
32
|
+
{
|
|
33
|
+
"file-system-append-file-not-found": () => "missing",
|
|
34
|
+
"file-system-append-file-permission-denied": () => "access-denied",
|
|
35
|
+
},
|
|
36
|
+
(otherError) => otherError,
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Identifiants d’erreur déclarés pour cette opération :
|
|
41
|
+
// file-system-append-file-not-found
|
|
42
|
+
// file-system-append-file-permission-denied
|
|
43
|
+
// file-system-append-file-is-directory
|
|
44
|
+
// file-system-append-file-not-directory
|
|
45
|
+
// file-system-append-file-no-space
|
|
46
|
+
// file-system-append-file-read-only
|
|
47
|
+
// file-system-append-file-invalid-argument
|
|
48
|
+
// file-system-append-file-too-many-open-files
|
|
49
|
+
// file-system-append-file-busy
|
|
50
|
+
// file-system-append-file-error
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @title DSFile.appendTextFile
|
|
3
|
+
*
|
|
4
|
+
* Ajouter du texte à un fichier.
|
|
5
|
+
*/
|
|
6
|
+
import * as DCommon from "@duplojs/lang/common";
|
|
7
|
+
import type * as DPath from "@duplojs/lang/path";
|
|
8
|
+
import * as DSFile from "@duplojs/server/file";
|
|
9
|
+
import * as DEither from "@duplojs/lang/either";
|
|
10
|
+
import * as DPattern from "@duplojs/lang/pattern";
|
|
11
|
+
|
|
12
|
+
declare const path: string & DPath.Path;
|
|
13
|
+
|
|
14
|
+
// Appel direct
|
|
15
|
+
const result = await DSFile.appendTextFile(path, "nouvelle ligne\n");
|
|
16
|
+
|
|
17
|
+
// Forme curifiée
|
|
18
|
+
const pipedResult = await DCommon.pipe(
|
|
19
|
+
path,
|
|
20
|
+
DSFile.appendTextFile("nouvelle ligne\n"),
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
// Chaque résultat indique la réussite ou l'échec de l'écriture.
|
|
24
|
+
|
|
25
|
+
// L’information du Left identifie l’opération ; sa valeur précise la cause.
|
|
26
|
+
if (DEither.isLeft(result)) {
|
|
27
|
+
const error = DEither.unwrapLeft(result);
|
|
28
|
+
|
|
29
|
+
const diagnosis = DPattern.matchWithErrorOtherwise(
|
|
30
|
+
error,
|
|
31
|
+
{
|
|
32
|
+
"file-system-append-text-file-not-found": () => "missing",
|
|
33
|
+
"file-system-append-text-file-permission-denied": () => "access-denied",
|
|
34
|
+
},
|
|
35
|
+
(otherError) => otherError,
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Identifiants d’erreur déclarés pour cette opération :
|
|
40
|
+
// file-system-append-text-file-not-found
|
|
41
|
+
// file-system-append-text-file-permission-denied
|
|
42
|
+
// file-system-append-text-file-is-directory
|
|
43
|
+
// file-system-append-text-file-not-directory
|
|
44
|
+
// file-system-append-text-file-no-space
|
|
45
|
+
// file-system-append-text-file-read-only
|
|
46
|
+
// file-system-append-text-file-invalid-argument
|
|
47
|
+
// file-system-append-text-file-too-many-open-files
|
|
48
|
+
// file-system-append-text-file-busy
|
|
49
|
+
// file-system-append-text-file-error
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @title DSFile.copy
|
|
3
|
+
*
|
|
4
|
+
* Copier une ressource, récursivement pour un dossier.
|
|
5
|
+
*/
|
|
6
|
+
import * as DCommon from "@duplojs/lang/common";
|
|
7
|
+
import type * as DPath from "@duplojs/lang/path";
|
|
8
|
+
import * as DSFile from "@duplojs/server/file";
|
|
9
|
+
import * as DEither from "@duplojs/lang/either";
|
|
10
|
+
import * as DPattern from "@duplojs/lang/pattern";
|
|
11
|
+
|
|
12
|
+
declare const source: string & DPath.Path;
|
|
13
|
+
declare const destination: string & DPath.Path;
|
|
14
|
+
|
|
15
|
+
// Appel direct
|
|
16
|
+
const result = await DSFile.copy(source, destination);
|
|
17
|
+
|
|
18
|
+
// Forme curifiée
|
|
19
|
+
const pipedResult = await DCommon.pipe(
|
|
20
|
+
source,
|
|
21
|
+
DSFile.copy(destination),
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
// Les résultats dépendent de l'état du système de fichiers et peuvent échouer.
|
|
25
|
+
|
|
26
|
+
// L’information du Left identifie l’opération ; sa valeur précise la cause.
|
|
27
|
+
if (DEither.isLeft(result)) {
|
|
28
|
+
const error = DEither.unwrapLeft(result);
|
|
29
|
+
|
|
30
|
+
const diagnosis = DPattern.matchWithErrorOtherwise(
|
|
31
|
+
error,
|
|
32
|
+
{
|
|
33
|
+
"file-system-copy-not-found": () => "missing",
|
|
34
|
+
"file-system-copy-permission-denied": () => "access-denied",
|
|
35
|
+
},
|
|
36
|
+
(otherError) => otherError,
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Identifiants d’erreur déclarés pour cette opération :
|
|
41
|
+
// file-system-copy-not-found
|
|
42
|
+
// file-system-copy-permission-denied
|
|
43
|
+
// file-system-copy-already-exists
|
|
44
|
+
// file-system-copy-not-directory
|
|
45
|
+
// file-system-copy-no-space
|
|
46
|
+
// file-system-copy-read-only
|
|
47
|
+
// file-system-copy-invalid-argument
|
|
48
|
+
// file-system-copy-too-many-open-files
|
|
49
|
+
// file-system-copy-busy
|
|
50
|
+
// file-system-copy-error
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @title DSFile.createEntryInterface
|
|
3
|
+
*
|
|
4
|
+
* Inspecter une entrée et construire son interface adaptée.
|
|
5
|
+
*/
|
|
6
|
+
import type * as DPath from "@duplojs/lang/path";
|
|
7
|
+
import * as DSFile from "@duplojs/server/file";
|
|
8
|
+
|
|
9
|
+
declare const path: string & DPath.Path;
|
|
10
|
+
|
|
11
|
+
const result = await DSFile.createEntryInterface(path);
|
|
12
|
+
|
|
13
|
+
// La réussite distingue fichier, dossier et entrée inconnue ; un échec porte l’erreur d’inspection.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @title DSFile.createFileInterface
|
|
3
|
+
*
|
|
4
|
+
* Construire une référence de fichier sans accès au disque.
|
|
5
|
+
*/
|
|
6
|
+
import type * as DPath from "@duplojs/lang/path";
|
|
7
|
+
import * as DSFile from "@duplojs/server/file";
|
|
8
|
+
|
|
9
|
+
declare const path: string & DPath.Path;
|
|
10
|
+
|
|
11
|
+
const entry = DSFile.createFileInterface(path);
|
|
12
|
+
|
|
13
|
+
// La construction ne vérifie ni l’existence ni la nature de la ressource.
|
|
14
|
+
|
|
15
|
+
// Les méthodes de référence extraient les composants sans accès au disque.
|
|
16
|
+
const name = entry.getName();
|
|
17
|
+
const mimeType = entry.getMimeType();
|
|
18
|
+
|
|
19
|
+
// stat, exists et les opérations de déplacement consultent le système.
|
|
20
|
+
// rename, move et relocate retournent une nouvelle interface en cas de succès ;
|
|
21
|
+
// ils ne modifient pas le chemin de cette référence.
|
|
22
|
+
const metadata = await entry.stat();
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @title DSFile.createFolderInterface
|
|
3
|
+
*
|
|
4
|
+
* Construire une référence de dossier sans accès au disque.
|
|
5
|
+
*/
|
|
6
|
+
import type * as DPath from "@duplojs/lang/path";
|
|
7
|
+
import * as DSFile from "@duplojs/server/file";
|
|
8
|
+
|
|
9
|
+
declare const path: string & DPath.Path;
|
|
10
|
+
|
|
11
|
+
const entry = DSFile.createFolderInterface(path);
|
|
12
|
+
|
|
13
|
+
// La construction ne vérifie ni l’existence ni la nature de la ressource.
|
|
14
|
+
|
|
15
|
+
// Ces méthodes consultent le système de fichiers et retournent un Either.
|
|
16
|
+
const children = await entry.getChildren();
|
|
17
|
+
const traversal = await entry.walk({ recursive: true });
|
|
18
|
+
|
|
19
|
+
// Un déplacement ou renommage réussi retourne une nouvelle interface ;
|
|
20
|
+
// la référence initiale conserve son ancien chemin.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @title DSFile.createUnknownEntryInterface
|
|
3
|
+
*
|
|
4
|
+
* Construire une référence d’entrée de type inconnu sans accès au disque.
|
|
5
|
+
*/
|
|
6
|
+
import type * as DPath from "@duplojs/lang/path";
|
|
7
|
+
import * as DSFile from "@duplojs/server/file";
|
|
8
|
+
|
|
9
|
+
declare const path: string & DPath.Path;
|
|
10
|
+
|
|
11
|
+
const entry = DSFile.createUnknownEntryInterface(path);
|
|
12
|
+
|
|
13
|
+
// La construction ne vérifie ni l’existence ni la nature de la ressource.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @title DSFile.ensureDirectory
|
|
3
|
+
*
|
|
4
|
+
* Créer un dossier et ses parents si nécessaire.
|
|
5
|
+
*/
|
|
6
|
+
import type * as DPath from "@duplojs/lang/path";
|
|
7
|
+
import * as DSFile from "@duplojs/server/file";
|
|
8
|
+
import * as DEither from "@duplojs/lang/either";
|
|
9
|
+
import * as DPattern from "@duplojs/lang/pattern";
|
|
10
|
+
|
|
11
|
+
declare const path: string & DPath.Path;
|
|
12
|
+
|
|
13
|
+
const result = await DSFile.ensureDirectory(path);
|
|
14
|
+
|
|
15
|
+
// La réussite confirme que le dossier a été assuré.
|
|
16
|
+
|
|
17
|
+
// L’information du Left identifie l’opération ; sa valeur précise la cause.
|
|
18
|
+
if (DEither.isLeft(result)) {
|
|
19
|
+
const error = DEither.unwrapLeft(result);
|
|
20
|
+
|
|
21
|
+
const diagnosis = DPattern.matchWithErrorOtherwise(
|
|
22
|
+
error,
|
|
23
|
+
{
|
|
24
|
+
"file-system-ensure-directory-permission-denied": () => "access-denied",
|
|
25
|
+
"file-system-ensure-directory-no-space": () => "no-space",
|
|
26
|
+
},
|
|
27
|
+
(otherError) => otherError,
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Identifiants d’erreur déclarés pour cette opération :
|
|
32
|
+
// file-system-ensure-directory-permission-denied
|
|
33
|
+
// file-system-ensure-directory-not-directory
|
|
34
|
+
// file-system-ensure-directory-no-space
|
|
35
|
+
// file-system-ensure-directory-read-only
|
|
36
|
+
// file-system-ensure-directory-invalid-argument
|
|
37
|
+
// file-system-ensure-directory-too-many-open-files
|
|
38
|
+
// file-system-ensure-directory-busy
|
|
39
|
+
// file-system-ensure-directory-error
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @title DSFile.ensureFile
|
|
3
|
+
*
|
|
4
|
+
* Créer un fichier absent sans tronquer un fichier existant.
|
|
5
|
+
*/
|
|
6
|
+
import type * as DPath from "@duplojs/lang/path";
|
|
7
|
+
import * as DSFile from "@duplojs/server/file";
|
|
8
|
+
import * as DEither from "@duplojs/lang/either";
|
|
9
|
+
import * as DPattern from "@duplojs/lang/pattern";
|
|
10
|
+
|
|
11
|
+
declare const path: string & DPath.Path;
|
|
12
|
+
|
|
13
|
+
const result = await DSFile.ensureFile(path);
|
|
14
|
+
|
|
15
|
+
// Le dossier parent doit déjà exister.
|
|
16
|
+
|
|
17
|
+
// L’information du Left identifie l’opération ; sa valeur précise la cause.
|
|
18
|
+
if (DEither.isLeft(result)) {
|
|
19
|
+
const error = DEither.unwrapLeft(result);
|
|
20
|
+
|
|
21
|
+
const diagnosis = DPattern.matchWithErrorOtherwise(
|
|
22
|
+
error,
|
|
23
|
+
{
|
|
24
|
+
"file-system-ensure-file-permission-denied": () => "access-denied",
|
|
25
|
+
"file-system-ensure-file-no-space": () => "no-space",
|
|
26
|
+
},
|
|
27
|
+
(otherError) => otherError,
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Identifiants d’erreur déclarés pour cette opération :
|
|
32
|
+
// file-system-ensure-file-permission-denied
|
|
33
|
+
// file-system-ensure-file-is-directory
|
|
34
|
+
// file-system-ensure-file-not-directory
|
|
35
|
+
// file-system-ensure-file-no-space
|
|
36
|
+
// file-system-ensure-file-read-only
|
|
37
|
+
// file-system-ensure-file-invalid-argument
|
|
38
|
+
// file-system-ensure-file-too-many-open-files
|
|
39
|
+
// file-system-ensure-file-busy
|
|
40
|
+
// file-system-ensure-file-error
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @title DSFile.exists
|
|
3
|
+
*
|
|
4
|
+
* Vérifier l’accès à une entrée du système de fichiers.
|
|
5
|
+
*/
|
|
6
|
+
import type * as DPath from "@duplojs/lang/path";
|
|
7
|
+
import * as DSFile from "@duplojs/server/file";
|
|
8
|
+
import * as DEither from "@duplojs/lang/either";
|
|
9
|
+
import * as DPattern from "@duplojs/lang/pattern";
|
|
10
|
+
|
|
11
|
+
declare const path: string & DPath.Path;
|
|
12
|
+
|
|
13
|
+
const result = await DSFile.exists(path);
|
|
14
|
+
|
|
15
|
+
// Le résultat est un Either : un échec ne signifie pas nécessairement que l’entrée est absente.
|
|
16
|
+
|
|
17
|
+
// L’information du Left identifie l’opération ; sa valeur précise la cause.
|
|
18
|
+
if (DEither.isLeft(result)) {
|
|
19
|
+
const error = DEither.unwrapLeft(result);
|
|
20
|
+
|
|
21
|
+
const diagnosis = DPattern.matchWithErrorOtherwise(
|
|
22
|
+
error,
|
|
23
|
+
{
|
|
24
|
+
"file-system-exists-not-found": () => "missing",
|
|
25
|
+
"file-system-exists-permission-denied": () => "access-denied",
|
|
26
|
+
},
|
|
27
|
+
(otherError) => otherError,
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Identifiants d’erreur déclarés pour cette opération :
|
|
32
|
+
// file-system-exists-not-found
|
|
33
|
+
// file-system-exists-permission-denied
|
|
34
|
+
// file-system-exists-not-directory
|
|
35
|
+
// file-system-exists-too-many-open-files
|
|
36
|
+
// file-system-exists-error
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @title DSFile.link
|
|
3
|
+
*
|
|
4
|
+
* Créer un lien physique vers une entrée existante.
|
|
5
|
+
*/
|
|
6
|
+
import * as DCommon from "@duplojs/lang/common";
|
|
7
|
+
import type * as DPath from "@duplojs/lang/path";
|
|
8
|
+
import * as DSFile from "@duplojs/server/file";
|
|
9
|
+
import * as DEither from "@duplojs/lang/either";
|
|
10
|
+
import * as DPattern from "@duplojs/lang/pattern";
|
|
11
|
+
|
|
12
|
+
declare const source: string & DPath.Path;
|
|
13
|
+
declare const destination: string & DPath.Path;
|
|
14
|
+
|
|
15
|
+
// Appel direct
|
|
16
|
+
const result = await DSFile.link(source, destination);
|
|
17
|
+
|
|
18
|
+
// Forme curifiée
|
|
19
|
+
const pipedResult = await DCommon.pipe(
|
|
20
|
+
source,
|
|
21
|
+
DSFile.link(destination),
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
// Les résultats dépendent de l'état du système de fichiers et peuvent échouer.
|
|
25
|
+
|
|
26
|
+
// L’information du Left identifie l’opération ; sa valeur précise la cause.
|
|
27
|
+
if (DEither.isLeft(result)) {
|
|
28
|
+
const error = DEither.unwrapLeft(result);
|
|
29
|
+
|
|
30
|
+
const diagnosis = DPattern.matchWithErrorOtherwise(
|
|
31
|
+
error,
|
|
32
|
+
{
|
|
33
|
+
"file-system-link-not-found": () => "missing",
|
|
34
|
+
"file-system-link-permission-denied": () => "access-denied",
|
|
35
|
+
},
|
|
36
|
+
(otherError) => otherError,
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Identifiants d’erreur déclarés pour cette opération :
|
|
41
|
+
// file-system-link-not-found
|
|
42
|
+
// file-system-link-permission-denied
|
|
43
|
+
// file-system-link-already-exists
|
|
44
|
+
// file-system-link-not-directory
|
|
45
|
+
// file-system-link-no-space
|
|
46
|
+
// file-system-link-read-only
|
|
47
|
+
// file-system-link-invalid-argument
|
|
48
|
+
// file-system-link-too-many-open-files
|
|
49
|
+
// file-system-link-busy
|
|
50
|
+
// file-system-link-cross-device
|
|
51
|
+
// file-system-link-error
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @title DSFile.linkStat
|
|
3
|
+
*
|
|
4
|
+
* Lire les métadonnées d’un lien lui-même.
|
|
5
|
+
*/
|
|
6
|
+
import type * as DPath from "@duplojs/lang/path";
|
|
7
|
+
import * as DSFile from "@duplojs/server/file";
|
|
8
|
+
import * as DEither from "@duplojs/lang/either";
|
|
9
|
+
import * as DPattern from "@duplojs/lang/pattern";
|
|
10
|
+
|
|
11
|
+
declare const path: string & DPath.Path;
|
|
12
|
+
|
|
13
|
+
const result = await DSFile.linkStat(path);
|
|
14
|
+
|
|
15
|
+
// Contrairement à stat, cette opération inspecte le lien symbolique lui-même.
|
|
16
|
+
|
|
17
|
+
// L’information du Left identifie l’opération ; sa valeur précise la cause.
|
|
18
|
+
if (DEither.isLeft(result)) {
|
|
19
|
+
const error = DEither.unwrapLeft(result);
|
|
20
|
+
|
|
21
|
+
const diagnosis = DPattern.matchWithErrorOtherwise(
|
|
22
|
+
error,
|
|
23
|
+
{
|
|
24
|
+
"file-system-link-stat-not-found": () => "missing",
|
|
25
|
+
"file-system-link-stat-permission-denied": () => "access-denied",
|
|
26
|
+
},
|
|
27
|
+
(otherError) => otherError,
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Identifiants d’erreur déclarés pour cette opération :
|
|
32
|
+
// file-system-link-stat-not-found
|
|
33
|
+
// file-system-link-stat-permission-denied
|
|
34
|
+
// file-system-link-stat-not-directory
|
|
35
|
+
// file-system-link-stat-too-many-open-files
|
|
36
|
+
// file-system-link-stat-busy
|
|
37
|
+
// file-system-link-stat-error
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @title DSFile.makeDirectory
|
|
3
|
+
*
|
|
4
|
+
* Créer un dossier, éventuellement avec ses parents.
|
|
5
|
+
*/
|
|
6
|
+
import type * as DPath from "@duplojs/lang/path";
|
|
7
|
+
import * as DSFile from "@duplojs/server/file";
|
|
8
|
+
import * as DEither from "@duplojs/lang/either";
|
|
9
|
+
import * as DPattern from "@duplojs/lang/pattern";
|
|
10
|
+
|
|
11
|
+
declare const path: string & DPath.Path;
|
|
12
|
+
|
|
13
|
+
const result = await DSFile.makeDirectory(path, { recursive: true });
|
|
14
|
+
|
|
15
|
+
// Le Left décrit un éventuel échec de création.
|
|
16
|
+
|
|
17
|
+
// L’information du Left identifie l’opération ; sa valeur précise la cause.
|
|
18
|
+
if (DEither.isLeft(result)) {
|
|
19
|
+
const error = DEither.unwrapLeft(result);
|
|
20
|
+
|
|
21
|
+
const diagnosis = DPattern.matchWithErrorOtherwise(
|
|
22
|
+
error,
|
|
23
|
+
{
|
|
24
|
+
"file-system-make-directory-not-found": () => "missing",
|
|
25
|
+
"file-system-make-directory-permission-denied": () => "access-denied",
|
|
26
|
+
},
|
|
27
|
+
(otherError) => otherError,
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Identifiants d’erreur déclarés pour cette opération :
|
|
32
|
+
// file-system-make-directory-not-found
|
|
33
|
+
// file-system-make-directory-permission-denied
|
|
34
|
+
// file-system-make-directory-already-exists
|
|
35
|
+
// file-system-make-directory-not-directory
|
|
36
|
+
// file-system-make-directory-no-space
|
|
37
|
+
// file-system-make-directory-read-only
|
|
38
|
+
// file-system-make-directory-invalid-argument
|
|
39
|
+
// file-system-make-directory-too-many-open-files
|
|
40
|
+
// file-system-make-directory-busy
|
|
41
|
+
// file-system-make-directory-error
|