@xyo-network/payload-builder 3.5.2 → 3.6.0-rc.2
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/browser/Builder.d.ts +19 -25
- package/dist/browser/Builder.d.ts.map +1 -1
- package/dist/browser/BuilderBase.d.ts +15 -13
- package/dist/browser/BuilderBase.d.ts.map +1 -1
- package/dist/browser/Options.d.ts +1 -1
- package/dist/browser/Options.d.ts.map +1 -1
- package/dist/browser/index.mjs +87 -140
- package/dist/browser/index.mjs.map +1 -1
- package/dist/neutral/Builder.d.ts +19 -25
- package/dist/neutral/Builder.d.ts.map +1 -1
- package/dist/neutral/BuilderBase.d.ts +15 -13
- package/dist/neutral/BuilderBase.d.ts.map +1 -1
- package/dist/neutral/Options.d.ts +1 -1
- package/dist/neutral/Options.d.ts.map +1 -1
- package/dist/neutral/index.mjs +87 -140
- package/dist/neutral/index.mjs.map +1 -1
- package/dist/node/Builder.d.ts +19 -25
- package/dist/node/Builder.d.ts.map +1 -1
- package/dist/node/BuilderBase.d.ts +15 -13
- package/dist/node/BuilderBase.d.ts.map +1 -1
- package/dist/node/Options.d.ts +1 -1
- package/dist/node/Options.d.ts.map +1 -1
- package/dist/node/index.mjs +87 -140
- package/dist/node/index.mjs.map +1 -1
- package/package.json +12 -11
- package/src/Builder.ts +92 -140
- package/src/BuilderBase.ts +41 -50
- package/src/Options.ts +1 -1
package/src/Builder.ts
CHANGED
|
@@ -1,96 +1,92 @@
|
|
|
1
1
|
import { assertEx } from '@xylabs/assert'
|
|
2
|
-
import type { Hash } from '@xylabs/hex'
|
|
3
2
|
import type {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
Hash,
|
|
4
|
+
Hex,
|
|
5
|
+
} from '@xylabs/hex'
|
|
6
|
+
import {
|
|
7
|
+
isHash, isHex, toHex,
|
|
8
|
+
} from '@xylabs/hex'
|
|
9
|
+
import type { AnyObject } from '@xylabs/object'
|
|
10
|
+
import { ObjectHasher } from '@xyo-network/hash'
|
|
11
|
+
import {
|
|
12
|
+
type Payload, StorageMetaConstants, type WithStorageMeta,
|
|
10
13
|
} from '@xyo-network/payload-model'
|
|
11
14
|
|
|
12
|
-
import
|
|
13
|
-
import { PayloadBuilderBase, removeMetaAndSchema } from './BuilderBase.ts'
|
|
15
|
+
import { PayloadBuilderBase } from './BuilderBase.ts'
|
|
14
16
|
import type { PayloadBuilderOptions } from './Options.ts'
|
|
15
17
|
|
|
16
|
-
export interface BuildOptions {
|
|
17
|
-
stamp?: boolean
|
|
18
|
-
validate?: boolean
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const omitByPredicate = <T extends object>(prefix: string) => (_: T[keyof T], key: keyof T) => {
|
|
22
|
-
assertEx(typeof key === 'string', () => `Invalid key type [${String(key)}, ${typeof key}]`)
|
|
23
|
-
return (key as string).startsWith(prefix)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
18
|
export class PayloadBuilder<
|
|
27
19
|
T extends Payload = Payload<AnyObject>,
|
|
28
20
|
O extends PayloadBuilderOptions<T> = PayloadBuilderOptions<T>,
|
|
29
21
|
> extends PayloadBuilderBase<T, O> {
|
|
30
|
-
static async
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
} = payload as WithMeta<T>
|
|
40
|
-
|
|
41
|
-
// check for legacy signatures
|
|
42
|
-
const { _signatures } = payload as { _signatures?: JsonArray }
|
|
43
|
-
if (_signatures && !incomingMeta.signatures) {
|
|
44
|
-
incomingMeta.signatures = _signatures
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const fields = removeMetaAndSchema(payload)
|
|
48
|
-
const dataHashableFields = await PayloadBuilder.dataHashableFields(schema, fields)
|
|
49
|
-
const $hash = validate || incomingDataHash === undefined ? await PayloadHasher.hash(dataHashableFields) : incomingDataHash
|
|
50
|
-
const $meta: JsonObject = { ...incomingMeta }
|
|
51
|
-
if ($meta.timestamp === undefined && stamp) {
|
|
52
|
-
$meta.timestamp = Date.now()
|
|
53
|
-
}
|
|
54
|
-
const hashableFields: WithMeta<Payload> = {
|
|
55
|
-
...dataHashableFields, $hash, schema,
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (Object.keys($meta).length > 0) {
|
|
59
|
-
hashableFields.$meta = $meta
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return hashableFields as WithMeta<T>
|
|
22
|
+
static async addSequencedStorageMeta<T extends Payload = Payload>(payload: T, hash?: Hash, dataHash?: Hash): Promise<WithStorageMeta<T>> {
|
|
23
|
+
assertEx(hash === undefined || isHash(hash), () => 'Invalid hash')
|
|
24
|
+
assertEx(dataHash === undefined || isHash(dataHash), () => 'Invalid dataHash')
|
|
25
|
+
const _hash = hash ?? await PayloadBuilder.hash(payload)
|
|
26
|
+
return {
|
|
27
|
+
...payload,
|
|
28
|
+
_sequence: this.buildSequence(Date.now(), _hash.slice(-(StorageMetaConstants.nonceBytes * 2)) as Hex),
|
|
29
|
+
_dataHash: dataHash ?? await PayloadBuilder.dataHash(payload),
|
|
30
|
+
_hash,
|
|
63
31
|
}
|
|
64
32
|
}
|
|
65
33
|
|
|
66
|
-
static async
|
|
67
|
-
|
|
34
|
+
static async addStorageMeta<T extends Payload>(payload: T): Promise<WithStorageMeta<T>>
|
|
35
|
+
static async addStorageMeta<T extends Payload>(payloads: T[]): Promise<WithStorageMeta<T>[]>
|
|
36
|
+
static async addStorageMeta<T extends Payload>(payloads: T | T[]): Promise<WithStorageMeta<T>[] | WithStorageMeta<T>> {
|
|
37
|
+
return Array.isArray(payloads)
|
|
38
|
+
? await (async () => {
|
|
39
|
+
const pairs = await PayloadBuilder.hashPairs(payloads)
|
|
40
|
+
return await Promise.all(pairs.map(async ([payload, hash]) => await this.addSequencedStorageMeta(
|
|
41
|
+
payload,
|
|
42
|
+
hash,
|
|
43
|
+
)))
|
|
44
|
+
})()
|
|
45
|
+
: this.addSequencedStorageMeta(
|
|
46
|
+
payloads,
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static buildSequence(epoch: number, nonce: Hex): Hex {
|
|
51
|
+
assertEx(
|
|
52
|
+
epoch <= StorageMetaConstants.maxEpoch,
|
|
53
|
+
() => `epoch must be less than or equal to ${StorageMetaConstants.maxEpoch} [${epoch}]`,
|
|
54
|
+
)
|
|
55
|
+
assertEx(isHex(nonce), () => 'nonce must be a Hex type')
|
|
56
|
+
assertEx(
|
|
57
|
+
nonce.length === StorageMetaConstants.nonceBytes * 2,
|
|
58
|
+
() => `nonce must be ${StorageMetaConstants.nonceBytes} bytes [${nonce.length}] <- Hex String Length`,
|
|
59
|
+
)
|
|
60
|
+
return `${toHex(epoch, { byteSize: 4 })}${nonce}` as Hex
|
|
68
61
|
}
|
|
69
62
|
|
|
70
|
-
static async
|
|
63
|
+
static async dataHash<T extends Payload>(payload: T): Promise<Hash> {
|
|
64
|
+
return await ObjectHasher.hash(this.omitMeta(payload))
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static async dataHashPairs<T extends Payload>(payloads: T[]): Promise<[T, Hash][]> {
|
|
71
68
|
return await Promise.all(
|
|
72
69
|
payloads.map(async (payload) => {
|
|
73
|
-
const
|
|
74
|
-
return [
|
|
70
|
+
const dataHash = await this.dataHash(payload)
|
|
71
|
+
return [payload, dataHash]
|
|
75
72
|
}),
|
|
76
73
|
)
|
|
77
74
|
}
|
|
78
75
|
|
|
79
|
-
static async dataHashes(payloads: undefined
|
|
80
|
-
static async dataHashes<T extends Payload>(payloads: T[]
|
|
81
|
-
static async dataHashes<T extends Payload>(payloads?: T[]
|
|
76
|
+
static async dataHashes(payloads: undefined): Promise<undefined>
|
|
77
|
+
static async dataHashes<T extends Payload>(payloads: T[]): Promise<Hash[]>
|
|
78
|
+
static async dataHashes<T extends Payload>(payloads?: T[]): Promise<Hash[] | undefined> {
|
|
82
79
|
return payloads
|
|
83
80
|
? await Promise.all(
|
|
84
81
|
payloads.map(async (payload) => {
|
|
85
|
-
|
|
86
|
-
return built.$hash
|
|
82
|
+
return await PayloadBuilder.dataHash(payload)
|
|
87
83
|
}),
|
|
88
84
|
)
|
|
89
85
|
: undefined
|
|
90
86
|
}
|
|
91
87
|
|
|
92
88
|
static async filterExclude<T extends Payload>(payloads: T[] = [], hash: Hash[] | Hash): Promise<T[]> {
|
|
93
|
-
return await
|
|
89
|
+
return await ObjectHasher.filterExcludeByHash(await this.filterExcludeByDataHash(payloads, hash), hash)
|
|
94
90
|
}
|
|
95
91
|
|
|
96
92
|
static async filterExcludeByDataHash<T extends Payload>(payloads: T[] = [], hash: Hash[] | Hash): Promise<T[]> {
|
|
@@ -107,8 +103,8 @@ export class PayloadBuilder<
|
|
|
107
103
|
return (await this.dataHashPairs(payloads)).find(([_, objHash]) => objHash === hash)?.[0]
|
|
108
104
|
}
|
|
109
105
|
|
|
110
|
-
static async hash<T extends Payload>(payload: T
|
|
111
|
-
return await
|
|
106
|
+
static async hash<T extends Payload>(payload: T): Promise<Hash> {
|
|
107
|
+
return await ObjectHasher.hash(this.omitStorageMeta(payload))
|
|
112
108
|
}
|
|
113
109
|
|
|
114
110
|
/**
|
|
@@ -116,68 +112,47 @@ export class PayloadBuilder<
|
|
|
116
112
|
* @param objs Any array of payloads
|
|
117
113
|
* @returns An array of payload/hash tuples
|
|
118
114
|
*/
|
|
119
|
-
static async hashPairs<T extends Payload>(payloads: T[]
|
|
115
|
+
static async hashPairs<T extends Payload>(payloads: T[]): Promise<[T, Hash][]> {
|
|
120
116
|
return await Promise.all(
|
|
121
|
-
payloads.map<Promise<[
|
|
122
|
-
|
|
123
|
-
return [built, await PayloadBuilder.hash(built)]
|
|
117
|
+
payloads.map<Promise<[T, Hash]>>(async (payload) => {
|
|
118
|
+
return [payload, await PayloadBuilder.hash(payload)]
|
|
124
119
|
}),
|
|
125
120
|
)
|
|
126
121
|
}
|
|
127
122
|
|
|
128
|
-
static
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
$hash?: Hash,
|
|
133
|
-
timestamp?: number,
|
|
134
|
-
stamp = false,
|
|
135
|
-
): Promise<WithMeta<T>> {
|
|
136
|
-
const dataFields = await this.dataHashableFields<T>(schema, fields)
|
|
137
|
-
assertEx($meta === undefined || isJsonObject($meta), () => '$meta must be JsonObject')
|
|
138
|
-
const result: WithMeta<T> = omitBy(
|
|
139
|
-
{
|
|
140
|
-
...dataFields,
|
|
141
|
-
$hash: $hash ?? (await PayloadBuilder.dataHash(dataFields)),
|
|
142
|
-
schema,
|
|
143
|
-
} as WithMeta<T>,
|
|
144
|
-
omitByPredicate('_'),
|
|
145
|
-
) as WithMeta<T>
|
|
146
|
-
|
|
147
|
-
const clonedMeta = { ...$meta }
|
|
148
|
-
|
|
149
|
-
if (timestamp) {
|
|
150
|
-
clonedMeta.timestamp = timestamp
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (clonedMeta.timestamp === undefined && stamp) {
|
|
154
|
-
clonedMeta.timestamp = Date.now()
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
if (Object.keys(clonedMeta).length > 0) {
|
|
158
|
-
result.$meta = clonedMeta
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
return result
|
|
123
|
+
static hashableFields<T extends Payload>(
|
|
124
|
+
payload: T,
|
|
125
|
+
): T {
|
|
126
|
+
return this.omitStorageMeta(payload)
|
|
162
127
|
}
|
|
163
128
|
|
|
164
129
|
static async hashes(payloads: undefined): Promise<undefined>
|
|
165
130
|
static async hashes<T extends Payload>(payloads: T[]): Promise<Hash[]>
|
|
166
131
|
static async hashes<T extends Payload>(payloads?: T[]): Promise<Hash[] | undefined> {
|
|
167
|
-
return await
|
|
132
|
+
return await ObjectHasher.hashes(payloads)
|
|
168
133
|
}
|
|
169
134
|
|
|
170
|
-
static
|
|
171
|
-
|
|
172
|
-
|
|
135
|
+
static sortByStorageMeta<T extends Payload>(payloads: WithStorageMeta<T>[], direction: -1 | 1 = 1) {
|
|
136
|
+
return payloads.sort((a, b) =>
|
|
137
|
+
a._sequence < b._sequence
|
|
138
|
+
? -direction
|
|
139
|
+
: a._sequence > b._sequence
|
|
140
|
+
? direction
|
|
141
|
+
: 0)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
static async toAllHashMap<T extends Payload>(payloads: T[]): Promise<Record<Hash, T>> {
|
|
145
|
+
const result: Record<Hash, T> = {}
|
|
146
|
+
for (const pair of await this.hashPairs(payloads)) {
|
|
147
|
+
const dataHash = await this.dataHash(pair[0])
|
|
173
148
|
result[pair[1]] = pair[0]
|
|
174
|
-
result[
|
|
149
|
+
result[dataHash] = pair[0]
|
|
175
150
|
}
|
|
176
151
|
return result
|
|
177
152
|
}
|
|
178
153
|
|
|
179
|
-
static async toDataHashMap<T extends Payload>(objs: T[]): Promise<Record<Hash,
|
|
180
|
-
const result: Record<Hash,
|
|
154
|
+
static async toDataHashMap<T extends Payload>(objs: T[]): Promise<Record<Hash, T>> {
|
|
155
|
+
const result: Record<Hash, T> = {}
|
|
181
156
|
for (const pair of await this.dataHashPairs(objs)) {
|
|
182
157
|
result[pair[1]] = pair[0]
|
|
183
158
|
}
|
|
@@ -189,41 +164,18 @@ export class PayloadBuilder<
|
|
|
189
164
|
* @param objs Any array of payloads
|
|
190
165
|
* @returns A map of hashes to payloads
|
|
191
166
|
*/
|
|
192
|
-
static async toHashMap<T extends Payload>(objs: T[]): Promise<Record<Hash,
|
|
193
|
-
const result: Record<Hash,
|
|
167
|
+
static async toHashMap<T extends Payload>(objs: T[]): Promise<Record<Hash, T>> {
|
|
168
|
+
const result: Record<Hash, T> = {}
|
|
194
169
|
for (const pair of await this.hashPairs(objs)) {
|
|
195
170
|
result[pair[1]] = pair[0]
|
|
196
171
|
}
|
|
197
172
|
return result
|
|
198
173
|
}
|
|
199
174
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
return payloads.map(payload => this.withoutMeta(payload))
|
|
206
|
-
} else {
|
|
207
|
-
if (payloads) {
|
|
208
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
209
|
-
const { $meta, ...result } = payloads
|
|
210
|
-
return result as Omit<T, '$meta'>
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
async build(options?: BuildOptions): Promise<WithMeta<T>> {
|
|
216
|
-
const dataHashableFields = await this.dataHashableFields()
|
|
217
|
-
return await PayloadBuilder.build<T>({
|
|
218
|
-
...dataHashableFields, $meta: this._$meta, schema: this._schema,
|
|
219
|
-
} as Payload as T, options)
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
async hashableFields() {
|
|
223
|
-
return await PayloadBuilder.hashableFields(
|
|
224
|
-
assertEx(this._schema, () => 'Payload: Missing Schema'),
|
|
225
|
-
this._fields,
|
|
226
|
-
this._$meta,
|
|
227
|
-
)
|
|
175
|
+
build(): T {
|
|
176
|
+
return {
|
|
177
|
+
schema: this._schema,
|
|
178
|
+
...this._fields,
|
|
179
|
+
} as T
|
|
228
180
|
}
|
|
229
181
|
}
|
package/src/BuilderBase.ts
CHANGED
|
@@ -1,98 +1,93 @@
|
|
|
1
1
|
import { assertEx } from '@xylabs/assert'
|
|
2
|
-
import type {
|
|
3
|
-
import type { AnyObject, JsonObject } from '@xylabs/object'
|
|
2
|
+
import type { AnyObject } from '@xylabs/object'
|
|
4
3
|
import {
|
|
5
4
|
isJsonObject, omitBy, toJson,
|
|
6
5
|
} from '@xylabs/object'
|
|
7
6
|
import type { Promisable } from '@xylabs/promise'
|
|
8
7
|
import { removeEmptyFields } from '@xyo-network/hash'
|
|
9
|
-
import type {
|
|
10
|
-
Payload, Schema, WithMeta, WithOptionalMeta,
|
|
11
|
-
} from '@xyo-network/payload-model'
|
|
8
|
+
import type { Payload, Schema } from '@xyo-network/payload-model'
|
|
12
9
|
|
|
10
|
+
import { PayloadBuilder } from './Builder.ts'
|
|
13
11
|
import type { PayloadBuilderOptions } from './Options.ts'
|
|
14
12
|
|
|
15
13
|
export type WithOptionalSchema<T extends Payload> = Omit<T, 'schema'> & Partial<T>
|
|
16
14
|
|
|
17
15
|
export type WithoutSchema<T extends WithOptionalSchema<Payload>> = Omit<T, 'schema'>
|
|
18
16
|
|
|
19
|
-
export
|
|
20
|
-
|
|
21
|
-
export const removeMetaAndSchema = <T extends Payload>(payload: WithOptionalSchema<WithOptionalMeta<T>>): WithoutSchema<WithoutMeta<T>> => {
|
|
22
|
-
const { ...result } = payload
|
|
23
|
-
delete result.$hash
|
|
24
|
-
delete result.$meta
|
|
17
|
+
export const removeMetaAndSchema = <T extends Payload>(payload: Partial<WithOptionalSchema<T>>): WithoutSchema<T> => {
|
|
18
|
+
const { ...result } = PayloadBuilder.omitMeta(payload as T) as WithOptionalSchema<T>
|
|
25
19
|
delete result.schema
|
|
26
20
|
return result as Omit<T, 'schema'>
|
|
27
21
|
}
|
|
28
22
|
|
|
29
|
-
const
|
|
23
|
+
const omitByPrefixPredicate = (prefix: string) => (_: unknown, key: string) => {
|
|
30
24
|
assertEx(typeof key === 'string', () => `Invalid key type [${key}, ${typeof key}]`)
|
|
31
25
|
return key.startsWith(prefix)
|
|
32
26
|
}
|
|
33
27
|
|
|
34
28
|
export class PayloadBuilderBase<T extends Payload = Payload<AnyObject>, O extends PayloadBuilderOptions<T> = PayloadBuilderOptions<T>> {
|
|
35
|
-
protected
|
|
36
|
-
protected _fields?: WithoutSchema<WithoutMeta<T>>
|
|
29
|
+
protected _fields?: Partial<WithoutSchema<T>>
|
|
37
30
|
protected _schema: Schema
|
|
38
31
|
|
|
39
32
|
constructor(readonly options: O) {
|
|
40
|
-
const {
|
|
41
|
-
schema, fields, meta,
|
|
42
|
-
} = options
|
|
33
|
+
const { schema, fields } = options
|
|
43
34
|
this._schema = schema
|
|
44
|
-
this._fields = removeEmptyFields(fields ?? {})
|
|
45
|
-
this._$meta = meta
|
|
35
|
+
this._fields = removeMetaAndSchema(removeEmptyFields(structuredClone(fields ?? {})))
|
|
46
36
|
}
|
|
47
37
|
|
|
48
|
-
static dataHashableFields<T extends Payload
|
|
49
|
-
schema:
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
38
|
+
static dataHashableFields<T extends Payload>(
|
|
39
|
+
schema: Schema,
|
|
40
|
+
payload: WithoutSchema<T>,
|
|
41
|
+
|
|
42
|
+
): Promisable<Payload> {
|
|
43
|
+
const cleanFields = removeEmptyFields({ ...payload, schema })
|
|
53
44
|
assertEx(
|
|
54
45
|
cleanFields === undefined || isJsonObject(cleanFields),
|
|
55
46
|
() => `Fields must be JsonObject: ${JSON.stringify(toJson(cleanFields), null, 2)}`,
|
|
56
47
|
)
|
|
57
|
-
return
|
|
48
|
+
return this.omitMeta(cleanFields) as T
|
|
58
49
|
}
|
|
59
50
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
51
|
+
static omitClientMeta<T extends Payload>(payload: T, maxDepth?: number): T
|
|
52
|
+
static omitClientMeta<T extends Payload>(payloads: T[], maxDepth?: number): T[]
|
|
53
|
+
static omitClientMeta<T extends Payload>(payloads: T | T[], maxDepth = 100): T | T[] {
|
|
54
|
+
return Array.isArray(payloads)
|
|
55
|
+
? payloads.map(payload => this.omitClientMeta(payload, maxDepth)) as T[]
|
|
56
|
+
: omitBy(payloads, omitByPrefixPredicate('$'), maxDepth) as T
|
|
57
|
+
}
|
|
66
58
|
|
|
67
|
-
|
|
59
|
+
static omitMeta<T extends Payload>(payload: T, maxDepth?: number): T
|
|
60
|
+
static omitMeta<T extends Payload>(payloads: T[], maxDepth?: number): T[]
|
|
61
|
+
static omitMeta<T extends Payload>(payloads: T | T[], maxDepth = 100): T | T[] {
|
|
62
|
+
return Array.isArray(payloads)
|
|
63
|
+
? this.omitStorageMeta(this.omitClientMeta(payloads, maxDepth), maxDepth)
|
|
64
|
+
: this.omitStorageMeta(this.omitClientMeta(payloads, maxDepth), maxDepth)
|
|
68
65
|
}
|
|
69
66
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
67
|
+
static omitStorageMeta<T extends Payload>(payload: T, maxDepth?: number): T
|
|
68
|
+
static omitStorageMeta<T extends Payload>(payloads: T[], maxDepth?: number): T[]
|
|
69
|
+
static omitStorageMeta<T extends Payload>(payloads: T | T[], maxDepth = 100): T | T[] {
|
|
70
|
+
return Array.isArray(payloads)
|
|
71
|
+
? payloads.map(payload => this.omitStorageMeta(payload, maxDepth)) as T[]
|
|
72
|
+
: omitBy(payloads, omitByPrefixPredicate('_'), maxDepth) as T
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
async dataHashableFields() {
|
|
76
76
|
return await PayloadBuilderBase.dataHashableFields(
|
|
77
77
|
assertEx(this._schema, () => 'Payload: Missing Schema'),
|
|
78
|
-
|
|
78
|
+
// TDOD: Add verification that required fields are present
|
|
79
|
+
this._fields as T,
|
|
79
80
|
)
|
|
80
81
|
}
|
|
81
82
|
|
|
82
|
-
|
|
83
|
-
fields(fields: WithOptionalSchema<WithOptionalMeta<T>>) {
|
|
83
|
+
fields(fields: WithOptionalSchema<T>) {
|
|
84
84
|
if (fields) {
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
$meta, $hash, schema, ...fieldsOnly
|
|
88
|
-
} = fields
|
|
89
|
-
if ($meta) {
|
|
90
|
-
this.$meta($meta)
|
|
91
|
-
}
|
|
85
|
+
const fieldsClone = structuredClone(fields)
|
|
86
|
+
const { schema } = fieldsClone
|
|
92
87
|
if (schema) {
|
|
93
88
|
this.schema(schema)
|
|
94
89
|
}
|
|
95
|
-
this._fields = removeMetaAndSchema<T>(
|
|
90
|
+
this._fields = removeEmptyFields(removeMetaAndSchema<T>(fieldsClone))
|
|
96
91
|
}
|
|
97
92
|
return this
|
|
98
93
|
}
|
|
@@ -100,8 +95,4 @@ export class PayloadBuilderBase<T extends Payload = Payload<AnyObject>, O extend
|
|
|
100
95
|
schema(value: Schema) {
|
|
101
96
|
this._schema = value
|
|
102
97
|
}
|
|
103
|
-
|
|
104
|
-
protected async metaFields(dataHash: Hash, stamp = true): Promise<JsonObject> {
|
|
105
|
-
return await PayloadBuilderBase.metaFields(dataHash, this._$meta, stamp)
|
|
106
|
-
}
|
|
107
98
|
}
|
package/src/Options.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { JsonObject } from '@xylabs/object'
|
|
|
3
3
|
import type { Schema } from '@xyo-network/payload-model'
|
|
4
4
|
|
|
5
5
|
export interface PayloadBuilderOptions<T> {
|
|
6
|
-
readonly fields?:
|
|
6
|
+
readonly fields?: Partial<T>
|
|
7
7
|
readonly logger?: Logger
|
|
8
8
|
readonly meta?: JsonObject
|
|
9
9
|
readonly schema: Schema
|