@k8ts/metadata 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.
- package/LICENSE.md +7 -0
- package/README.md +3 -0
- package/dist/error.d.ts +5 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +12 -0
- package/dist/error.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/input/dict-input.d.ts +12 -0
- package/dist/input/dict-input.d.ts.map +1 -0
- package/dist/input/dict-input.js +3 -0
- package/dist/input/dict-input.js.map +1 -0
- package/dist/input/parse-dict.d.ts +5 -0
- package/dist/input/parse-dict.d.ts.map +1 -0
- package/dist/input/parse-dict.js +48 -0
- package/dist/input/parse-dict.js.map +1 -0
- package/dist/key/convert.d.ts +6 -0
- package/dist/key/convert.d.ts.map +1 -0
- package/dist/key/convert.js +7 -0
- package/dist/key/convert.js.map +1 -0
- package/dist/key/index.d.ts +4 -0
- package/dist/key/index.d.ts.map +1 -0
- package/dist/key/index.js +11 -0
- package/dist/key/index.js.map +1 -0
- package/dist/key/parse-key.d.ts +5 -0
- package/dist/key/parse-key.d.ts.map +1 -0
- package/dist/key/parse-key.js +45 -0
- package/dist/key/parse-key.js.map +1 -0
- package/dist/key/repr.d.ts +30 -0
- package/dist/key/repr.d.ts.map +1 -0
- package/dist/key/repr.js +64 -0
- package/dist/key/repr.js.map +1 -0
- package/dist/key/types.d.ts +23 -0
- package/dist/key/types.d.ts.map +1 -0
- package/dist/key/types.js +8 -0
- package/dist/key/types.js.map +1 -0
- package/dist/meta.d.ts +101 -0
- package/dist/meta.d.ts.map +1 -0
- package/dist/meta.js +230 -0
- package/dist/meta.js.map +1 -0
- package/dist/mutable-meta.d.ts +1 -0
- package/dist/mutable-meta.d.ts.map +1 -0
- package/dist/mutable-meta.js +2 -0
- package/dist/mutable-meta.js.map +1 -0
- package/dist/src.tsbuildinfo +1 -0
- package/dist/test.tsbuildinfo +1 -0
- package/package.json +88 -0
- package/src/error.ts +7 -0
- package/src/index.ts +2 -0
- package/src/input/dict-input.ts +12 -0
- package/src/input/parse-dict.ts +45 -0
- package/src/key/convert.ts +6 -0
- package/src/key/index.ts +4 -0
- package/src/key/parse-key.ts +58 -0
- package/src/key/repr.ts +72 -0
- package/src/key/types.ts +27 -0
- package/src/meta.ts +275 -0
- package/src/mutable-meta.ts +0 -0
- package/src/tsconfig.json +10 -0
- package/tsconfig.json +15 -0
package/src/key/repr.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { hash } from "immutable"
|
|
2
|
+
interface ImmObject {
|
|
3
|
+
equals(other: ImmObject): boolean
|
|
4
|
+
hashCode(): number
|
|
5
|
+
}
|
|
6
|
+
abstract class KeyType implements ImmObject {
|
|
7
|
+
abstract get str(): string
|
|
8
|
+
equals(other: ImmObject): boolean {
|
|
9
|
+
return this.constructor === other.constructor && this.toString() === other.toString()
|
|
10
|
+
}
|
|
11
|
+
hashCode(): number {
|
|
12
|
+
return hash(this.toString())
|
|
13
|
+
}
|
|
14
|
+
toString() {
|
|
15
|
+
return this.str
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class ValueKey extends KeyType {
|
|
20
|
+
type = "full" as const
|
|
21
|
+
constructor(
|
|
22
|
+
readonly _prefix: string,
|
|
23
|
+
readonly _section: string | undefined,
|
|
24
|
+
readonly _name: string
|
|
25
|
+
) {
|
|
26
|
+
super()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
get suffix() {
|
|
30
|
+
const parts = []
|
|
31
|
+
if (this._section) {
|
|
32
|
+
parts.push(this._section)
|
|
33
|
+
if (!this._section.endsWith("/")) {
|
|
34
|
+
parts.push("/")
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
parts.push(this._name)
|
|
38
|
+
return parts.join("")
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
get str() {
|
|
42
|
+
return [this._prefix, this.suffix].join("")
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
get parent() {
|
|
46
|
+
if (this._section == null) {
|
|
47
|
+
return null
|
|
48
|
+
}
|
|
49
|
+
return new SectionKey(this._section)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
section(section: string | SectionKey) {
|
|
53
|
+
section = section instanceof SectionKey ? section.str : section
|
|
54
|
+
if (this._section) {
|
|
55
|
+
throw new Error("Already has a section")
|
|
56
|
+
}
|
|
57
|
+
return new ValueKey(this._prefix, section, this._name)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export class SectionKey extends KeyType {
|
|
62
|
+
type = "heading" as const
|
|
63
|
+
constructor(readonly _section: string) {
|
|
64
|
+
super()
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
get str() {
|
|
68
|
+
return [this._section].join("")
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export type SomeKey = ValueKey | SectionKey
|
package/src/key/types.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export namespace Char {
|
|
2
|
+
export namespace Prefix {
|
|
3
|
+
export type Label = "%"
|
|
4
|
+
export type Annotation = "^"
|
|
5
|
+
export type Comment = "#"
|
|
6
|
+
export type Custom = `${Label | Annotation | Comment}`
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type Section = "/"
|
|
10
|
+
export const Section = "/"
|
|
11
|
+
|
|
12
|
+
export type Lower =
|
|
13
|
+
`${"a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"}`
|
|
14
|
+
export type Upper = Uppercase<Lower>
|
|
15
|
+
export type Digit = `${"0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"}`
|
|
16
|
+
export type Extra = "-" | "_" | "."
|
|
17
|
+
export type Normal = `${Lower | Digit | Extra | Upper}`
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export namespace Key {
|
|
21
|
+
export type Section = `${Char.Normal}${string}${Char.Section}`
|
|
22
|
+
export type Special = "name" | "namespace"
|
|
23
|
+
export type Value = `${Char.Prefix.Custom}${string}${Char.Normal}` | Special
|
|
24
|
+
|
|
25
|
+
export type Key = Section | Value
|
|
26
|
+
}
|
|
27
|
+
export type Key = Key.Key
|
package/src/meta.ts
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import { Map, Set } from "immutable"
|
|
2
|
+
import { MetadataError } from "./error"
|
|
3
|
+
import type { InputMeta, MetaInputParts } from "./input/dict-input"
|
|
4
|
+
import { parseKey, parseMetaInput } from "./key"
|
|
5
|
+
import { ValueKey, type SectionKey } from "./key/repr"
|
|
6
|
+
import { Key as Key_ } from "./key/types"
|
|
7
|
+
export type Meta = Meta.Meta
|
|
8
|
+
export type MutableMeta = Meta.MutableMeta
|
|
9
|
+
export namespace Meta {
|
|
10
|
+
export type Input = InputMeta
|
|
11
|
+
export import Key = Key_
|
|
12
|
+
export class Meta implements Iterable<[ValueKey, string]> {
|
|
13
|
+
constructor(private readonly _dict: Map<ValueKey, string>) {
|
|
14
|
+
const a = _dict
|
|
15
|
+
const aaa = 1
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
[Symbol.iterator]() {
|
|
19
|
+
return this._dict.entries()[Symbol.iterator]()
|
|
20
|
+
}
|
|
21
|
+
protected _create(raw: Map<ValueKey, string>) {
|
|
22
|
+
return new Meta(raw)
|
|
23
|
+
}
|
|
24
|
+
private _createWith(f: (raw: Map<ValueKey, string>) => Map<ValueKey, string>) {
|
|
25
|
+
return this._create(f(this._dict))
|
|
26
|
+
}
|
|
27
|
+
add(key: Key.Value, value: string): Meta
|
|
28
|
+
add(key: Key.Section, value: MetaInputParts.Nested): Meta
|
|
29
|
+
add(input: InputMeta): Meta
|
|
30
|
+
add(a: any, b?: any) {
|
|
31
|
+
return this._createWith(raw => {
|
|
32
|
+
const parsed = _pairToMap([a, b])
|
|
33
|
+
const newMap = raw.mergeWith((prev, cur, key) => {
|
|
34
|
+
throw new MetadataError(`Duplicate entry for ${key}, was ${prev} now ${cur}`, {
|
|
35
|
+
key: key.str
|
|
36
|
+
})
|
|
37
|
+
}, parsed)
|
|
38
|
+
return newMap
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
equals(other: Meta.Input) {
|
|
43
|
+
return this._dict.equals(make(other)._dict)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
section(key: string) {
|
|
47
|
+
return this._createWith(raw => {
|
|
48
|
+
return raw.mapKeys(k => k.section(key))
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
overwrite(key: Key.Value, value: string): Meta
|
|
53
|
+
overwrite(key: Key.Section, value: MetaInputParts.Nested): Meta
|
|
54
|
+
overwrite(input?: InputMeta): Meta
|
|
55
|
+
overwrite(a?: any, b?: any) {
|
|
56
|
+
if (a === undefined) {
|
|
57
|
+
return this
|
|
58
|
+
}
|
|
59
|
+
return this._createWith(raw => {
|
|
60
|
+
const fromPair = _pairToMap([a, b])
|
|
61
|
+
return raw.merge(fromPair)
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
has<X extends Key.Value>(key: X) {
|
|
66
|
+
const parsed = parseKey(key)
|
|
67
|
+
if (parsed instanceof ValueKey) {
|
|
68
|
+
return this._dict.has(parsed)
|
|
69
|
+
} else {
|
|
70
|
+
return this._matchSectionKeys(parsed).size > 0
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
get(key: Key.Value) {
|
|
75
|
+
const parsed = parseKey(key)
|
|
76
|
+
const v = this._dict.get(parsed as ValueKey)
|
|
77
|
+
if (v === undefined) {
|
|
78
|
+
throw new MetadataError(`Key ${key} not found!`, { key })
|
|
79
|
+
}
|
|
80
|
+
return v
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
tryGet(key: Key.Value, fallback?: string) {
|
|
84
|
+
const parsed = parseKey(key)
|
|
85
|
+
if (!(parsed instanceof ValueKey)) {
|
|
86
|
+
throw new MetadataError("Unexpected section key!", { key })
|
|
87
|
+
}
|
|
88
|
+
return this._dict.get(parsed) ?? fallback
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
private _matchSectionKeys(key: SectionKey) {
|
|
92
|
+
return this._dict.filter((_, k) => k.parent?.equals(key))
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
pick(...keySpecs: Key.Key[]) {
|
|
96
|
+
return this._createWith(raw => {
|
|
97
|
+
const parsed = keySpecs.map(parseKey)
|
|
98
|
+
let keySet = Set()
|
|
99
|
+
for (const key of parsed) {
|
|
100
|
+
if (key instanceof ValueKey) {
|
|
101
|
+
keySet = keySet.add(key)
|
|
102
|
+
} else {
|
|
103
|
+
const sectionKeys = this._matchSectionKeys(key)
|
|
104
|
+
keySet = keySet.union(sectionKeys.keySeq())
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return raw.filter((_, k) => keySet.has(k))
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
private _prefixed(prefix: string) {
|
|
112
|
+
return this._dict
|
|
113
|
+
.filter((_, k) => k._prefix === prefix)
|
|
114
|
+
.mapKeys(k => k.suffix)
|
|
115
|
+
.toObject()
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
get labels() {
|
|
119
|
+
return this._prefixed("%")
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
get annotations() {
|
|
123
|
+
return this._prefixed("^")
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
get comments() {
|
|
127
|
+
return this._prefixed("#")
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
get values() {
|
|
131
|
+
return this._dict.toJS()
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
get core() {
|
|
135
|
+
return this._prefixed("") as {
|
|
136
|
+
[key in Key.Special]?: string
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
remove(key: Key.Value): this
|
|
140
|
+
remove(ns: Key.Section, key: string): this
|
|
141
|
+
remove(ns: Key.Section): this
|
|
142
|
+
remove(a: any, b?: any) {
|
|
143
|
+
return this._createWith(raw => {
|
|
144
|
+
const parsed = parseKey(a)
|
|
145
|
+
if (parsed instanceof ValueKey) {
|
|
146
|
+
return raw.delete(parsed)
|
|
147
|
+
} else {
|
|
148
|
+
return raw.filter((_, k) => !k.parent?.equals(parsed))
|
|
149
|
+
}
|
|
150
|
+
})
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
expand() {
|
|
154
|
+
const labels = this.labels
|
|
155
|
+
const annotations = this.annotations
|
|
156
|
+
const core = this.core
|
|
157
|
+
return {
|
|
158
|
+
...core,
|
|
159
|
+
labels,
|
|
160
|
+
annotations
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
toMutable() {
|
|
165
|
+
return new MutableMeta(this)
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export function make(key: Key.Value, value: string): Meta
|
|
170
|
+
export function make(key: Key.Section, value: MetaInputParts.Nested): Meta
|
|
171
|
+
export function make(input?: InputMeta): Meta
|
|
172
|
+
export function make(a?: any, b?: any) {
|
|
173
|
+
return new Meta(_pairToMap([a, b]))
|
|
174
|
+
}
|
|
175
|
+
function _pairToObject(pair: [string, string | object] | [object]) {
|
|
176
|
+
const [key, value] = pair
|
|
177
|
+
if (key instanceof Meta) {
|
|
178
|
+
return Map(key)
|
|
179
|
+
}
|
|
180
|
+
if (typeof key === "string") {
|
|
181
|
+
return {
|
|
182
|
+
[key]: value as string
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return key
|
|
186
|
+
}
|
|
187
|
+
function _pairToMap(pair: [string, string | object] | [object]) {
|
|
188
|
+
return parseMetaInput(_pairToObject(pair))
|
|
189
|
+
}
|
|
190
|
+
export function makeMutable(input: InputMeta = {}) {
|
|
191
|
+
return make(input).toMutable()
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export function splat(...input: InputMeta[]) {
|
|
195
|
+
return input.map(make).reduce((acc, meta) => acc.add(meta), make())
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export function is(value: any): value is Meta {
|
|
199
|
+
return value instanceof Meta
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export class MutableMeta {
|
|
203
|
+
constructor(private _meta: Meta) {}
|
|
204
|
+
|
|
205
|
+
add(key: Key.Value, value: string): this
|
|
206
|
+
add(key: Key.Section, value: MetaInputParts.Nested): this
|
|
207
|
+
add(input: InputMeta): this
|
|
208
|
+
add(a: any, b?: any) {
|
|
209
|
+
this._meta = this._meta.add(a, b)
|
|
210
|
+
return this
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
remove(key: Key.Value): this
|
|
214
|
+
remove(ns: Key.Section, key: string): this
|
|
215
|
+
remove(ns: Key.Section): this
|
|
216
|
+
remove(a: any, b?: any) {
|
|
217
|
+
this._meta = this._meta.remove(a, b)
|
|
218
|
+
return this
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
overwrite(key: Key.Value, value: string): this
|
|
222
|
+
overwrite(key: Key.Section, value: MetaInputParts.Nested): this
|
|
223
|
+
overwrite(input?: InputMeta): this
|
|
224
|
+
overwrite(a?: any, b?: any) {
|
|
225
|
+
this._meta = this._meta.overwrite(a, b)
|
|
226
|
+
return this
|
|
227
|
+
}
|
|
228
|
+
equals(other: Meta.Input) {
|
|
229
|
+
return this._meta.equals(other)
|
|
230
|
+
}
|
|
231
|
+
get(key: Key.Value) {
|
|
232
|
+
return this._meta.get(key)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
tryGet(key: Key.Value, fallback?: string) {
|
|
236
|
+
return this._meta.tryGet(key, fallback)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
has(key: Key.Value) {
|
|
240
|
+
return this._meta.has(key)
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
pick(...keySpecs: Key.Key[]) {
|
|
244
|
+
const newMeta = this._meta.pick(...keySpecs)
|
|
245
|
+
return new MutableMeta(newMeta)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
toMutable() {
|
|
249
|
+
return new MutableMeta(this._meta)
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
section(key: string) {
|
|
253
|
+
return new MutableMeta(this._meta.section(key))
|
|
254
|
+
}
|
|
255
|
+
get labels() {
|
|
256
|
+
return this._meta.labels
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
get annotations() {
|
|
260
|
+
return this._meta.annotations
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
get comments() {
|
|
264
|
+
return this._meta.comments
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
get core() {
|
|
268
|
+
return this._meta.core
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
toImmutable() {
|
|
272
|
+
return this._meta
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
File without changes
|