@projitect/cli-internals 0.0.0-stage → 1.0.1
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/LICENSE +21 -0
- package/dist/applier.d.ts +12 -0
- package/dist/applier.d.ts.map +1 -0
- package/dist/applier.js +69 -0
- package/dist/applier.js.map +1 -0
- package/dist/commands/add.d.ts +34 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +64 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/build.d.ts +39 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +108 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/dispatch.d.ts +5 -0
- package/dist/commands/dispatch.d.ts.map +1 -0
- package/dist/commands/dispatch.js +211 -0
- package/dist/commands/dispatch.js.map +1 -0
- package/dist/commands/explain.d.ts +10 -0
- package/dist/commands/explain.d.ts.map +1 -0
- package/dist/commands/explain.js +46 -0
- package/dist/commands/explain.js.map +1 -0
- package/dist/commands/init.d.ts +34 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +153 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/inspect-json.d.ts +51 -0
- package/dist/commands/inspect-json.d.ts.map +1 -0
- package/dist/commands/inspect-json.js +58 -0
- package/dist/commands/inspect-json.js.map +1 -0
- package/dist/commands/inspect.d.ts +41 -0
- package/dist/commands/inspect.d.ts.map +1 -0
- package/dist/commands/inspect.js +74 -0
- package/dist/commands/inspect.js.map +1 -0
- package/dist/commands/remodel.d.ts +22 -0
- package/dist/commands/remodel.d.ts.map +1 -0
- package/dist/commands/remodel.js +49 -0
- package/dist/commands/remodel.js.map +1 -0
- package/dist/config-cascade.d.ts +25 -0
- package/dist/config-cascade.d.ts.map +1 -0
- package/dist/config-cascade.js +45 -0
- package/dist/config-cascade.js.map +1 -0
- package/dist/differ.d.ts +31 -0
- package/dist/differ.d.ts.map +1 -0
- package/dist/differ.js +134 -0
- package/dist/differ.js.map +1 -0
- package/dist/edit-pjt.d.ts +19 -0
- package/dist/edit-pjt.d.ts.map +1 -0
- package/dist/edit-pjt.js +40 -0
- package/dist/edit-pjt.js.map +1 -0
- package/dist/filesystem-impl.d.ts +25 -0
- package/dist/filesystem-impl.d.ts.map +1 -0
- package/dist/filesystem-impl.js +153 -0
- package/dist/filesystem-impl.js.map +1 -0
- package/dist/git.d.ts +29 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +63 -0
- package/dist/git.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/ipc/client.d.ts +11 -0
- package/dist/ipc/client.d.ts.map +1 -0
- package/dist/ipc/client.js +45 -0
- package/dist/ipc/client.js.map +1 -0
- package/dist/ipc/index.d.ts +5 -0
- package/dist/ipc/index.d.ts.map +1 -0
- package/dist/ipc/index.js +5 -0
- package/dist/ipc/index.js.map +1 -0
- package/dist/ipc/protocol.d.ts +251 -0
- package/dist/ipc/protocol.d.ts.map +1 -0
- package/dist/ipc/protocol.js +41 -0
- package/dist/ipc/protocol.js.map +1 -0
- package/dist/ipc/server.d.ts +9 -0
- package/dist/ipc/server.d.ts.map +1 -0
- package/dist/ipc/server.js +23 -0
- package/dist/ipc/server.js.map +1 -0
- package/dist/ipc/transport.d.ts +12 -0
- package/dist/ipc/transport.d.ts.map +1 -0
- package/dist/ipc/transport.js +19 -0
- package/dist/ipc/transport.js.map +1 -0
- package/dist/loader.d.ts +45 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +65 -0
- package/dist/loader.js.map +1 -0
- package/dist/lockfile.d.ts +22 -0
- package/dist/lockfile.d.ts.map +1 -0
- package/dist/lockfile.js +59 -0
- package/dist/lockfile.js.map +1 -0
- package/dist/permissions.d.ts +20 -0
- package/dist/permissions.d.ts.map +1 -0
- package/dist/permissions.js +86 -0
- package/dist/permissions.js.map +1 -0
- package/dist/plan.d.ts +278 -0
- package/dist/plan.d.ts.map +1 -0
- package/dist/plan.js +212 -0
- package/dist/plan.js.map +1 -0
- package/dist/platform/file-system.d.ts +3 -0
- package/dist/platform/file-system.d.ts.map +1 -0
- package/dist/platform/file-system.js +109 -0
- package/dist/platform/file-system.js.map +1 -0
- package/dist/platform/index.d.ts +17 -0
- package/dist/platform/index.d.ts.map +1 -0
- package/dist/platform/index.js +20 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/platform/process-runner.d.ts +41 -0
- package/dist/platform/process-runner.d.ts.map +1 -0
- package/dist/platform/process-runner.js +120 -0
- package/dist/platform/process-runner.js.map +1 -0
- package/dist/platform/stdio.d.ts +9 -0
- package/dist/platform/stdio.d.ts.map +1 -0
- package/dist/platform/stdio.js +11 -0
- package/dist/platform/stdio.js.map +1 -0
- package/dist/platform/terminal.d.ts +3 -0
- package/dist/platform/terminal.d.ts.map +1 -0
- package/dist/platform/terminal.js +81 -0
- package/dist/platform/terminal.js.map +1 -0
- package/dist/pm.d.ts +36 -0
- package/dist/pm.d.ts.map +1 -0
- package/dist/pm.js +95 -0
- package/dist/pm.js.map +1 -0
- package/dist/post-apply.d.ts +20 -0
- package/dist/post-apply.d.ts.map +1 -0
- package/dist/post-apply.js +29 -0
- package/dist/post-apply.js.map +1 -0
- package/dist/project-file.d.ts +8 -0
- package/dist/project-file.d.ts.map +1 -0
- package/dist/project-file.js +12 -0
- package/dist/project-file.js.map +1 -0
- package/dist/region.d.ts +105 -0
- package/dist/region.d.ts.map +1 -0
- package/dist/region.js +94 -0
- package/dist/region.js.map +1 -0
- package/dist/remover.d.ts +16 -0
- package/dist/remover.d.ts.map +1 -0
- package/dist/remover.js +88 -0
- package/dist/remover.js.map +1 -0
- package/package.json +52 -3
- package/src/applier.ts +91 -0
- package/src/commands/add.ts +88 -0
- package/src/commands/build.ts +156 -0
- package/src/commands/dispatch.ts +345 -0
- package/src/commands/explain.ts +81 -0
- package/src/commands/init.ts +233 -0
- package/src/commands/inspect-json.ts +68 -0
- package/src/commands/inspect.ts +106 -0
- package/src/commands/remodel.ts +72 -0
- package/src/config-cascade.ts +60 -0
- package/src/differ.ts +188 -0
- package/src/edit-pjt.ts +56 -0
- package/src/filesystem-impl.ts +230 -0
- package/src/git.ts +87 -0
- package/src/index.ts +54 -0
- package/src/ipc/client.ts +108 -0
- package/src/ipc/index.ts +12 -0
- package/src/ipc/protocol.ts +48 -0
- package/src/ipc/server.ts +62 -0
- package/src/ipc/transport.ts +28 -0
- package/src/loader.ts +115 -0
- package/src/lockfile.ts +81 -0
- package/src/permissions.ts +106 -0
- package/src/plan.ts +459 -0
- package/src/platform/file-system.ts +155 -0
- package/src/platform/index.ts +26 -0
- package/src/platform/process-runner.ts +150 -0
- package/src/platform/stdio.ts +11 -0
- package/src/platform/terminal.ts +89 -0
- package/src/pm.ts +163 -0
- package/src/post-apply.ts +45 -0
- package/src/project-file.ts +15 -0
- package/src/region.ts +139 -0
- package/src/remover.ts +127 -0
- package/README.md +0 -3
package/src/remover.ts
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { Array, Effect, Match, Option, Predicate } from "effect"
|
|
2
|
+
import { PredicateX, RecordX, StringX } from "@nunofyobiz/effect-extras"
|
|
3
|
+
import { BlueprintFileSystem } from "@projitect/core"
|
|
4
|
+
import type { Errors, PjtLock } from "@projitect/core"
|
|
5
|
+
import { readIfExists } from "./project-file.js"
|
|
6
|
+
import { findRegion } from "./region.js"
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Apply removal operations through the project `BlueprintFileSystem`. Used by `pjt remodel` / `pjt build` after a blueprint
|
|
10
|
+
* leaves `.pjt.ts` — the operations come from the diff between the previous lockfile and the
|
|
11
|
+
* current blueprint set.
|
|
12
|
+
*
|
|
13
|
+
* Returns the list of paths actually mutated.
|
|
14
|
+
*/
|
|
15
|
+
export const applyRemovals = (params: {
|
|
16
|
+
readonly removals: readonly PjtLock.LockOperation[]
|
|
17
|
+
}): Effect.Effect<readonly string[], RemoveError, BlueprintFileSystem> =>
|
|
18
|
+
Effect.forEach(params.removals, (op) =>
|
|
19
|
+
Effect.map(applyOne(op), (mutated) => (mutated ? Option.some(op.path) : Option.none<string>())),
|
|
20
|
+
).pipe(Effect.map(Array.getSomes))
|
|
21
|
+
|
|
22
|
+
type RemoveError =
|
|
23
|
+
| Errors.RegionMissingEnd
|
|
24
|
+
| Errors.RegionDuplicate
|
|
25
|
+
| Errors.FsWriteFailed
|
|
26
|
+
| Errors.FsPermissionDenied
|
|
27
|
+
|
|
28
|
+
const applyOne = (
|
|
29
|
+
op: PjtLock.LockOperation,
|
|
30
|
+
): Effect.Effect<boolean, RemoveError, BlueprintFileSystem> =>
|
|
31
|
+
Match.valueTags(op, {
|
|
32
|
+
Region: (region) => removeRegion(region),
|
|
33
|
+
Merge: (merge) => removeMergeKeys(merge.path, merge.ownedKeys),
|
|
34
|
+
Owned: (owned) => removeFile(owned.path, owned.ownedDir),
|
|
35
|
+
// Seed is write-once; we never delete the file when a seed blueprint leaves.
|
|
36
|
+
Seed: () => Effect.succeed(false),
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
const removeRegion = (
|
|
40
|
+
op: PjtLock.LockRegionOp,
|
|
41
|
+
): Effect.Effect<boolean, RemoveError, BlueprintFileSystem> =>
|
|
42
|
+
Effect.gen(function* () {
|
|
43
|
+
const fs = yield* BlueprintFileSystem
|
|
44
|
+
const current = yield* readIfExists(op.path)
|
|
45
|
+
if (current === null) {
|
|
46
|
+
return false
|
|
47
|
+
}
|
|
48
|
+
const found = yield* findRegion({
|
|
49
|
+
fileContent: current,
|
|
50
|
+
ownerId: op.ownerId,
|
|
51
|
+
commentPrefix: op.commentPrefix,
|
|
52
|
+
commentSuffix: op.commentSuffix ?? "",
|
|
53
|
+
path: op.path,
|
|
54
|
+
})
|
|
55
|
+
if (found._tag === "Absent") {
|
|
56
|
+
return false
|
|
57
|
+
}
|
|
58
|
+
const next = StringX.replaceLineRange(current, found.startLine, found.endLine, [])
|
|
59
|
+
yield* fs.writeFile(op.path, next)
|
|
60
|
+
return true
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
const removeMergeKeys = (
|
|
64
|
+
file: string,
|
|
65
|
+
keys: readonly string[],
|
|
66
|
+
): Effect.Effect<boolean, RemoveError, BlueprintFileSystem> =>
|
|
67
|
+
Effect.gen(function* () {
|
|
68
|
+
const fs = yield* BlueprintFileSystem
|
|
69
|
+
const raw = yield* readIfExists(file)
|
|
70
|
+
if (raw === null) {
|
|
71
|
+
return false
|
|
72
|
+
}
|
|
73
|
+
const parsed = yield* Effect.try(() => JSON.parse(raw) as unknown).pipe(Effect.option)
|
|
74
|
+
if (Option.isNone(parsed) || !PredicateX.unsafeIsRecord(parsed.value)) {
|
|
75
|
+
return false
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Fold each dotted key out of the tree, tracking whether anything actually changed.
|
|
79
|
+
const seed: { readonly tree: unknown; readonly mutated: boolean } = {
|
|
80
|
+
tree: parsed.value,
|
|
81
|
+
mutated: false,
|
|
82
|
+
}
|
|
83
|
+
const result = Array.reduce(keys, seed, (state, key) =>
|
|
84
|
+
Option.match(RecordX.deleteByPath(state.tree, key.split(".")), {
|
|
85
|
+
onSome: (tree) => ({ tree, mutated: true }),
|
|
86
|
+
onNone: () => state,
|
|
87
|
+
}),
|
|
88
|
+
)
|
|
89
|
+
if (!result.mutated) {
|
|
90
|
+
return false
|
|
91
|
+
}
|
|
92
|
+
yield* fs.writeFile(file, `${JSON.stringify(result.tree, null, 2)}\n`)
|
|
93
|
+
return true
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
const removeFile = (
|
|
97
|
+
file: string,
|
|
98
|
+
ownedDir: string | undefined,
|
|
99
|
+
): Effect.Effect<boolean, never, BlueprintFileSystem> =>
|
|
100
|
+
Effect.gen(function* () {
|
|
101
|
+
const fs = yield* BlueprintFileSystem
|
|
102
|
+
yield* fs.remove(file)
|
|
103
|
+
if (Predicate.isNotUndefined(ownedDir)) {
|
|
104
|
+
yield* pruneEmptyDirs(parentDir(file), ownedDir)
|
|
105
|
+
}
|
|
106
|
+
return true
|
|
107
|
+
}).pipe(Effect.orElseSucceed(() => false))
|
|
108
|
+
|
|
109
|
+
// Project-relative paths use `/`; the parent of a top-level name is the project root (`""`).
|
|
110
|
+
const parentDir = (file: string): string => file.slice(0, Math.max(0, file.lastIndexOf("/")))
|
|
111
|
+
|
|
112
|
+
/** Remove empty directories upward from `dir` to `ownedDir` inclusive, never above it. */
|
|
113
|
+
const pruneEmptyDirs = (
|
|
114
|
+
dir: string,
|
|
115
|
+
ownedDir: string,
|
|
116
|
+
): Effect.Effect<void, never, BlueprintFileSystem> =>
|
|
117
|
+
Effect.gen(function* () {
|
|
118
|
+
if (dir !== ownedDir && !dir.startsWith(`${ownedDir}/`)) {
|
|
119
|
+
return
|
|
120
|
+
}
|
|
121
|
+
const fs = yield* BlueprintFileSystem
|
|
122
|
+
// Atomic: fails (and stops the climb) if `dir` holds any entry, however recently it appeared.
|
|
123
|
+
yield* fs.removeEmptyDir(dir)
|
|
124
|
+
if (dir !== ownedDir) {
|
|
125
|
+
yield* pruneEmptyDirs(parentDir(dir), ownedDir)
|
|
126
|
+
}
|
|
127
|
+
}).pipe(Effect.orElseSucceed(() => undefined))
|
package/README.md
DELETED