@quadrokit/client 0.1.0 → 0.2.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/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.mjs +69 -0
- package/dist/generate/codegen.d.ts +3 -0
- package/dist/generate/codegen.d.ts.map +1 -0
- package/dist/generate/codegen.mjs +287 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/{src/index.ts → dist/index.mjs} +1 -1
- package/dist/runtime/collection.d.ts +29 -0
- package/dist/runtime/collection.d.ts.map +1 -0
- package/dist/runtime/collection.mjs +94 -0
- package/dist/runtime/data-class.d.ts +42 -0
- package/dist/runtime/data-class.d.ts.map +1 -0
- package/dist/runtime/data-class.mjs +99 -0
- package/dist/runtime/datastore.d.ts +8 -0
- package/dist/runtime/datastore.d.ts.map +1 -0
- package/dist/runtime/datastore.mjs +15 -0
- package/dist/runtime/errors.d.ts +6 -0
- package/dist/runtime/errors.d.ts.map +1 -0
- package/dist/runtime/errors.mjs +10 -0
- package/dist/runtime/http.d.ts +16 -0
- package/dist/runtime/http.d.ts.map +1 -0
- package/dist/runtime/http.mjs +54 -0
- package/dist/runtime/index.d.ts +9 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.mjs +7 -0
- package/dist/runtime/paths.d.ts +16 -0
- package/dist/runtime/paths.d.ts.map +1 -0
- package/dist/runtime/paths.mjs +2 -0
- package/dist/runtime/query.d.ts +14 -0
- package/dist/runtime/query.d.ts.map +1 -0
- package/dist/runtime/query.mjs +76 -0
- package/dist/runtime/unwrap.d.ts +4 -0
- package/dist/runtime/unwrap.d.ts.map +1 -0
- package/dist/runtime/unwrap.mjs +31 -0
- package/package.json +14 -7
- package/src/cli.ts +0 -82
- package/src/generate/codegen.ts +0 -317
- package/src/runtime/collection.ts +0 -135
- package/src/runtime/data-class.ts +0 -156
- package/src/runtime/datastore.ts +0 -25
- package/src/runtime/errors.ts +0 -11
- package/src/runtime/http.ts +0 -64
- package/src/runtime/index.ts +0 -23
- package/src/runtime/paths.ts +0 -42
- package/src/runtime/query.ts +0 -104
- package/src/runtime/unwrap.ts +0 -33
- package/tsconfig.json +0 -9
package/src/runtime/index.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
export {
|
|
2
|
-
type CollectionContext,
|
|
3
|
-
type CollectionHandle,
|
|
4
|
-
type CollectionOptions,
|
|
5
|
-
createCollection,
|
|
6
|
-
} from './collection.js'
|
|
7
|
-
export {
|
|
8
|
-
attachRelatedApis,
|
|
9
|
-
type DataClassRuntimeConfig,
|
|
10
|
-
type EntityNavigationConfig,
|
|
11
|
-
makeDataClassApi,
|
|
12
|
-
makeRelatedCollectionApi,
|
|
13
|
-
} from './data-class.js'
|
|
14
|
-
export { callDatastorePath, createDatastoreNamespace } from './datastore.js'
|
|
15
|
-
export { QuadroHttpError } from './errors.js'
|
|
16
|
-
export {
|
|
17
|
-
normalizeBaseURL,
|
|
18
|
-
type QuadroFetchOptions,
|
|
19
|
-
QuadroHttp,
|
|
20
|
-
} from './http.js'
|
|
21
|
-
export type { Paths1, SelectedEntity } from './paths.js'
|
|
22
|
-
export { buildListSearchParams, type ListQueryParams } from './query.js'
|
|
23
|
-
export { unwrapEntity, unwrapEntityList } from './unwrap.js'
|
package/src/runtime/paths.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/** Type-level helpers for `$select` dot paths (compile-time only). */
|
|
2
|
-
|
|
3
|
-
type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (
|
|
4
|
-
k: infer I
|
|
5
|
-
) => void
|
|
6
|
-
? I
|
|
7
|
-
: never
|
|
8
|
-
|
|
9
|
-
type PickOne<T, H extends string> = H extends keyof T & string
|
|
10
|
-
? Pick<T, H>
|
|
11
|
-
: H extends `${infer K}.${infer R}`
|
|
12
|
-
? K extends keyof T & string
|
|
13
|
-
? NonNullable<T[K]> extends infer U
|
|
14
|
-
? U extends object
|
|
15
|
-
? { [P in K]: PickOne<U, R> }
|
|
16
|
-
: never
|
|
17
|
-
: never
|
|
18
|
-
: never
|
|
19
|
-
: never
|
|
20
|
-
|
|
21
|
-
declare const selectBrand: unique symbol
|
|
22
|
-
|
|
23
|
-
/** Entity narrowed to selected paths (branded for nominal distinction). */
|
|
24
|
-
export type SelectedEntity<T, S extends readonly string[]> =
|
|
25
|
-
UnionToIntersection<
|
|
26
|
-
S[number] extends infer H ? (H extends string ? PickOne<T, H> : never) : never
|
|
27
|
-
> extends infer O
|
|
28
|
-
? O extends object
|
|
29
|
-
? O & { readonly [selectBrand]: S }
|
|
30
|
-
: never
|
|
31
|
-
: never
|
|
32
|
-
|
|
33
|
-
/** Flat union of first-level and nested dot paths (codegen emits concrete unions). */
|
|
34
|
-
export type Paths1<T> = T extends object
|
|
35
|
-
? {
|
|
36
|
-
[K in keyof T & string]: NonNullable<T[K]> extends infer U
|
|
37
|
-
? U extends object
|
|
38
|
-
? K | `${K}.${Paths1<U>}`
|
|
39
|
-
: K
|
|
40
|
-
: K
|
|
41
|
-
}[keyof T & string]
|
|
42
|
-
: never
|
package/src/runtime/query.ts
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
/** Build 4D REST query params ($skip, $top, $filter, $expand, $select). */
|
|
2
|
-
|
|
3
|
-
export interface ListQueryParams {
|
|
4
|
-
page?: number
|
|
5
|
-
pageSize?: number
|
|
6
|
-
/** Dot-paths like `manager.name` → $expand + nested $select where possible. */
|
|
7
|
-
select?: readonly string[]
|
|
8
|
-
/** OData-style filter string (4D REST). */
|
|
9
|
-
filter?: string
|
|
10
|
-
orderby?: string
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function buildListSearchParams(
|
|
14
|
-
className: string,
|
|
15
|
-
opts: ListQueryParams,
|
|
16
|
-
_relationMap: Record<string, string>
|
|
17
|
-
): string {
|
|
18
|
-
const params = new URLSearchParams()
|
|
19
|
-
const page = opts.page ?? 1
|
|
20
|
-
const pageSize = opts.pageSize ?? 50
|
|
21
|
-
const skip = (page - 1) * pageSize
|
|
22
|
-
if (skip > 0) {
|
|
23
|
-
params.set('$skip', String(skip))
|
|
24
|
-
}
|
|
25
|
-
params.set('$top', String(pageSize))
|
|
26
|
-
if (opts.filter) {
|
|
27
|
-
params.set('$filter', opts.filter)
|
|
28
|
-
}
|
|
29
|
-
if (opts.orderby) {
|
|
30
|
-
params.set('$orderby', opts.orderby)
|
|
31
|
-
}
|
|
32
|
-
const { expand, selectRoot } = buildExpandAndSelect(className, opts.select ?? [], _relationMap)
|
|
33
|
-
if (selectRoot.length) {
|
|
34
|
-
params.set('$select', selectRoot.join(','))
|
|
35
|
-
}
|
|
36
|
-
if (expand.length) {
|
|
37
|
-
params.set('$expand', expand.join(','))
|
|
38
|
-
}
|
|
39
|
-
const q = params.toString()
|
|
40
|
-
return q ? `?${q}` : ''
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/** Query string for a single entity (only $select / $expand, no paging). */
|
|
44
|
-
export function buildEntityParams(
|
|
45
|
-
className: string,
|
|
46
|
-
select: readonly string[] | undefined,
|
|
47
|
-
_relationMap: Record<string, string>
|
|
48
|
-
): string {
|
|
49
|
-
if (!select?.length) {
|
|
50
|
-
return ''
|
|
51
|
-
}
|
|
52
|
-
const { expand, selectRoot } = buildExpandAndSelect(className, select, _relationMap)
|
|
53
|
-
const params = new URLSearchParams()
|
|
54
|
-
if (selectRoot.length) {
|
|
55
|
-
params.set('$select', selectRoot.join(','))
|
|
56
|
-
}
|
|
57
|
-
if (expand.length) {
|
|
58
|
-
params.set('$expand', expand.join(','))
|
|
59
|
-
}
|
|
60
|
-
const q = params.toString()
|
|
61
|
-
return q ? `?${q}` : ''
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function buildExpandAndSelect(
|
|
65
|
-
_className: string,
|
|
66
|
-
paths: readonly string[],
|
|
67
|
-
_relationMap: Record<string, string>
|
|
68
|
-
): { expand: string[]; selectRoot: string[] } {
|
|
69
|
-
if (!paths.length) {
|
|
70
|
-
return { expand: [], selectRoot: [] }
|
|
71
|
-
}
|
|
72
|
-
const rootSelect = new Set<string>()
|
|
73
|
-
const expandParts: string[] = []
|
|
74
|
-
const byRel = new Map<string, Set<string>>()
|
|
75
|
-
|
|
76
|
-
for (const p of paths) {
|
|
77
|
-
const dot = p.indexOf('.')
|
|
78
|
-
if (dot === -1) {
|
|
79
|
-
rootSelect.add(p)
|
|
80
|
-
continue
|
|
81
|
-
}
|
|
82
|
-
const rel = p.slice(0, dot)
|
|
83
|
-
const rest = p.slice(dot + 1)
|
|
84
|
-
if (!byRel.has(rel)) {
|
|
85
|
-
byRel.set(rel, new Set())
|
|
86
|
-
}
|
|
87
|
-
byRel.get(rel)!.add(rest)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
for (const [rel, nested] of byRel) {
|
|
91
|
-
const nestedList = [...nested]
|
|
92
|
-
const inner = nestedList.length ? `($select=${nestedList.join(',')})` : ''
|
|
93
|
-
// Use navigation property name (4D / OData $expand), not the target class name.
|
|
94
|
-
expandParts.push(`${rel}${inner}`)
|
|
95
|
-
if (!rootSelect.has(rel)) {
|
|
96
|
-
rootSelect.add(rel)
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return {
|
|
101
|
-
expand: expandParts,
|
|
102
|
-
selectRoot: [...rootSelect],
|
|
103
|
-
}
|
|
104
|
-
}
|
package/src/runtime/unwrap.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/** Normalize 4D REST JSON (array or `{ ClassName: [...] }`). */
|
|
2
|
-
|
|
3
|
-
export function unwrapEntityList<T>(className: string, body: unknown): T[] {
|
|
4
|
-
if (Array.isArray(body)) {
|
|
5
|
-
return body as T[]
|
|
6
|
-
}
|
|
7
|
-
if (body && typeof body === 'object' && className in body) {
|
|
8
|
-
const v = (body as Record<string, unknown>)[className]
|
|
9
|
-
if (Array.isArray(v)) {
|
|
10
|
-
return v as T[]
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
if (body && typeof body === 'object' && '__ENTITIES' in body) {
|
|
14
|
-
const v = (body as { __ENTITIES?: unknown }).__ENTITIES
|
|
15
|
-
if (Array.isArray(v)) {
|
|
16
|
-
return v as T[]
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
return []
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function unwrapEntity<T>(className: string, body: unknown): T | null {
|
|
23
|
-
if (body == null) {
|
|
24
|
-
return null
|
|
25
|
-
}
|
|
26
|
-
if (Array.isArray(body)) {
|
|
27
|
-
return (body[0] as T) ?? null
|
|
28
|
-
}
|
|
29
|
-
if (typeof body === 'object' && className in body) {
|
|
30
|
-
return (body as Record<string, T>)[className] ?? null
|
|
31
|
-
}
|
|
32
|
-
return body as T
|
|
33
|
-
}
|