@k8ts/instruments 0.1.0

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.
Files changed (307) hide show
  1. package/LICENSE.md +7 -0
  2. package/README.md +3 -0
  3. package/dist/_embedder/base.d.ts +11 -0
  4. package/dist/_embedder/base.d.ts.map +1 -0
  5. package/dist/_embedder/base.js +39 -0
  6. package/dist/_embedder/base.js.map +1 -0
  7. package/dist/_embedder/index.d.ts +2 -0
  8. package/dist/_embedder/index.d.ts.map +1 -0
  9. package/dist/_embedder/index.js +18 -0
  10. package/dist/_embedder/index.js.map +1 -0
  11. package/dist/_string/index.d.ts +6 -0
  12. package/dist/_string/index.d.ts.map +1 -0
  13. package/dist/_string/index.js +22 -0
  14. package/dist/_string/index.js.map +1 -0
  15. package/dist/_string/markers.d.ts +3 -0
  16. package/dist/_string/markers.d.ts.map +1 -0
  17. package/dist/_string/markers.js +48 -0
  18. package/dist/_string/markers.js.map +1 -0
  19. package/dist/_string/post-processor.d.ts +7 -0
  20. package/dist/_string/post-processor.d.ts.map +1 -0
  21. package/dist/_string/post-processor.js +30 -0
  22. package/dist/_string/post-processor.js.map +1 -0
  23. package/dist/_string/pretty-objects.d.ts +27 -0
  24. package/dist/_string/pretty-objects.d.ts.map +1 -0
  25. package/dist/_string/pretty-objects.js +192 -0
  26. package/dist/_string/pretty-objects.js.map +1 -0
  27. package/dist/_string/pretty-print.d.ts +2 -0
  28. package/dist/_string/pretty-print.d.ts.map +1 -0
  29. package/dist/_string/pretty-print.js +27 -0
  30. package/dist/_string/pretty-print.js.map +1 -0
  31. package/dist/_string/super-script.d.ts +2 -0
  32. package/dist/_string/super-script.d.ts.map +1 -0
  33. package/dist/_string/super-script.js +20 -0
  34. package/dist/_string/super-script.js.map +1 -0
  35. package/dist/api-kind/index.d.ts +43 -0
  36. package/dist/api-kind/index.d.ts.map +1 -0
  37. package/dist/api-kind/index.js +102 -0
  38. package/dist/api-kind/index.js.map +1 -0
  39. package/dist/cmd/cli-command.d.ts +23 -0
  40. package/dist/cmd/cli-command.d.ts.map +1 -0
  41. package/dist/cmd/cli-command.js +73 -0
  42. package/dist/cmd/cli-command.js.map +1 -0
  43. package/dist/cmd/cli-term.d.ts +25 -0
  44. package/dist/cmd/cli-term.d.ts.map +1 -0
  45. package/dist/cmd/cli-term.js +55 -0
  46. package/dist/cmd/cli-term.js.map +1 -0
  47. package/dist/cmd/index.d.ts +3 -0
  48. package/dist/cmd/index.d.ts.map +1 -0
  49. package/dist/cmd/index.js +7 -0
  50. package/dist/cmd/index.js.map +1 -0
  51. package/dist/cmd/types.d.ts +5 -0
  52. package/dist/cmd/types.d.ts.map +1 -0
  53. package/dist/cmd/types.js +3 -0
  54. package/dist/cmd/types.js.map +1 -0
  55. package/dist/displayers/displayers.d.ts +33 -0
  56. package/dist/displayers/displayers.d.ts.map +1 -0
  57. package/dist/displayers/displayers.js +129 -0
  58. package/dist/displayers/displayers.js.map +1 -0
  59. package/dist/displayers/index.d.ts +2 -0
  60. package/dist/displayers/index.d.ts.map +1 -0
  61. package/dist/displayers/index.js +18 -0
  62. package/dist/displayers/index.js.map +1 -0
  63. package/dist/env/env.d.ts +20 -0
  64. package/dist/env/env.d.ts.map +1 -0
  65. package/dist/env/env.js +68 -0
  66. package/dist/env/env.js.map +1 -0
  67. package/dist/env/index.d.ts +3 -0
  68. package/dist/env/index.d.ts.map +1 -0
  69. package/dist/env/index.js +7 -0
  70. package/dist/env/index.js.map +1 -0
  71. package/dist/env/types.d.ts +4 -0
  72. package/dist/env/types.d.ts.map +1 -0
  73. package/dist/env/types.js +3 -0
  74. package/dist/env/types.js.map +1 -0
  75. package/dist/env/validate-name.d.ts +2 -0
  76. package/dist/env/validate-name.d.ts.map +1 -0
  77. package/dist/env/validate-name.js +12 -0
  78. package/dist/env/validate-name.js.map +1 -0
  79. package/dist/error.d.ts +8 -0
  80. package/dist/error.d.ts.map +1 -0
  81. package/dist/error.js +20 -0
  82. package/dist/error.js.map +1 -0
  83. package/dist/forward-exports/delayed-exports.d.ts +18 -0
  84. package/dist/forward-exports/delayed-exports.d.ts.map +1 -0
  85. package/dist/forward-exports/delayed-exports.js +119 -0
  86. package/dist/forward-exports/delayed-exports.js.map +1 -0
  87. package/dist/forward-exports/index.d.ts +2 -0
  88. package/dist/forward-exports/index.d.ts.map +1 -0
  89. package/dist/forward-exports/index.js +18 -0
  90. package/dist/forward-exports/index.js.map +1 -0
  91. package/dist/graph/base-node.d.ts +34 -0
  92. package/dist/graph/base-node.d.ts.map +1 -0
  93. package/dist/graph/base-node.js +102 -0
  94. package/dist/graph/base-node.js.map +1 -0
  95. package/dist/graph/base-origin-entity.d.ts +19 -0
  96. package/dist/graph/base-origin-entity.d.ts.map +1 -0
  97. package/dist/graph/base-origin-entity.js +105 -0
  98. package/dist/graph/base-origin-entity.js.map +1 -0
  99. package/dist/graph/dependencies.d.ts +12 -0
  100. package/dist/graph/dependencies.d.ts.map +1 -0
  101. package/dist/graph/dependencies.js +82 -0
  102. package/dist/graph/dependencies.js.map +1 -0
  103. package/dist/graph/index.d.ts +7 -0
  104. package/dist/graph/index.d.ts.map +1 -0
  105. package/dist/graph/index.js +23 -0
  106. package/dist/graph/index.js.map +1 -0
  107. package/dist/graph/origin-node.d.ts +32 -0
  108. package/dist/graph/origin-node.d.ts.map +1 -0
  109. package/dist/graph/origin-node.js +161 -0
  110. package/dist/graph/origin-node.js.map +1 -0
  111. package/dist/graph/relations.d.ts +26 -0
  112. package/dist/graph/relations.d.ts.map +1 -0
  113. package/dist/graph/relations.js +38 -0
  114. package/dist/graph/relations.js.map +1 -0
  115. package/dist/graph/resource-node.d.ts +28 -0
  116. package/dist/graph/resource-node.d.ts.map +1 -0
  117. package/dist/graph/resource-node.js +144 -0
  118. package/dist/graph/resource-node.js.map +1 -0
  119. package/dist/image/family.d.ts +26 -0
  120. package/dist/image/family.d.ts.map +1 -0
  121. package/dist/image/family.js +63 -0
  122. package/dist/image/family.js.map +1 -0
  123. package/dist/image/index.d.ts +2 -0
  124. package/dist/image/index.d.ts.map +1 -0
  125. package/dist/image/index.js +9 -0
  126. package/dist/image/index.js.map +1 -0
  127. package/dist/index.d.ts +19 -0
  128. package/dist/index.d.ts.map +1 -0
  129. package/dist/index.js +35 -0
  130. package/dist/index.js.map +1 -0
  131. package/dist/kind-map/index.d.ts +44 -0
  132. package/dist/kind-map/index.d.ts.map +1 -0
  133. package/dist/kind-map/index.js +123 -0
  134. package/dist/kind-map/index.js.map +1 -0
  135. package/dist/manifest/index.d.ts +46 -0
  136. package/dist/manifest/index.d.ts.map +1 -0
  137. package/dist/manifest/index.js +21 -0
  138. package/dist/manifest/index.js.map +1 -0
  139. package/dist/manifest/manifest-builder.d.ts +45 -0
  140. package/dist/manifest/manifest-builder.d.ts.map +1 -0
  141. package/dist/manifest/manifest-builder.js +66 -0
  142. package/dist/manifest/manifest-builder.js.map +1 -0
  143. package/dist/ports/error.d.ts +5 -0
  144. package/dist/ports/error.d.ts.map +1 -0
  145. package/dist/ports/error.js +13 -0
  146. package/dist/ports/error.js.map +1 -0
  147. package/dist/ports/index.d.ts +7 -0
  148. package/dist/ports/index.d.ts.map +1 -0
  149. package/dist/ports/index.js +13 -0
  150. package/dist/ports/index.js.map +1 -0
  151. package/dist/ports/map.d.ts +13 -0
  152. package/dist/ports/map.d.ts.map +1 -0
  153. package/dist/ports/map.js +38 -0
  154. package/dist/ports/map.js.map +1 -0
  155. package/dist/ports/set.d.ts +18 -0
  156. package/dist/ports/set.d.ts.map +1 -0
  157. package/dist/ports/set.js +60 -0
  158. package/dist/ports/set.js.map +1 -0
  159. package/dist/ports/tools/entry.d.ts +6 -0
  160. package/dist/ports/tools/entry.d.ts.map +1 -0
  161. package/dist/ports/tools/entry.js +36 -0
  162. package/dist/ports/tools/entry.js.map +1 -0
  163. package/dist/ports/tools/parse.d.ts +3 -0
  164. package/dist/ports/tools/parse.d.ts.map +1 -0
  165. package/dist/ports/tools/parse.js +35 -0
  166. package/dist/ports/tools/parse.js.map +1 -0
  167. package/dist/ports/types.d.ts +37 -0
  168. package/dist/ports/types.d.ts.map +1 -0
  169. package/dist/ports/types.js +3 -0
  170. package/dist/ports/types.js.map +1 -0
  171. package/dist/producer/index.d.ts +2 -0
  172. package/dist/producer/index.d.ts.map +1 -0
  173. package/dist/producer/index.js +18 -0
  174. package/dist/producer/index.js.map +1 -0
  175. package/dist/producer/producer.d.ts +6 -0
  176. package/dist/producer/producer.d.ts.map +1 -0
  177. package/dist/producer/producer.js +13 -0
  178. package/dist/producer/producer.js.map +1 -0
  179. package/dist/ref-key/index.d.ts +2 -0
  180. package/dist/ref-key/index.d.ts.map +1 -0
  181. package/dist/ref-key/index.js +18 -0
  182. package/dist/ref-key/index.js.map +1 -0
  183. package/dist/ref-key/ref-key.d.ts +23 -0
  184. package/dist/ref-key/ref-key.d.ts.map +1 -0
  185. package/dist/ref-key/ref-key.js +67 -0
  186. package/dist/ref-key/ref-key.js.map +1 -0
  187. package/dist/reference/forward-ref.d.ts +22 -0
  188. package/dist/reference/forward-ref.d.ts.map +1 -0
  189. package/dist/reference/forward-ref.js +126 -0
  190. package/dist/reference/forward-ref.js.map +1 -0
  191. package/dist/reference/index.d.ts +4 -0
  192. package/dist/reference/index.d.ts.map +1 -0
  193. package/dist/reference/index.js +8 -0
  194. package/dist/reference/index.js.map +1 -0
  195. package/dist/reference/refable.d.ts +12 -0
  196. package/dist/reference/refable.d.ts.map +1 -0
  197. package/dist/reference/refable.js +3 -0
  198. package/dist/reference/refable.js.map +1 -0
  199. package/dist/resources/index.d.ts +3 -0
  200. package/dist/resources/index.d.ts.map +1 -0
  201. package/dist/resources/index.js +19 -0
  202. package/dist/resources/index.js.map +1 -0
  203. package/dist/resources/objects.d.ts +22 -0
  204. package/dist/resources/objects.d.ts.map +1 -0
  205. package/dist/resources/objects.js +93 -0
  206. package/dist/resources/objects.js.map +1 -0
  207. package/dist/resources/parser.d.ts +4 -0
  208. package/dist/resources/parser.d.ts.map +1 -0
  209. package/dist/resources/parser.js +21 -0
  210. package/dist/resources/parser.js.map +1 -0
  211. package/dist/resources/types.d.ts +18 -0
  212. package/dist/resources/types.d.ts.map +1 -0
  213. package/dist/resources/types.js +3 -0
  214. package/dist/resources/types.js.map +1 -0
  215. package/dist/src.tsbuildinfo +1 -0
  216. package/dist/test.tsbuildinfo +1 -0
  217. package/dist/tracing/git.d.ts +19 -0
  218. package/dist/tracing/git.d.ts.map +1 -0
  219. package/dist/tracing/git.js +45 -0
  220. package/dist/tracing/git.js.map +1 -0
  221. package/dist/tracing/index.d.ts +4 -0
  222. package/dist/tracing/index.d.ts.map +1 -0
  223. package/dist/tracing/index.js +20 -0
  224. package/dist/tracing/index.js.map +1 -0
  225. package/dist/tracing/trace.d.ts +11 -0
  226. package/dist/tracing/trace.d.ts.map +1 -0
  227. package/dist/tracing/trace.js +27 -0
  228. package/dist/tracing/trace.js.map +1 -0
  229. package/dist/tracing/traced.d.ts +4 -0
  230. package/dist/tracing/traced.d.ts.map +1 -0
  231. package/dist/tracing/traced.js +6 -0
  232. package/dist/tracing/traced.js.map +1 -0
  233. package/dist/units/index.d.ts +3 -0
  234. package/dist/units/index.d.ts.map +1 -0
  235. package/dist/units/index.js +22 -0
  236. package/dist/units/index.js.map +1 -0
  237. package/dist/units/unit-parser.d.ts +19 -0
  238. package/dist/units/unit-parser.d.ts.map +1 -0
  239. package/dist/units/unit-parser.js +53 -0
  240. package/dist/units/unit-parser.js.map +1 -0
  241. package/dist/units/units.d.ts +37 -0
  242. package/dist/units/units.d.ts.map +1 -0
  243. package/dist/units/units.js +36 -0
  244. package/dist/units/units.js.map +1 -0
  245. package/package.json +89 -0
  246. package/src/_embedder/base.ts +42 -0
  247. package/src/_embedder/index.ts +1 -0
  248. package/src/_string/index.ts +5 -0
  249. package/src/_string/markers.ts +47 -0
  250. package/src/_string/post-processor.ts +25 -0
  251. package/src/_string/pretty-objects.ts +65 -0
  252. package/src/_string/pretty-print.ts +24 -0
  253. package/src/_string/super-script.ts +17 -0
  254. package/src/api-kind/index.ts +134 -0
  255. package/src/cmd/cli-command.ts +89 -0
  256. package/src/cmd/cli-term.ts +60 -0
  257. package/src/cmd/index.ts +2 -0
  258. package/src/cmd/types.ts +4 -0
  259. package/src/displayers/displayers.ts +147 -0
  260. package/src/displayers/index.ts +1 -0
  261. package/src/env/env.ts +74 -0
  262. package/src/env/index.ts +2 -0
  263. package/src/env/types.ts +7 -0
  264. package/src/env/validate-name.ts +10 -0
  265. package/src/error.ts +15 -0
  266. package/src/forward-exports/delayed-exports.ts +155 -0
  267. package/src/forward-exports/index.ts +1 -0
  268. package/src/graph/base-node.ts +125 -0
  269. package/src/graph/base-origin-entity.ts +44 -0
  270. package/src/graph/dependencies.ts +27 -0
  271. package/src/graph/index.ts +6 -0
  272. package/src/graph/origin-node.ts +118 -0
  273. package/src/graph/relations.ts +62 -0
  274. package/src/graph/resource-node.ts +104 -0
  275. package/src/image/family.ts +71 -0
  276. package/src/image/index.ts +1 -0
  277. package/src/index.ts +18 -0
  278. package/src/kind-map/index.ts +150 -0
  279. package/src/manifest/index.ts +53 -0
  280. package/src/manifest/manifest-builder.ts +98 -0
  281. package/src/ports/error.ts +8 -0
  282. package/src/ports/index.ts +8 -0
  283. package/src/ports/map.ts +41 -0
  284. package/src/ports/set.ts +79 -0
  285. package/src/ports/tools/entry.ts +43 -0
  286. package/src/ports/tools/parse.ts +40 -0
  287. package/src/ports/types.ts +42 -0
  288. package/src/producer/index.ts +1 -0
  289. package/src/producer/producer.ts +18 -0
  290. package/src/ref-key/index.ts +1 -0
  291. package/src/ref-key/ref-key.ts +76 -0
  292. package/src/reference/forward-ref.ts +122 -0
  293. package/src/reference/index.ts +3 -0
  294. package/src/reference/refable.ts +11 -0
  295. package/src/resources/index.ts +2 -0
  296. package/src/resources/objects.ts +99 -0
  297. package/src/resources/parser.ts +24 -0
  298. package/src/resources/types.ts +23 -0
  299. package/src/tracing/git.ts +51 -0
  300. package/src/tracing/index.ts +3 -0
  301. package/src/tracing/trace.ts +31 -0
  302. package/src/tracing/traced.ts +4 -0
  303. package/src/tsconfig.json +10 -0
  304. package/src/units/index.ts +2 -0
  305. package/src/units/unit-parser.ts +63 -0
  306. package/src/units/units.ts +53 -0
  307. package/tsconfig.json +15 -0
