@k8ts/metadata 0.4.14 → 0.5.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/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/input/dict-input.d.ts +2 -1
- package/dist/input/dict-input.d.ts.map +1 -1
- package/dist/input/parse-dict.d.ts +1 -3
- package/dist/input/parse-dict.d.ts.map +1 -1
- package/dist/input/parse-dict.js +7 -11
- package/dist/input/parse-dict.js.map +1 -1
- package/dist/key/parse-key.d.ts.map +1 -1
- package/dist/key/parse-key.js +3 -2
- package/dist/key/parse-key.js.map +1 -1
- package/dist/key/repr.d.ts +0 -2
- package/dist/key/repr.d.ts.map +1 -1
- package/dist/key/repr.js +0 -4
- package/dist/key/repr.js.map +1 -1
- package/dist/key/types.d.ts +2 -7
- package/dist/key/types.d.ts.map +1 -1
- package/dist/key/types.js.map +1 -1
- package/dist/meta.d.ts +25 -65
- package/dist/meta.d.ts.map +1 -1
- package/dist/meta.js +106 -119
- package/dist/meta.js.map +1 -1
- package/dist/order-meta-keyed-object.d.ts +2 -0
- package/dist/order-meta-keyed-object.d.ts.map +1 -0
- package/dist/order-meta-keyed-object.js +21 -0
- package/dist/order-meta-keyed-object.js.map +1 -0
- package/dist/util.d.ts +23 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +113 -0
- package/dist/util.js.map +1 -0
- package/package.json +17 -16
- package/src/index.ts +2 -2
- package/src/input/dict-input.ts +6 -1
- package/src/input/parse-dict.ts +9 -13
- package/src/key/parse-key.ts +5 -3
- package/src/key/repr.ts +1 -5
- package/src/key/types.ts +2 -9
- package/src/meta.ts +116 -145
- package/src/order-meta-keyed-object.ts +20 -0
- package/src/util.ts +115 -0
- package/dist/key/convert.d.ts +0 -6
- package/dist/key/convert.d.ts.map +0 -1
- package/dist/key/convert.js +0 -7
- package/dist/key/convert.js.map +0 -1
- package/dist/mutable-meta.d.ts +0 -2
- package/dist/mutable-meta.d.ts.map +0 -1
- package/dist/mutable-meta.js +0 -3
- package/dist/mutable-meta.js.map +0 -1
- package/src/key/convert.ts +0 -6
- package/src/mutable-meta.ts +0 -0
package/src/input/dict-input.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ValueKey } from "../key"
|
|
2
2
|
import type { Key } from "../key/types"
|
|
3
|
+
import type { MetaLike } from "../meta"
|
|
3
4
|
|
|
4
5
|
export namespace MetaInputParts {
|
|
5
6
|
type Of<T extends string, V> = {
|
|
@@ -11,4 +12,8 @@ export namespace MetaInputParts {
|
|
|
11
12
|
export type Input = Full & Heading
|
|
12
13
|
}
|
|
13
14
|
|
|
14
|
-
export type InputMeta =
|
|
15
|
+
export type InputMeta =
|
|
16
|
+
| MetaLike
|
|
17
|
+
| MetaInputParts.Input
|
|
18
|
+
| undefined
|
|
19
|
+
| Iterable<readonly [ValueKey, string]>
|
package/src/input/parse-dict.ts
CHANGED
|
@@ -1,24 +1,20 @@
|
|
|
1
|
-
import { Map } from "immutable"
|
|
2
1
|
import { isNullish } from "what-are-you"
|
|
3
2
|
import { parseInnerKey, parseOuterKey } from "../key/parse-key"
|
|
4
|
-
import { SectionKey
|
|
3
|
+
import { SectionKey } from "../key/repr"
|
|
5
4
|
import { Meta } from "../meta"
|
|
6
5
|
import type { InputMeta } from "./dict-input"
|
|
7
6
|
|
|
8
|
-
export function parseMetaInput(input: InputMeta): Map<
|
|
7
|
+
export function parseMetaInput(input: InputMeta): Map<string, string> {
|
|
9
8
|
if (input == null) {
|
|
10
|
-
return Map()
|
|
9
|
+
return new Map()
|
|
11
10
|
}
|
|
12
|
-
if (Map
|
|
13
|
-
return input as Map<
|
|
11
|
+
if (input instanceof Map) {
|
|
12
|
+
return new Map(input) as Map<string, string>
|
|
14
13
|
}
|
|
15
14
|
if (input instanceof Meta.Meta) {
|
|
16
|
-
return input["_dict"]
|
|
15
|
+
return new Map(input["_dict"] as Map<string, string>)
|
|
17
16
|
}
|
|
18
|
-
|
|
19
|
-
return input["_meta"]["_dict"]
|
|
20
|
-
}
|
|
21
|
-
let map = Map<ValueKey, string>()
|
|
17
|
+
let map = new Map<string, string>()
|
|
22
18
|
for (const [key, value] of Object.entries(input)) {
|
|
23
19
|
const outer = parseOuterKey(key)
|
|
24
20
|
if (isNullish(value)) {
|
|
@@ -37,13 +33,13 @@ export function parseMetaInput(input: InputMeta): Map<ValueKey, string> {
|
|
|
37
33
|
if (typeof vv !== "string") {
|
|
38
34
|
throw new Error(`Expected string value for inner key ${kk}`)
|
|
39
35
|
}
|
|
40
|
-
map
|
|
36
|
+
map.set(inner.section(outer).str, vv as string)
|
|
41
37
|
}
|
|
42
38
|
} else {
|
|
43
39
|
if (typeof value !== "string") {
|
|
44
40
|
throw new Error(`Expected string value for key ${key}`)
|
|
45
41
|
}
|
|
46
|
-
map
|
|
42
|
+
map.set(outer.str, value as string)
|
|
47
43
|
}
|
|
48
44
|
}
|
|
49
45
|
return map
|
package/src/key/parse-key.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { anyCharOf, anyStringOf, digit, lower, string
|
|
1
|
+
import { anyCharOf, anyStringOf, digit, letter, lower, string } from "parjs"
|
|
2
2
|
import { many1, map, maybe, or, qthen, stringify, then, thenq } from "parjs/combinators"
|
|
3
3
|
|
|
4
4
|
import { MetadataError } from "../error"
|
|
@@ -6,9 +6,11 @@ import { SectionKey, ValueKey } from "./repr"
|
|
|
6
6
|
|
|
7
7
|
const cPrefix = anyCharOf("%^#")
|
|
8
8
|
const cSection = string("/")
|
|
9
|
+
export const normalChar = letter().pipe(or(digit())).expects("alphanumeric")
|
|
10
|
+
const cDot = anyCharOf(".")
|
|
11
|
+
|
|
12
|
+
const cExtra = anyCharOf(`-_`).pipe(or(cDot)).expects("'-', '_', or '.'")
|
|
9
13
|
|
|
10
|
-
const cExtra = anyCharOf("-_.").expects("'-', '_', or '.'")
|
|
11
|
-
export const normalChar = upper().pipe(or(lower(), digit())).expects("alphanumeric")
|
|
12
14
|
const cNameChar = lower().pipe(or(digit())).pipe(or("-"))
|
|
13
15
|
const cInterior = normalChar.pipe(or(cExtra)).expects("alphanumeric, '-', '_', or '.'")
|
|
14
16
|
|
package/src/key/repr.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { hash } from "immutable"
|
|
2
1
|
import { MetadataError } from "../error"
|
|
3
2
|
import { normalChar } from "./parse-key"
|
|
4
3
|
interface ImmObject {
|
|
5
4
|
equals(other: ImmObject): boolean
|
|
6
|
-
hashCode(): number
|
|
7
5
|
}
|
|
8
6
|
|
|
9
7
|
abstract class KeyType implements ImmObject {
|
|
@@ -11,9 +9,7 @@ abstract class KeyType implements ImmObject {
|
|
|
11
9
|
equals(other: ImmObject): boolean {
|
|
12
10
|
return this.constructor === other.constructor && this.toString() === other.toString()
|
|
13
11
|
}
|
|
14
|
-
|
|
15
|
-
return hash(this.toString())
|
|
16
|
-
}
|
|
12
|
+
|
|
17
13
|
toString() {
|
|
18
14
|
return this.str
|
|
19
15
|
}
|
package/src/key/types.ts
CHANGED
|
@@ -8,19 +8,12 @@ export namespace Char {
|
|
|
8
8
|
|
|
9
9
|
export type Section = "/"
|
|
10
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}`
|
|
18
11
|
}
|
|
19
12
|
|
|
20
13
|
export namespace Key {
|
|
21
|
-
export type Section = `${
|
|
14
|
+
export type Section = `${string}${Char.Section}`
|
|
22
15
|
export type Special = "name" | "namespace"
|
|
23
|
-
export type Value = (`${Char.Prefix.Custom}${string}` & `${string}${
|
|
16
|
+
export type Value = (`${Char.Prefix.Custom}${string}` & `${string}${string}`) | Special
|
|
24
17
|
|
|
25
18
|
export type Key = Section | Value
|
|
26
19
|
}
|
package/src/meta.ts
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { seq } from "doddle"
|
|
2
2
|
import { MetadataError } from "./error"
|
|
3
3
|
import type { InputMeta, MetaInputParts } from "./input/dict-input"
|
|
4
4
|
import { parseKey, parseMetaInput } from "./key"
|
|
5
5
|
import { pNameValue } from "./key/parse-key"
|
|
6
6
|
import { checkMetaString, ValueKey, type SectionKey } from "./key/repr"
|
|
7
|
-
import { Key
|
|
7
|
+
import { Key } from "./key/types"
|
|
8
|
+
import { orderMetaKeyedObject } from "./order-meta-keyed-object"
|
|
9
|
+
import { equalsMap, toJS } from "./util"
|
|
8
10
|
export type Meta = Meta.Meta
|
|
9
11
|
export type MutableMeta = Meta.MutableMeta
|
|
12
|
+
const MetaMarker = Symbol("k8ts.org/metadata")
|
|
13
|
+
export interface MetaLike {
|
|
14
|
+
readonly [MetaMarker]: true
|
|
15
|
+
}
|
|
10
16
|
export namespace Meta {
|
|
11
17
|
export function _checkNameValue(what: string, v: string) {
|
|
12
18
|
if (!pNameValue.parse(v).isOk) {
|
|
@@ -14,73 +20,81 @@ export namespace Meta {
|
|
|
14
20
|
}
|
|
15
21
|
checkMetaString(what, v, 63)
|
|
16
22
|
}
|
|
17
|
-
export function _checkValue(key:
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
export function _checkValue(key: string, v: string) {
|
|
24
|
+
const parsed = parseKey(key)
|
|
25
|
+
if (!(parsed instanceof ValueKey)) {
|
|
26
|
+
throw new MetadataError(`Expected value key, got section key for ${key}`)
|
|
27
|
+
}
|
|
28
|
+
if (parsed.metaType === "label") {
|
|
29
|
+
checkMetaString(`value of ${key}`, v, 63)
|
|
30
|
+
} else if (parsed.metaType === "core") {
|
|
31
|
+
_checkNameValue(`value of ${key}`, v)
|
|
22
32
|
}
|
|
23
33
|
}
|
|
24
34
|
export type Input = InputMeta
|
|
25
|
-
export
|
|
26
|
-
|
|
27
|
-
constructor(private readonly _dict: Map<
|
|
35
|
+
export class Meta implements Iterable<[ValueKey, string]>, MetaLike {
|
|
36
|
+
readonly [MetaMarker] = true
|
|
37
|
+
constructor(private readonly _dict: Map<string, string>) {
|
|
28
38
|
for (const [key, value] of _dict.entries()) {
|
|
29
39
|
_checkValue(key, value)
|
|
30
40
|
}
|
|
31
41
|
}
|
|
32
42
|
|
|
33
|
-
[Symbol.iterator]() {
|
|
34
|
-
|
|
43
|
+
*[Symbol.iterator]() {
|
|
44
|
+
for (const entry of this._dict.entries()) {
|
|
45
|
+
yield [parseKey(entry[0]) as ValueKey, entry[1]] as [ValueKey, string]
|
|
46
|
+
}
|
|
35
47
|
}
|
|
36
|
-
protected _create(raw: Map<
|
|
48
|
+
protected _create(raw: Map<string, string>) {
|
|
37
49
|
return new Meta(raw)
|
|
38
50
|
}
|
|
39
|
-
|
|
40
|
-
return this._create(
|
|
51
|
+
clone() {
|
|
52
|
+
return this._create(new Map(this._dict))
|
|
41
53
|
}
|
|
42
|
-
add(key: Key.Value, value
|
|
54
|
+
add(key: Key.Value, value?: string): Meta
|
|
43
55
|
add(key: Key.Section, value: MetaInputParts.Nested): Meta
|
|
44
56
|
add(input: InputMeta): Meta
|
|
45
57
|
add(a: any, b?: any) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
58
|
+
const parsed = _pairToMap([a, b])
|
|
59
|
+
for (const [k, v] of parsed) {
|
|
60
|
+
if (this._dict.has(k)) {
|
|
61
|
+
const prev = this._dict.get(k)
|
|
62
|
+
throw new MetadataError(`Duplicate entry for ${k}, was ${prev} now ${v}`, {
|
|
63
|
+
key: (k as any).str
|
|
51
64
|
})
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
}
|
|
65
|
+
}
|
|
66
|
+
this._dict.set(k, v)
|
|
67
|
+
}
|
|
68
|
+
return this
|
|
55
69
|
}
|
|
56
70
|
|
|
57
71
|
equals(other: Meta.Input) {
|
|
58
|
-
return this._dict
|
|
72
|
+
return equalsMap(this._dict, make(other)._dict)
|
|
59
73
|
}
|
|
60
74
|
|
|
61
75
|
section(key: string) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
})
|
|
76
|
+
const newS = seq(this).map(([k, v]) => [k.section(key), v] as const)
|
|
77
|
+
return parseMetaInput(newS)
|
|
65
78
|
}
|
|
66
79
|
|
|
67
|
-
overwrite(key: Key.Value, value: string): Meta
|
|
80
|
+
overwrite(key: Key.Value, value: string | undefined): Meta
|
|
68
81
|
overwrite(key: Key.Section, value: MetaInputParts.Nested): Meta
|
|
69
82
|
overwrite(input?: InputMeta): Meta
|
|
70
83
|
overwrite(a?: any, b?: any) {
|
|
71
84
|
if (a === undefined) {
|
|
72
85
|
return this
|
|
73
86
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
87
|
+
const fromPair = _pairToMap([a, b])
|
|
88
|
+
for (const [k, v] of fromPair.entries()) {
|
|
89
|
+
this._dict.set(k, v)
|
|
90
|
+
}
|
|
91
|
+
return this
|
|
78
92
|
}
|
|
79
93
|
|
|
80
94
|
has<X extends Key.Value>(key: X) {
|
|
81
95
|
const parsed = parseKey(key)
|
|
82
96
|
if (parsed instanceof ValueKey) {
|
|
83
|
-
return this._dict.has(
|
|
97
|
+
return this._dict.has(key)
|
|
84
98
|
} else {
|
|
85
99
|
return this._matchSectionKeys(parsed).size > 0
|
|
86
100
|
}
|
|
@@ -88,7 +102,7 @@ export namespace Meta {
|
|
|
88
102
|
|
|
89
103
|
get(key: Key.Value) {
|
|
90
104
|
const parsed = parseKey(key)
|
|
91
|
-
const v = this._dict.get(
|
|
105
|
+
const v = this._dict.get(key)
|
|
92
106
|
if (v === undefined) {
|
|
93
107
|
throw new MetadataError(`Key ${key} not found!`, { key })
|
|
94
108
|
}
|
|
@@ -100,34 +114,44 @@ export namespace Meta {
|
|
|
100
114
|
if (!(parsed instanceof ValueKey)) {
|
|
101
115
|
throw new MetadataError("Unexpected section key!", { key })
|
|
102
116
|
}
|
|
103
|
-
return this._dict.get(
|
|
117
|
+
return this._dict.get(key) ?? fallback
|
|
104
118
|
}
|
|
105
119
|
|
|
106
120
|
private _matchSectionKeys(key: SectionKey) {
|
|
107
|
-
return this
|
|
121
|
+
return seq(this)
|
|
122
|
+
.filter(([k, v]) => k.parent?.equals(key) ?? false)
|
|
123
|
+
.toMap(x => [x[0].str, x[1]] as const)
|
|
124
|
+
.pull()
|
|
108
125
|
}
|
|
109
126
|
|
|
110
127
|
pick(...keySpecs: Key.Key[]) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
128
|
+
const parsed = keySpecs.map(parseKey)
|
|
129
|
+
const keyStrSet = new Set<string>()
|
|
130
|
+
for (const key of parsed) {
|
|
131
|
+
if (key instanceof ValueKey) {
|
|
132
|
+
keyStrSet.add(key.str)
|
|
133
|
+
} else {
|
|
134
|
+
const sectionKeys = this._matchSectionKeys(key)
|
|
135
|
+
for (const k of sectionKeys.keys()) {
|
|
136
|
+
keyStrSet.add(k)
|
|
120
137
|
}
|
|
121
138
|
}
|
|
122
|
-
|
|
123
|
-
|
|
139
|
+
}
|
|
140
|
+
const out = new Map<string, string>()
|
|
141
|
+
for (const [k, v] of this._dict.entries()) {
|
|
142
|
+
if (keyStrSet.has(k)) out.set(k, v)
|
|
143
|
+
}
|
|
144
|
+
return this._create(out)
|
|
124
145
|
}
|
|
125
146
|
|
|
126
147
|
private _prefixed(prefix: string) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
148
|
+
const out: { [k: string]: string } = {}
|
|
149
|
+
for (const [k, v] of this) {
|
|
150
|
+
if (k._prefix === prefix) {
|
|
151
|
+
out[k.suffix] = v
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return orderMetaKeyedObject(out)
|
|
131
155
|
}
|
|
132
156
|
|
|
133
157
|
get labels() {
|
|
@@ -143,7 +167,14 @@ export namespace Meta {
|
|
|
143
167
|
}
|
|
144
168
|
|
|
145
169
|
get values() {
|
|
146
|
-
return this._dict
|
|
170
|
+
return toJS(this._dict)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
get keys(): ValueKey[] {
|
|
174
|
+
return seq(this)
|
|
175
|
+
.map(([k, v]) => k)
|
|
176
|
+
.toArray()
|
|
177
|
+
.pull()
|
|
147
178
|
}
|
|
148
179
|
|
|
149
180
|
get core() {
|
|
@@ -155,14 +186,25 @@ export namespace Meta {
|
|
|
155
186
|
remove(ns: Key.Section, key: string): this
|
|
156
187
|
remove(ns: Key.Section): this
|
|
157
188
|
remove(a: any, b?: any) {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
189
|
+
const parsed = parseKey(a)
|
|
190
|
+
if (parsed instanceof ValueKey) {
|
|
191
|
+
this._dict.delete(parsed.str)
|
|
192
|
+
return this
|
|
193
|
+
}
|
|
194
|
+
if (b !== undefined) {
|
|
195
|
+
// remove specific key from section
|
|
196
|
+
for (const k of this.keys) {
|
|
197
|
+
if (k.parent?.equals(parsed) && k.suffix === b) {
|
|
198
|
+
this._dict.delete(k.str)
|
|
199
|
+
}
|
|
164
200
|
}
|
|
165
|
-
|
|
201
|
+
return this
|
|
202
|
+
}
|
|
203
|
+
// remove entire section
|
|
204
|
+
for (const k of this.keys) {
|
|
205
|
+
if (k.parent?.equals(parsed)) this._dict.delete(k.str)
|
|
206
|
+
}
|
|
207
|
+
return this
|
|
166
208
|
}
|
|
167
209
|
|
|
168
210
|
expand() {
|
|
@@ -175,10 +217,6 @@ export namespace Meta {
|
|
|
175
217
|
annotations
|
|
176
218
|
}
|
|
177
219
|
}
|
|
178
|
-
|
|
179
|
-
toMutable() {
|
|
180
|
-
return new MutableMeta(this)
|
|
181
|
-
}
|
|
182
220
|
}
|
|
183
221
|
|
|
184
222
|
export function make(key: Key.Value, value: string): Meta
|
|
@@ -187,11 +225,9 @@ export namespace Meta {
|
|
|
187
225
|
export function make(a?: any, b?: any) {
|
|
188
226
|
return new Meta(_pairToMap([a, b]))
|
|
189
227
|
}
|
|
190
|
-
function _pairToObject(pair: [string, string | object] | [object]) {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
return Map(key)
|
|
194
|
-
}
|
|
228
|
+
function _pairToObject(pair: [string | ValueKey, string | object] | [object]) {
|
|
229
|
+
let [key, value] = pair
|
|
230
|
+
key = key instanceof ValueKey ? key.str : key
|
|
195
231
|
if (typeof key === "string") {
|
|
196
232
|
return {
|
|
197
233
|
[key]: value as string
|
|
@@ -199,11 +235,8 @@ export namespace Meta {
|
|
|
199
235
|
}
|
|
200
236
|
return key
|
|
201
237
|
}
|
|
202
|
-
function _pairToMap(pair: [string, string | object] | [object]) {
|
|
203
|
-
return parseMetaInput(_pairToObject(pair))
|
|
204
|
-
}
|
|
205
|
-
export function makeMutable(input: InputMeta = {}) {
|
|
206
|
-
return make(input).toMutable()
|
|
238
|
+
function _pairToMap(pair: [string | ValueKey, string | object] | [object]) {
|
|
239
|
+
return parseMetaInput(_pairToObject(pair))
|
|
207
240
|
}
|
|
208
241
|
|
|
209
242
|
export function splat(...input: InputMeta[]) {
|
|
@@ -214,77 +247,15 @@ export namespace Meta {
|
|
|
214
247
|
return value instanceof Meta
|
|
215
248
|
}
|
|
216
249
|
|
|
217
|
-
export class MutableMeta {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
remove(key: Key.Value): this
|
|
229
|
-
remove(ns: Key.Section, key: string): this
|
|
230
|
-
remove(ns: Key.Section): this
|
|
231
|
-
remove(a: any, b?: any) {
|
|
232
|
-
this._meta = this._meta.remove(a, b)
|
|
233
|
-
return this
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
overwrite(key: Key.Value, value: string): this
|
|
237
|
-
overwrite(key: Key.Section, value: MetaInputParts.Nested): this
|
|
238
|
-
overwrite(input?: InputMeta): this
|
|
239
|
-
overwrite(a?: any, b?: any) {
|
|
240
|
-
this._meta = this._meta.overwrite(a, b)
|
|
241
|
-
return this
|
|
242
|
-
}
|
|
243
|
-
equals(other: Meta.Input) {
|
|
244
|
-
return this._meta.equals(other)
|
|
245
|
-
}
|
|
246
|
-
get(key: Key.Value) {
|
|
247
|
-
return this._meta.get(key)
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
tryGet(key: Key.Value, fallback?: string) {
|
|
251
|
-
return this._meta.tryGet(key, fallback)
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
has(key: Key.Value) {
|
|
255
|
-
return this._meta.has(key)
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
pick(...keySpecs: Key.Key[]) {
|
|
259
|
-
const newMeta = this._meta.pick(...keySpecs)
|
|
260
|
-
return new MutableMeta(newMeta)
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
toMutable() {
|
|
264
|
-
return new MutableMeta(this._meta)
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
section(key: string) {
|
|
268
|
-
return new MutableMeta(this._meta.section(key))
|
|
269
|
-
}
|
|
270
|
-
get labels() {
|
|
271
|
-
return this._meta.labels
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
get annotations() {
|
|
275
|
-
return this._meta.annotations
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
get comments() {
|
|
279
|
-
return this._meta.comments
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
get core() {
|
|
283
|
-
return this._meta.core
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
toImmutable() {
|
|
287
|
-
return this._meta
|
|
250
|
+
export class MutableMeta extends Meta {
|
|
251
|
+
// MutableMeta is now just a direct extension of Meta so callers
|
|
252
|
+
// that expect MutableMeta keep working. The class body is empty
|
|
253
|
+
// because all mutation behavior lives on `Meta` itself.
|
|
254
|
+
constructor(...args: any[]) {
|
|
255
|
+
// Construct as a Meta instance. `Meta` constructor signature
|
|
256
|
+
// expects a Map<ValueKey, string> which callers provide when
|
|
257
|
+
// creating mutable instances.
|
|
258
|
+
super(args[0])
|
|
288
259
|
}
|
|
289
260
|
}
|
|
290
261
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { seq } from "doddle"
|
|
2
|
+
|
|
3
|
+
function comparisonKey(key: string) {
|
|
4
|
+
const bySlash = key.split("/")
|
|
5
|
+
if (bySlash.length === 1) {
|
|
6
|
+
return key
|
|
7
|
+
}
|
|
8
|
+
if (bySlash.length > 2) {
|
|
9
|
+
throw new Error(`Invalid composed key ${key}, too many '/' characters.`)
|
|
10
|
+
}
|
|
11
|
+
const [dns, name] = bySlash
|
|
12
|
+
const dnsParts = dns.split(".").reverse()
|
|
13
|
+
return [...dnsParts, name].join("\uffff")
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function orderMetaKeyedObject(input: Record<string, string>): Record<string, any> {
|
|
17
|
+
const entries = seq(Object.entries(input)).orderBy(([key]) => comparisonKey(key))
|
|
18
|
+
|
|
19
|
+
return Object.fromEntries(entries)
|
|
20
|
+
}
|
package/src/util.ts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
type Pair<X> = [X, X]
|
|
2
|
+
export function mergeWith<K1, K2, V1, V2, V3>(
|
|
3
|
+
map1: Map<K1, V1>,
|
|
4
|
+
map2: Map<K2, V2>,
|
|
5
|
+
merger: (val1: V1, val2: V2, key: K1 | K2) => V3
|
|
6
|
+
): Map<K1 | K2, V1 | V2 | V3> {
|
|
7
|
+
const result = new Map<K1 | K2, V1 | V2 | V3>(map1)
|
|
8
|
+
const allKeys = new Set<K1 | K2>([...map1.keys(), ...map2.keys()])
|
|
9
|
+
for (const k of allKeys) {
|
|
10
|
+
const val1 = map1.get(k as K1)
|
|
11
|
+
const val2 = map2.get(k as K2)
|
|
12
|
+
if (val1 !== undefined && val2 !== undefined) {
|
|
13
|
+
result.set(k, merger(val1, val2, k))
|
|
14
|
+
} else if (val2 !== undefined) {
|
|
15
|
+
result.set(k, val2)
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return result
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function merge<K1, K2, V1, V2>(map1: Map<K1, V1>, map2: Map<K2, V2>): Map<K1 | K2, V1 | V2> {
|
|
22
|
+
return mergeWith(map1, map2, (_old, _new) => _new)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function filterMap<K, V>(map: Map<K, V>, pred: (v: V, k: K) => boolean): Map<K, V> {
|
|
26
|
+
const out = new Map<K, V>()
|
|
27
|
+
for (const [k, v] of map.entries()) {
|
|
28
|
+
if (pred(v, k)) out.set(k, v)
|
|
29
|
+
}
|
|
30
|
+
return out
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function mapKeys<K, V, NK>(map: Map<K, V>, fn: (k: K) => NK): Map<NK, V> {
|
|
34
|
+
const out = new Map<NK, V>()
|
|
35
|
+
for (const [k, v] of map.entries()) {
|
|
36
|
+
out.set(fn(k), v)
|
|
37
|
+
}
|
|
38
|
+
return out
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function mapValues<K, V, NV>(map: Map<K, V>, fn: (v: V, k: K) => NV): Map<K, NV> {
|
|
42
|
+
const out = new Map<K, NV>()
|
|
43
|
+
for (const [k, v] of map.entries()) {
|
|
44
|
+
out.set(k, fn(v, k))
|
|
45
|
+
}
|
|
46
|
+
return out
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function toObject<K, V>(map: Map<K, V>): { [k: string]: V } {
|
|
50
|
+
const out: { [k: string]: V } = {}
|
|
51
|
+
for (const [k, v] of map.entries()) {
|
|
52
|
+
const key = (k as any)?.str ?? String(k)
|
|
53
|
+
out[key] = v
|
|
54
|
+
}
|
|
55
|
+
return out
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function toJS<K, V>(map: Map<K, V>): { [k: string]: V } {
|
|
59
|
+
return toObject(map)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function equalsMap<K, V>(a: Map<K, V>, b: Map<K, V>): boolean {
|
|
63
|
+
if (a.size !== b.size) return false
|
|
64
|
+
for (const [ka, va] of a.entries()) {
|
|
65
|
+
let found = false
|
|
66
|
+
for (const [kb, vb] of b.entries()) {
|
|
67
|
+
const sa = (ka as any)?.str ?? ka
|
|
68
|
+
const sb = (kb as any)?.str ?? kb
|
|
69
|
+
if (sa === sb) {
|
|
70
|
+
found = true
|
|
71
|
+
if (va !== vb) return false
|
|
72
|
+
break
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (!found) return false
|
|
76
|
+
}
|
|
77
|
+
return true
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function mapFromObject<V>(obj: { [k: string]: V }): Map<string, V> {
|
|
81
|
+
const map = new Map<string, V>()
|
|
82
|
+
for (const k of Object.keys(obj)) {
|
|
83
|
+
map.set(k, obj[k])
|
|
84
|
+
}
|
|
85
|
+
return map
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function mapToObject<V>(map: Map<string, V>): { [k: string]: V } {
|
|
89
|
+
const obj: { [k: string]: V } = {}
|
|
90
|
+
for (const [k, v] of map.entries()) {
|
|
91
|
+
obj[k] = v
|
|
92
|
+
}
|
|
93
|
+
return obj
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export type SourcedPropertyDescriptor = PropertyDescriptor & {
|
|
97
|
+
source: object
|
|
98
|
+
}
|
|
99
|
+
export function getDeepPropertyDescriptor(
|
|
100
|
+
obj: any,
|
|
101
|
+
propertyKey: string | symbol
|
|
102
|
+
): SourcedPropertyDescriptor | undefined {
|
|
103
|
+
let current = obj
|
|
104
|
+
while (current) {
|
|
105
|
+
const descriptor = Object.getOwnPropertyDescriptor(current, propertyKey)
|
|
106
|
+
if (descriptor) {
|
|
107
|
+
return {
|
|
108
|
+
...descriptor,
|
|
109
|
+
source: current
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
current = Object.getPrototypeOf(current)
|
|
113
|
+
}
|
|
114
|
+
return undefined
|
|
115
|
+
}
|
package/dist/key/convert.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../../src/key/convert.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAEtC,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC;;EAEtD"}
|
package/dist/key/convert.js
DELETED
package/dist/key/convert.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"convert.js","sourceRoot":"","sources":["../../src/key/convert.ts"],"names":[],"mappings":";;AAGA,oCAEC;AAFD,SAAgB,YAAY,CAAC,GAA0B;IACnD,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAA;AAC7C,CAAC"}
|
package/dist/mutable-meta.d.ts
DELETED