@mikrojs/native 0.18.0 → 0.18.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/CMakeLists.txt +62 -1
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -1
- package/dist/runtime/result/native-result.node-shim.d.ts +3 -0
- package/dist/runtime/result/native-result.node-shim.d.ts.map +1 -0
- package/dist/runtime/result/native-result.node-shim.js +41 -0
- package/dist/runtime/result/native-result.node-shim.js.map +1 -0
- package/dist/runtime/result/types.d.ts +55 -0
- package/dist/runtime/result/types.d.ts.map +1 -0
- package/dist/runtime/result/types.js +2 -0
- package/dist/runtime/result/types.js.map +1 -0
- package/dist/runtime/schema/core.d.ts +115 -0
- package/dist/runtime/schema/core.d.ts.map +1 -0
- package/dist/runtime/schema/core.js +259 -0
- package/dist/runtime/schema/core.js.map +1 -0
- package/dist/runtime/schema/shared.d.ts +54 -0
- package/dist/runtime/schema/shared.d.ts.map +1 -0
- package/dist/runtime/schema/shared.js +489 -0
- package/dist/runtime/schema/shared.js.map +1 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/include/mikrojs/cbor_helpers.h +20 -0
- package/include/mikrojs/mem.h +11 -0
- package/include/mikrojs/mikrojs.h +2 -1
- package/include/mikrojs/ota_client.h +342 -0
- package/include/mikrojs/ota_config.h +100 -0
- package/include/mikrojs/ota_env.h +192 -0
- package/include/mikrojs/ota_js_hooks.h +71 -0
- package/include/mikrojs/ota_policy.h +131 -0
- package/include/mikrojs/ota_slots.h +47 -0
- package/include/mikrojs/sys_codec.h +61 -0
- package/package.json +7 -5
- package/prebuilds/darwin-arm64/mikrojs.napi.node +0 -0
- package/prebuilds/linux-arm64/mikrojs.napi.node +0 -0
- package/prebuilds/linux-x64/mikrojs.napi.node +0 -0
- package/runtime/internal.d.ts +22 -16
- package/runtime/kv/shared.ts +11 -5
- package/runtime/kv/types.ts +4 -4
- package/runtime/ota/client.ts +12 -51
- package/runtime/ota/config.ts +18 -0
- package/runtime/ota/ota.ts +28 -70
- package/runtime/ota/types.ts +220 -2
- package/runtime/schema/core.ts +539 -0
- package/runtime/schema/schema.ts +36 -314
- package/runtime/schema/shared.ts +494 -0
- package/runtime/schema/types.ts +84 -12
- package/scripts/bundle-runtime.js +33 -0
- package/scripts/gen-checkin-fixtures.js +323 -0
- package/src/builtins.cpp +7 -8
- package/src/fs.cpp +3 -0
- package/src/mem.cpp +38 -0
- package/src/mik_abort.cpp +8 -1
- package/src/mik_cbor.cpp +43 -5
- package/src/mik_inspect.cpp +128 -22
- package/src/mik_ota_client.cpp +1230 -0
- package/src/mik_ota_config.cpp +296 -0
- package/src/mik_ota_js_hooks.cpp +190 -0
- package/src/mik_ota_policy.cpp +419 -0
- package/src/mik_ota_slots.cpp +249 -0
- package/src/mik_repl.cpp +9 -3
- package/src/mik_result.cpp +3 -1
- package/src/mik_sys_codec.cpp +167 -0
- package/src/mikrojs.cpp +15 -0
- package/src/modules.cpp +32 -13
- package/runtime/ota/client-impl.ts +0 -590
- package/runtime/ota/policy.ts +0 -299
package/runtime/schema/schema.ts
CHANGED
|
@@ -1,322 +1,44 @@
|
|
|
1
1
|
import {err, ok} from 'mikro/result'
|
|
2
2
|
|
|
3
3
|
import type {Result} from '../result/types.js'
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export interface ObjectSchema<Shape extends Record<string, Schema> = Record<string, Schema>> {
|
|
42
|
-
readonly kind: 'object'
|
|
43
|
-
readonly shape: Shape
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export interface OptionalSchema<S extends Schema = Schema> {
|
|
47
|
-
readonly kind: 'optional'
|
|
48
|
-
readonly inner: S
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export interface TupleSchema<Elements extends readonly Schema[] = readonly Schema[]> {
|
|
52
|
-
readonly kind: 'tuple'
|
|
53
|
-
readonly elements: Elements
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export interface UnionSchema<Members extends readonly Schema[] = readonly Schema[]> {
|
|
57
|
-
readonly kind: 'union'
|
|
58
|
-
readonly members: Members
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export interface TaggedUnionSchema<
|
|
62
|
-
Key extends string = string,
|
|
63
|
-
Branches extends Record<string, ObjectSchema> = Record<string, ObjectSchema>,
|
|
64
|
-
> {
|
|
65
|
-
readonly kind: 'taggedUnion'
|
|
66
|
-
readonly key: Key
|
|
67
|
-
readonly branches: Branches
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export type Schema =
|
|
71
|
-
| StringSchema
|
|
72
|
-
| NumberSchema
|
|
73
|
-
| BooleanSchema
|
|
74
|
-
| UnknownSchema
|
|
75
|
-
| LiteralSchema
|
|
76
|
-
| ArraySchema
|
|
77
|
-
| ObjectSchema
|
|
78
|
-
| OptionalSchema
|
|
79
|
-
| TupleSchema
|
|
80
|
-
| UnionSchema
|
|
81
|
-
| TaggedUnionSchema
|
|
82
|
-
|
|
83
|
-
// ── Type inference ──────────────────────────────────────────────────
|
|
84
|
-
|
|
85
|
-
type Simplify<T> = {[K in keyof T]: T[K]} & {}
|
|
86
|
-
|
|
87
|
-
export type Infer<S> = S extends StringSchema
|
|
88
|
-
? string
|
|
89
|
-
: S extends NumberSchema
|
|
90
|
-
? number
|
|
91
|
-
: S extends BooleanSchema
|
|
92
|
-
? boolean
|
|
93
|
-
: S extends UnknownSchema
|
|
94
|
-
? unknown
|
|
95
|
-
: S extends LiteralSchema<infer T>
|
|
96
|
-
? T
|
|
97
|
-
: S extends ArraySchema<infer E>
|
|
98
|
-
? Infer<E>[]
|
|
99
|
-
: S extends ObjectSchema<infer Shape>
|
|
100
|
-
? Simplify<InferObject<Shape>>
|
|
101
|
-
: S extends TupleSchema<infer Elements>
|
|
102
|
-
? InferTuple<Elements>
|
|
103
|
-
: S extends OptionalSchema<infer Inner>
|
|
104
|
-
? Infer<Inner> | undefined
|
|
105
|
-
: S extends UnionSchema<infer Members>
|
|
106
|
-
? InferUnion<Members>
|
|
107
|
-
: S extends TaggedUnionSchema<infer Key, infer Branches>
|
|
108
|
-
? InferTaggedUnion<Key, Branches>
|
|
109
|
-
: never
|
|
110
|
-
|
|
111
|
-
type InferObject<Shape> = {
|
|
112
|
-
[K in keyof Shape as Shape[K] extends OptionalSchema ? never : K]: Infer<Shape[K]>
|
|
113
|
-
} & {
|
|
114
|
-
[K in keyof Shape as Shape[K] extends OptionalSchema ? K : never]?: Infer<Shape[K]>
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
type InferTuple<Elements> = Elements extends readonly [infer Head, ...infer Tail]
|
|
118
|
-
? [Infer<Head>, ...InferTuple<Tail>]
|
|
119
|
-
: []
|
|
120
|
-
|
|
121
|
-
type InferUnion<Members> = Members extends readonly [infer Head, ...infer Tail]
|
|
122
|
-
? Infer<Head> | InferUnion<Tail>
|
|
123
|
-
: never
|
|
124
|
-
|
|
125
|
-
type InferTaggedUnion<Key extends string, Branches> = {
|
|
126
|
-
[Tag in keyof Branches & string]: {[K in Key]: Tag} & Infer<Branches[Tag]>
|
|
127
|
-
}[keyof Branches & string]
|
|
128
|
-
|
|
129
|
-
// ── Schema constructors ─────────────────────────────────────────────
|
|
130
|
-
|
|
131
|
-
export function string(): StringSchema {
|
|
132
|
-
return {kind: 'string'}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
export function number(): NumberSchema {
|
|
136
|
-
return {kind: 'number'}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
export function boolean(): BooleanSchema {
|
|
140
|
-
return {kind: 'boolean'}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
export function unknown(): UnknownSchema {
|
|
144
|
-
return {kind: 'unknown'}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
export function literal<T extends Primitive>(value: T): LiteralSchema<T> {
|
|
148
|
-
return {kind: 'literal', value}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
export function array<S extends Schema>(element: S): ArraySchema<S> {
|
|
152
|
-
return {kind: 'array', element}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
export function object<Shape extends Record<string, Schema>>(shape: Shape): ObjectSchema<Shape> {
|
|
156
|
-
return {kind: 'object', shape}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
export function tuple<Elements extends readonly Schema[]>(
|
|
160
|
-
elements: [...Elements],
|
|
161
|
-
): TupleSchema<Elements> {
|
|
162
|
-
return {kind: 'tuple', elements}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
export function optional<S extends Schema>(inner: S): OptionalSchema<S> {
|
|
166
|
-
return {kind: 'optional', inner}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
export function union<Members extends readonly Schema[]>(
|
|
170
|
-
members: [...Members],
|
|
171
|
-
): UnionSchema<Members> {
|
|
172
|
-
return {kind: 'union', members}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
export function taggedUnion<Key extends string, Branches extends Record<string, ObjectSchema>>(
|
|
176
|
-
key: Key,
|
|
177
|
-
branches: Branches,
|
|
178
|
-
): TaggedUnionSchema<Key, Branches> {
|
|
179
|
-
return {kind: 'taggedUnion', key, branches}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// ── Parse ───────────────────────────────────────────────────────────
|
|
4
|
+
import {type Infer, type Schema, type SchemaError, validate} from './core.js'
|
|
5
|
+
|
|
6
|
+
export type {
|
|
7
|
+
ArraySchema,
|
|
8
|
+
BooleanSchema,
|
|
9
|
+
DefaultOption,
|
|
10
|
+
Infer,
|
|
11
|
+
InferRead,
|
|
12
|
+
LiteralSchema,
|
|
13
|
+
NumberSchema,
|
|
14
|
+
ObjectSchema,
|
|
15
|
+
OptionalSchema,
|
|
16
|
+
ScalarOptions,
|
|
17
|
+
Schema,
|
|
18
|
+
StringSchema,
|
|
19
|
+
TaggedUnionSchema,
|
|
20
|
+
TupleSchema,
|
|
21
|
+
UnionSchema,
|
|
22
|
+
UnknownSchema,
|
|
23
|
+
} from './core.js'
|
|
24
|
+
export {
|
|
25
|
+
applyDefaults,
|
|
26
|
+
array,
|
|
27
|
+
boolean,
|
|
28
|
+
literal,
|
|
29
|
+
number,
|
|
30
|
+
object,
|
|
31
|
+
optional,
|
|
32
|
+
SchemaError,
|
|
33
|
+
string,
|
|
34
|
+
taggedUnion,
|
|
35
|
+
tuple,
|
|
36
|
+
union,
|
|
37
|
+
unknown,
|
|
38
|
+
} from './core.js'
|
|
183
39
|
|
|
184
40
|
export function parse<S extends Schema>(schema: S, value: unknown): Result<Infer<S>, SchemaError> {
|
|
185
41
|
const result = validate(schema, value, '')
|
|
186
|
-
if (result !== null) return result
|
|
42
|
+
if (result !== null) return err(result.error)
|
|
187
43
|
return ok(value as Infer<S>)
|
|
188
44
|
}
|
|
189
|
-
|
|
190
|
-
function typeOf(value: unknown): string {
|
|
191
|
-
if (value === null) return 'null'
|
|
192
|
-
if (Array.isArray(value)) return 'array'
|
|
193
|
-
return typeof value
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
function validate(
|
|
197
|
-
schema: Schema,
|
|
198
|
-
value: unknown,
|
|
199
|
-
path: string,
|
|
200
|
-
): ReturnType<typeof err<SchemaError>> | null {
|
|
201
|
-
switch (schema.kind) {
|
|
202
|
-
case 'string':
|
|
203
|
-
if (typeof value !== 'string')
|
|
204
|
-
return err(SchemaError.ValidationFailed(`expected string, got ${typeOf(value)}`, path))
|
|
205
|
-
return null
|
|
206
|
-
|
|
207
|
-
case 'number':
|
|
208
|
-
if (typeof value !== 'number' || Number.isNaN(value))
|
|
209
|
-
return err(SchemaError.ValidationFailed(`expected number, got ${typeOf(value)}`, path))
|
|
210
|
-
return null
|
|
211
|
-
|
|
212
|
-
case 'boolean':
|
|
213
|
-
if (typeof value !== 'boolean')
|
|
214
|
-
return err(SchemaError.ValidationFailed(`expected boolean, got ${typeOf(value)}`, path))
|
|
215
|
-
return null
|
|
216
|
-
|
|
217
|
-
case 'unknown':
|
|
218
|
-
return null
|
|
219
|
-
|
|
220
|
-
case 'literal':
|
|
221
|
-
if (value !== schema.value)
|
|
222
|
-
return err(
|
|
223
|
-
SchemaError.ValidationFailed(
|
|
224
|
-
`expected ${JSON.stringify(schema.value)}, got ${JSON.stringify(value)}`,
|
|
225
|
-
path,
|
|
226
|
-
),
|
|
227
|
-
)
|
|
228
|
-
return null
|
|
229
|
-
|
|
230
|
-
case 'array': {
|
|
231
|
-
if (!Array.isArray(value))
|
|
232
|
-
return err(SchemaError.ValidationFailed(`expected array, got ${typeOf(value)}`, path))
|
|
233
|
-
for (let i = 0; i < value.length; i++) {
|
|
234
|
-
const result = validate(schema.element, value[i], `${path}[${i}]`)
|
|
235
|
-
if (result !== null) return result
|
|
236
|
-
}
|
|
237
|
-
return null
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
case 'object': {
|
|
241
|
-
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
242
|
-
return err(SchemaError.ValidationFailed(`expected object, got ${typeOf(value)}`, path))
|
|
243
|
-
const obj = value as Record<string, unknown>
|
|
244
|
-
const keys = Object.keys(schema.shape)
|
|
245
|
-
for (let i = 0; i < keys.length; i++) {
|
|
246
|
-
const key = keys[i]!
|
|
247
|
-
const fieldSchema = schema.shape[key]!
|
|
248
|
-
const fieldPath = `${path}.${key}`
|
|
249
|
-
if (fieldSchema.kind === 'optional') {
|
|
250
|
-
if (key in obj) {
|
|
251
|
-
const result = validate(fieldSchema, obj[key], fieldPath)
|
|
252
|
-
if (result !== null) return result
|
|
253
|
-
}
|
|
254
|
-
} else {
|
|
255
|
-
if (!(key in obj))
|
|
256
|
-
return err(SchemaError.ValidationFailed(`missing required field`, fieldPath))
|
|
257
|
-
const result = validate(fieldSchema, obj[key], fieldPath)
|
|
258
|
-
if (result !== null) return result
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
return null
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
case 'tuple': {
|
|
265
|
-
if (!Array.isArray(value))
|
|
266
|
-
return err(SchemaError.ValidationFailed(`expected array, got ${typeOf(value)}`, path))
|
|
267
|
-
if (value.length !== schema.elements.length)
|
|
268
|
-
return err(
|
|
269
|
-
SchemaError.ValidationFailed(
|
|
270
|
-
`expected ${schema.elements.length} elements, got ${value.length}`,
|
|
271
|
-
path,
|
|
272
|
-
),
|
|
273
|
-
)
|
|
274
|
-
for (let i = 0; i < schema.elements.length; i++) {
|
|
275
|
-
const result = validate(schema.elements[i]!, value[i], `${path}[${i}]`)
|
|
276
|
-
if (result !== null) return result
|
|
277
|
-
}
|
|
278
|
-
return null
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
case 'optional': {
|
|
282
|
-
if (value === undefined) return null
|
|
283
|
-
return validate(schema.inner, value, path)
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
case 'union': {
|
|
287
|
-
for (let i = 0; i < schema.members.length; i++) {
|
|
288
|
-
const result = validate(schema.members[i]!, value, path)
|
|
289
|
-
if (result === null) return null
|
|
290
|
-
}
|
|
291
|
-
return err(SchemaError.ValidationFailed(`value did not match any union member`, path))
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
case 'taggedUnion': {
|
|
295
|
-
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
296
|
-
return err(SchemaError.ValidationFailed(`expected object, got ${typeOf(value)}`, path))
|
|
297
|
-
const obj = value as Record<string, unknown>
|
|
298
|
-
const tag = obj[schema.key]
|
|
299
|
-
if (tag === undefined)
|
|
300
|
-
return err(
|
|
301
|
-
SchemaError.ValidationFailed(`missing discriminator field`, `${path}.${schema.key}`),
|
|
302
|
-
)
|
|
303
|
-
if (typeof tag !== 'string' && typeof tag !== 'number' && typeof tag !== 'boolean')
|
|
304
|
-
return err(
|
|
305
|
-
SchemaError.ValidationFailed(
|
|
306
|
-
`expected primitive discriminator, got ${typeOf(tag)}`,
|
|
307
|
-
`${path}.${schema.key}`,
|
|
308
|
-
),
|
|
309
|
-
)
|
|
310
|
-
const branch = schema.branches[tag as string]
|
|
311
|
-
if (branch === undefined)
|
|
312
|
-
return err(
|
|
313
|
-
SchemaError.ValidationFailed(
|
|
314
|
-
`unknown tag ${JSON.stringify(tag)}`,
|
|
315
|
-
`${path}.${schema.key}`,
|
|
316
|
-
),
|
|
317
|
-
)
|
|
318
|
-
return validate(branch, value, path)
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
return err(SchemaError.ValidationFailed(`unknown schema kind: ${(schema as any).kind}`, path))
|
|
322
|
-
}
|