@@ -0,0 +1,134 @@
1
+ import { hash } from "immutable"
2
+ import { InstrumentsError } from "../error"
3
+
4
+ export type Kind<
5
+ Name extends string = string,
6
+ Version extends Kind.Version = Kind.Version
7
+ > = Kind.Kind<Name, Version>
8
+ export namespace Kind {
9
+ export type InputVersion = `v${string}`
10
+
11
+ export interface IdentParent {
12
+ text: string
13
+ name: string
14
+ }
15
+
16
+ export abstract class Identifier<
17
+ Name extends string = string,
18
+ Parent extends IdentParent | null = IdentParent | null
19
+ > implements IdentParent
20
+ {
21
+ constructor(
22
+ readonly name: Name,
23
+ readonly parent: Parent
24
+ ) {
25
+ this.toString = () => this.text
26
+ }
27
+ get text(): string {
28
+ return [this.parent?.text, this.name].filter(Boolean).join("/")
29
+ }
30
+
31
+ abstract child<Name extends string>(name: Name): Identifier<Name, this>
32
+
33
+ equals(other: any) {
34
+ if (typeof other !== "object" || !other) {
35
+ return false
36
+ }
37
+ if (!(other instanceof Identifier)) {
38
+ return false
39
+ }
40
+ return this.text === other.text
41
+ }
42
+
43
+ private hashCode() {
44
+ return hash(this.text)
45
+ }
46
+ }
47
+
48
+ export class Group<const Name extends string = string> extends Identifier<Name, null> {
49
+ constructor(override name: Name) {
50
+ super(name, null)
51
+ }
52
+ version<Version extends InputVersion>(apiVersion: Version) {
53
+ return new Version(apiVersion, this)
54
+ }
55
+
56
+ child<Name extends string>(name: Name): Version<Name, this> {
57
+ if (!name.startsWith("v")) {
58
+ throw new InstrumentsError(
59
+ `Invalid version name "${name}". Version name must start with "v".`
60
+ )
61
+ }
62
+ return this.version(name as any)
63
+ }
64
+ }
65
+
66
+ export class Version<
67
+ const _Version extends string = string,
68
+ const _Group extends Group = Group
69
+ > extends Identifier<_Version, _Group> {
70
+ kind<Kind extends string>(kind: Kind) {
71
+ return new Kind(kind, this)
72
+ }
73
+
74
+ get group() {
75
+ return this.parent
76
+ }
77
+
78
+ child<Name extends string>(name: Name): Kind<Name, this> {
79
+ return this.kind(name)
80
+ }
81
+ }
82
+
83
+ export class Kind<
84
+ const Name extends string = string,
85
+ const V extends Version = Version
86
+ > extends Identifier<Name, V> {
87
+ get version() {
88
+ return this.parent
89
+ }
90
+
91
+ get group() {
92
+ return this.parent?.parent
93
+ }
94
+
95
+ subkind<SubKind extends string>(subkind: SubKind) {
96
+ return new SubKind(subkind, this)
97
+ }
98
+
99
+ child<Name extends string>(name: Name): SubKind<Name, this> {
100
+ return this.subkind(name)
101
+ }
102
+ }
103
+
104
+ export class SubKind<
105
+ _SubKind extends string = string,
106
+ _Parent extends Kind = Kind
107
+ > extends Identifier<_SubKind, _Parent> {
108
+ constructor(name: _SubKind, parent: _Parent) {
109
+ super(name, parent)
110
+ }
111
+
112
+ subkind<SubKind extends string>(subkind: SubKind): never {
113
+ throw new InstrumentsError(`SubKind "${this.text}" cannot have subkind "${subkind}".`)
114
+ }
115
+
116
+ child<Name extends string>(name: Name): never {
117
+ return this.subkind(name)
118
+ }
119
+ }
120
+
121
+ export function group<ApiGroup extends string>(apiGroup: ApiGroup) {
122
+ return new Group(apiGroup)
123
+ }
124
+
125
+ export function version<ApiVersion extends InputVersion>(apiVersion: ApiVersion) {
126
+ return new Version(apiVersion, group(""))
127
+ }
128
+ }
129
+ export function kinded(kind: Kind.Identifier) {
130
+ return <T extends abstract new (...args: any[]) => object>(ctor: T) => {
131
+ ctor.prototype.kind = kind
132
+ return ctor
133
+ }
134
+ }
@@ -0,0 +1,89 @@
1
+ import { List, Map } from "immutable"
2
+ import { defaultsDeep, merge } from "lodash"
3
+ import {
4
+ CliFlag,
5
+ CliOptionValue,
6
+ VerbatimTerm,
7
+ type CliTerm,
8
+ type ValueTermJoiner
9
+ } from "./cli-term"
10
+ import type { CliArgsMapping, CliKey } from "./types"
11
+
12
+ export interface CliCommandBuilderOptions {
13
+ joiner: ValueTermJoiner
14
+ }
15
+
16
+ export class CmdBuilder {
17
+ protected constructor(
18
+ readonly executable: string,
19
+ private readonly _terms: List<CliTerm>,
20
+ private readonly _options: CliCommandBuilderOptions
21
+ ) {}
22
+
23
+ private _withArgs(f: (args: List<CliTerm>) => List<CliTerm>) {
24
+ return new CmdBuilder(this.executable, f(this._terms), this._options)
25
+ }
26
+
27
+ private _withOptions(f: (options: CliCommandBuilderOptions) => CliCommandBuilderOptions) {
28
+ return new CmdBuilder(this.executable, this._terms, f(this._options))
29
+ }
30
+
31
+ flag(...flags: CliKey[]) {
32
+ const flagTerms = flags.map(flag => new CliFlag(flag))
33
+ return this._withArgs(terms => terms.concat(flagTerms))
34
+ }
35
+
36
+ verbatim(...values: string[]) {
37
+ const verbatimTerms = values.map(value => new VerbatimTerm(value))
38
+ return this._withArgs(terms => terms.concat(verbatimTerms))
39
+ }
40
+
41
+ option(args: CliArgsMapping) {
42
+ const map = Map(args)
43
+ const optionTerms = map.entrySeq().map(([key, value]) => {
44
+ let joiner: string | undefined
45
+ const lastChar = key.at(-1)
46
+ if (lastChar === "=") {
47
+ joiner = "="
48
+ key = key.slice(0, -1) as CliKey
49
+ } else if (lastChar === " ") {
50
+ joiner = " "
51
+ key = key.slice(0, -1) as CliKey
52
+ }
53
+ return new CliOptionValue(key, joiner, value)
54
+ })
55
+ return this._withArgs(terms => terms.concat(optionTerms))
56
+ }
57
+
58
+ joiner(joiner: ValueTermJoiner) {
59
+ return this._withOptions(options => merge({}, options, { joiner: joiner }))
60
+ }
61
+
62
+ toArray() {
63
+ const terms = this._terms
64
+ .filter(x => !x.isMissing)
65
+ .map(term => term.str(this._options.joiner))
66
+ .toArray()
67
+ if (this.executable !== "") {
68
+ terms.unshift(this.executable)
69
+ }
70
+ return terms
71
+ }
72
+
73
+ toString() {
74
+ return this.toArray().join(" ")
75
+ }
76
+
77
+ static make(executable: string, options: CliCommandBuilderOptions) {
78
+ return new CmdBuilder(executable, List(), options)
79
+ }
80
+ }
81
+
82
+ const defaultOptions: CliCommandBuilderOptions = {
83
+ joiner: " "
84
+ }
85
+
86
+ export function Cmd(executable: string, options?: Partial<CliCommandBuilderOptions>) {
87
+ options = defaultsDeep({}, options, defaultOptions)
88
+ return CmdBuilder.make(executable, options as any)
89
+ }
@@ -0,0 +1,60 @@
1
+ import { InstrumentsError } from "../error"
2
+ import type { CliValue } from "./types"
3
+
4
+ export class CliFlag {
5
+ constructor(readonly key: string) {}
6
+
7
+ str(joiner: string) {
8
+ return this.key
9
+ }
10
+
11
+ get isMissing() {
12
+ return false
13
+ }
14
+ }
15
+
16
+ export type ValueTermJoiner = "=" | " "
17
+
18
+ export class CliOptionValue {
19
+ constructor(
20
+ private readonly key: string,
21
+ private readonly overrideTermJoiner: string | undefined,
22
+ private readonly value: CliValue
23
+ ) {}
24
+
25
+ get isMissing() {
26
+ return this.value === null
27
+ }
28
+
29
+ private _valueStr() {
30
+ if (this.value === null) {
31
+ throw new Error("Shouldn't be here")
32
+ }
33
+ if (this.value === "") {
34
+ return `""`
35
+ }
36
+ return `${this.value}`
37
+ }
38
+
39
+ str(joiner: string) {
40
+ if (this.value === undefined) {
41
+ throw new InstrumentsError("CliOptionValue cannot be undefined, use null instead")
42
+ }
43
+
44
+ return [this.key, this._valueStr()].join(this.overrideTermJoiner ?? joiner)
45
+ }
46
+ }
47
+
48
+ export class VerbatimTerm {
49
+ constructor(readonly value: string) {}
50
+
51
+ str(joiner: string) {
52
+ return this.value
53
+ }
54
+
55
+ get isMissing() {
56
+ return false
57
+ }
58
+ }
59
+
60
+ export type CliTerm = CliFlag | CliOptionValue | VerbatimTerm
@@ -0,0 +1,2 @@
1
+ export { Cmd, CmdBuilder } from "./cli-command"
2
+ export { CliArgsMapping, CliKey, CliValue } from "./types"
@@ -0,0 +1,4 @@
1
+ export type CliKey = `-${string}` | `--${string}`
2
+ export type InputCliKey = `${CliKey}=` | `${CliKey} ` | CliKey
3
+ export type CliValue = string | number | boolean | null | `${string}` | ` ${string}`
4
+ export type CliArgsMapping = Record<InputCliKey, CliValue>
@@ -0,0 +1,147 @@
1
+ import chalk from "chalk"
2
+ import { Embedder } from "../_embedder"
3
+
4
+ export type KnownFormats = "local" | "global" | undefined
5
+ export namespace Displayers {
6
+ export interface Out {
7
+ default: (format?: string) => string
8
+ simple: (format?: KnownFormats | string) => string
9
+ pretty: (format?: KnownFormats | string) => string
10
+ prefix?: () => string
11
+ }
12
+ export type In<Target extends object = object> = {
13
+ simple?: (this: Out, self: Target, format?: string) => string | object
14
+ pretty?: (this: Out, self: Target, format?: string) => string | object
15
+ prefix?: (this: Out, self: Target) => string
16
+ }
17
+ export type Modes = keyof In
18
+ }
19
+ const chalkNoColor = new chalk.Instance({
20
+ level: 0
21
+ })
22
+ class DisplayerDecorator {
23
+ private _system = new Embedder<object, Displayers.In>("displayers")
24
+ private _lastMode: Displayers.Modes = "simple"
25
+ private _withLastMode(mode: Displayers.Modes, fn: (...args: any[]) => string) {
26
+ return (...args: any[]) => {
27
+ const oldMode = this._lastMode
28
+ this._lastMode = mode
29
+ const result = fn(...args)
30
+ this._lastMode = oldMode
31
+ return result
32
+ }
33
+ }
34
+ implement(ctor: abstract new (...args: any[]) => object, input: Displayers.In) {
35
+ this._system.set(ctor.prototype, input)
36
+ const decorator = this
37
+ Object.defineProperties(ctor.prototype, {
38
+ [Symbol.toStringTag]: {
39
+ get() {
40
+ const a = decorator.get(this)
41
+ return a.default()
42
+ }
43
+ },
44
+ toString: {
45
+ value() {
46
+ return this[Symbol.toStringTag]
47
+ }
48
+ }
49
+ })
50
+ }
51
+
52
+ wrapRecursiveFallback(out: Displayers.Out) {
53
+ const oAny = out as any
54
+ const self = this
55
+ for (const k in out) {
56
+ const orig = oAny[k]
57
+ if (typeof orig === "function") {
58
+ oAny[k] = function (...args: any[]) {
59
+ const oldMode = self._lastMode
60
+ if (k === "simple" || k === "pretty") {
61
+ self._lastMode = k
62
+ }
63
+ try {
64
+ let result = orig.call(oAny, ...args)
65
+ if (!Array.isArray(result)) {
66
+ result = [result]
67
+ }
68
+ const terms = result.map((x: any) => {
69
+ const sndDisplayers = Displayers.tryGet(x) as any
70
+ if (sndDisplayers) {
71
+ return sndDisplayers[k].call(sndDisplayers, x, ...args)
72
+ }
73
+ return x
74
+ })
75
+ return terms.join(" ")
76
+ } finally {
77
+ this._lastMode = oldMode
78
+ }
79
+ }
80
+ }
81
+ }
82
+ return out
83
+ }
84
+
85
+ tryGet(target: any): Displayers.Out | undefined {
86
+ if (typeof target !== "object") {
87
+ return undefined
88
+ }
89
+ const input = this._system.get(target)
90
+ if (!input) {
91
+ return undefined
92
+ }
93
+ const o: Displayers.Out = {
94
+ default: (format?: string) => {
95
+ const lastMode = this._lastMode
96
+ const result = o[lastMode]?.call(o, format) ?? o.simple(format)
97
+ return result
98
+ },
99
+ simple: format => {
100
+ const result = input.simple?.call(o, target, format)
101
+ if (!result) {
102
+ const pretty = input.pretty?.call(o, target, format)
103
+ if (typeof pretty === "string") {
104
+ return chalkNoColor(pretty)
105
+ }
106
+ return "?!!?"
107
+ }
108
+ return result as any
109
+ },
110
+ prefix: input.prefix && (() => input.prefix!.call(o, target)),
111
+ pretty: format => {
112
+ return (input.pretty?.call(o, target, format) ??
113
+ input.simple?.call(o, target, format) ??
114
+ "?!?") as any
115
+ }
116
+ }
117
+ return this.wrapRecursiveFallback(o)
118
+ }
119
+
120
+ get(target: object): Displayers.Out {
121
+ this._system.get(target) // error if not there
122
+ return this.tryGet(target)!
123
+ }
124
+
125
+ get decorator() {
126
+ return Object.assign(
127
+ <
128
+ Target extends abstract new (...args: any[]) => object,
129
+ Impl extends Displayers.In<InstanceType<Target>>
130
+ >(
131
+ input: Impl
132
+ ) => {
133
+ return (ctor: Target) => {
134
+ this.implement(ctor, input as any)
135
+ return ctor
136
+ }
137
+ },
138
+ {
139
+ get: (target: object): Displayers.Out => {
140
+ return this.get(target)
141
+ }
142
+ }
143
+ )
144
+ }
145
+ }
146
+ export const Displayers = new DisplayerDecorator()
147
+ export const displayers = Displayers.decorator
@@ -0,0 +1 @@
1
+ export * from "./displayers"
package/src/env/env.ts ADDED
@@ -0,0 +1,74 @@
1
+ import { Map, type MapOf } from "immutable"
2
+ import { InstrumentsError } from "../error"
3
+ import type { InputEnv, InputEnvMapping } from "./types"
4
+ import { isValidEnvVarName } from "./validate-name"
5
+
6
+ type _EnvBuilderMap = MapOf<InputEnvMapping>
7
+ export class EnvBuilder {
8
+ constructor(private readonly _env: _EnvBuilderMap) {
9
+ for (const key of _env.keys()) {
10
+ if (!isValidEnvVarName(key)) {
11
+ throw new InstrumentsError("Invalid environment variable name", {
12
+ key: key
13
+ })
14
+ }
15
+ }
16
+ }
17
+
18
+ get values() {
19
+ return this._env
20
+ }
21
+
22
+ private _withEnv(f: (env: _EnvBuilderMap) => _EnvBuilderMap) {
23
+ return new EnvBuilder(f(this._env))
24
+ }
25
+
26
+ add(name: string, value: string): EnvBuilder
27
+ add(input: InputEnvMapping): EnvBuilder
28
+ add(a: any, b?: any) {
29
+ const pairs: [string, string][] = typeof a === "string" ? [[a, b]] : Object.entries(a)
30
+ const map = Map(pairs)
31
+ const existingKeys = map
32
+ .keySeq()
33
+ .filter(k => this._env.has(k))
34
+ .toList()
35
+ if (existingKeys.size > 0) {
36
+ throw new InstrumentsError("Cannot overwrite existing keys using add", {
37
+ keys: existingKeys.toArray()
38
+ })
39
+ }
40
+ return this._withEnv(env => env.merge(map) as any)
41
+ }
42
+
43
+ overwrite(name: string, value: string): EnvBuilder
44
+ overwrite(input: InputEnvMapping): EnvBuilder
45
+ overwrite(a: any, b?: any) {
46
+ if (typeof a === "string") {
47
+ return this._withEnv(env => env.set(a, b))
48
+ } else {
49
+ const map = Map(a as InputEnvMapping) as _EnvBuilderMap
50
+ return this._withEnv(env => env.merge(map) as any)
51
+ }
52
+ }
53
+
54
+ toObject() {
55
+ return this._env
56
+ .filter(v => v != null)
57
+ .map(x => `${x}`)
58
+ .toObject()
59
+ }
60
+
61
+ static make(env?: InputEnv) {
62
+ if (!env) {
63
+ return new EnvBuilder(Map({}))
64
+ }
65
+ if (env instanceof EnvBuilder) {
66
+ return env
67
+ }
68
+ return new EnvBuilder(Map(env ?? {}).filter(v => v != null) as _EnvBuilderMap)
69
+ }
70
+ }
71
+
72
+ export function Env(env?: InputEnvMapping) {
73
+ return EnvBuilder.make(env)
74
+ }
@@ -0,0 +1,2 @@
1
+ export { Env, EnvBuilder } from "./env"
2
+ export { InputEnvMapping } from "./types"
@@ -0,0 +1,7 @@
1
+ import type { EnvBuilder } from "./env"
2
+
3
+ export type InputEnvMapping = Partial<
4
+ Record<string, string | null | number | boolean | bigint | undefined>
5
+ >
6
+
7
+ export type InputEnv = EnvBuilder | InputEnvMapping
@@ -0,0 +1,10 @@
1
+ import { anyCharOf, digit, letter } from "parjs"
2
+ import { many, or, stringify, then } from "parjs/combinators"
3
+
4
+ const pEnvVarStartChar = letter().pipe(or(anyCharOf("_")))
5
+ const pEnvVarChar = pEnvVarStartChar.pipe(or(digit()))
6
+ const pEnvVarName = pEnvVarStartChar.pipe(then(pEnvVarChar.pipe(many())), stringify())
7
+
8
+ export function isValidEnvVarName(x: string) {
9
+ return pEnvVarName.parse(x).isOk
10
+ }
package/src/error.ts ADDED
@@ -0,0 +1,15 @@
1
+ export class InstrumentsError extends Error {
2
+ override get name() {
3
+ return this.constructor.name
4
+ }
5
+ constructor(message: string, details: Record<string, any> = {}) {
6
+ super(message)
7
+ Object.assign(this, details)
8
+ }
9
+ }
10
+
11
+ export class ProxyOperationError extends InstrumentsError {
12
+ constructor(message: string, details: Record<string, any> = {}) {
13
+ super(message, details)
14
+ }
15
+ }