@sdcorejs/angular 19.2.0 → 19.2.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/components/api-contract-builder/index.d.ts +8 -0
- package/components/api-contract-builder/src/api-contract-builder.component.d.ts +123 -0
- package/components/api-contract-builder/src/api-contract.configuration.d.ts +41 -0
- package/components/api-contract-builder/src/api-contract.expression.d.ts +43 -0
- package/components/api-contract-builder/src/api-contract.model.d.ts +167 -0
- package/components/api-contract-builder/src/api-contract.samples.d.ts +25 -0
- package/components/api-contract-builder/src/api-contract.schema.d.ts +126 -0
- package/components/api-contract-builder/src/api-contract.serializer.d.ts +17 -0
- package/components/api-contract-builder/src/api-contract.validation.d.ts +12 -0
- package/components/api-contract-builder/src/components/api-contract-diagnostic-list.component.d.ts +18 -0
- package/components/api-contract-builder/src/components/api-contract-node-drawer.component.d.ts +130 -0
- package/components/api-contract-builder/src/components/api-contract-node-editor.component.d.ts +35 -0
- package/components/api-contract-builder/src/components/api-contract-node-summary.component.d.ts +41 -0
- package/components/api-contract-builder/src/components/api-contract-record-editor.component.d.ts +36 -0
- package/components/api-contract-builder/src/components/api-contract-source-editor.component.d.ts +86 -0
- package/components/api-contract-builder/src/components/api-contract-suggestion.model.d.ts +17 -0
- package/components/badge/src/badge.component.d.ts +1 -0
- package/components/index.d.ts +1 -0
- package/components/section/src/section.component.d.ts +2 -0
- package/fesm2022/sdcorejs-angular-components-api-contract-builder.mjs +3411 -0
- package/fesm2022/sdcorejs-angular-components-api-contract-builder.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-components-badge.mjs +14 -2
- package/fesm2022/sdcorejs-angular-components-badge.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-operator.mjs +2 -2
- package/fesm2022/sdcorejs-angular-components-operator.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-section.mjs +22 -5
- package/fesm2022/sdcorejs-angular-components-section.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-table.mjs +14 -13
- package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components.mjs +1 -0
- package/fesm2022/sdcorejs-angular-components.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-i18n.mjs +405 -0
- package/fesm2022/sdcorejs-angular-i18n.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-modules-icon.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-modules-layout.mjs +146 -83
- package/fesm2022/sdcorejs-angular-modules-layout.mjs.map +1 -1
- package/i18n/src/en.d.ts +80 -0
- package/modules/layout/components/sidebar-v1/components/sidebar/sidebar.component.d.ts +9 -0
- package/modules/layout/pipes/menu-focus.pipe.d.ts +6 -2
- package/modules/layout/utils/index.d.ts +1 -0
- package/modules/layout/utils/menu-path.util.d.ts +16 -0
- package/package.json +17 -13
package/components/api-contract-builder/src/components/api-contract-node-drawer.component.d.ts
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { SdSideDrawer } from '@sdcorejs/angular/components/side-drawer';
|
|
2
|
+
import { type SdApiContractDataType } from '../api-contract.model';
|
|
3
|
+
import { type SdApiContractStructuralNode } from '../api-contract.schema';
|
|
4
|
+
import type { SdApiContractSuggestion } from './api-contract-suggestion.model';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
/** What the drawer hands back when the author closes the books on one node. */
|
|
7
|
+
export interface SdApiContractNodeCommit {
|
|
8
|
+
name: string;
|
|
9
|
+
node: SdApiContractStructuralNode;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* A layer list asking for the drawer to be opened.
|
|
13
|
+
*
|
|
14
|
+
* The list does not own the drawer — the builder does, so there is exactly one drawer and one staged
|
|
15
|
+
* draft on the page. The list only says which node the author reached for; the builder knows which
|
|
16
|
+
* section that list was wired into and applies the commit there.
|
|
17
|
+
*/
|
|
18
|
+
export interface SdApiContractNodeEditRequest {
|
|
19
|
+
/** `null` means "add a new node to this collection". */
|
|
20
|
+
name: string | null;
|
|
21
|
+
node: SdApiContractStructuralNode | null;
|
|
22
|
+
/** Names already taken at this level, so the drawer can refuse a duplicate. */
|
|
23
|
+
siblingNames: readonly string[];
|
|
24
|
+
/**
|
|
25
|
+
* Where the listed collection sits inside its layer root — `[]` for an object layer, `['items']`
|
|
26
|
+
* for an array layer whose fields belong to the element.
|
|
27
|
+
*
|
|
28
|
+
* why cần: drawer không dùng field này, nhưng builder thì có. Một tầng `array` (vd `output.schema`
|
|
29
|
+
* nhận `${res.body.items}`) khai field ở `items.properties`, còn tầng `object` khai ở `properties`.
|
|
30
|
+
* Danh sách đã biết mình đang đọc chỗ nào, nên nó nói ra thay vì để builder đoán lại.
|
|
31
|
+
*/
|
|
32
|
+
pointer?: readonly string[];
|
|
33
|
+
}
|
|
34
|
+
interface SdApiContractOption {
|
|
35
|
+
value: string;
|
|
36
|
+
label: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Editing surface for exactly one node, staged and committed in one go.
|
|
40
|
+
*
|
|
41
|
+
* The layer lists outside are read-only, so this drawer is the only place a node changes. It holds a
|
|
42
|
+
* DEEP COPY of the node it was seeded from and emits `nodeCommit` once, when the author saves — that
|
|
43
|
+
* is what makes "Huỷ" able to actually cancel, and what keeps the tree from changing under the
|
|
44
|
+
* author's cursor on every keystroke.
|
|
45
|
+
*
|
|
46
|
+
* Save is blocked only for the two problems that stop a node from existing at all: no name, or a name
|
|
47
|
+
* a sibling already holds. Everything else — a reference to a field that does not exist yet, a type
|
|
48
|
+
* that will not fit — saves and is reported by `validateSdApiContract`, because inventing rules here
|
|
49
|
+
* would stop an author declaring one end of a mapping before the other exists.
|
|
50
|
+
*/
|
|
51
|
+
export declare class SdApiContractNodeDrawer {
|
|
52
|
+
#private;
|
|
53
|
+
/** `mapping` shows the value editor; `schema` is a plain declaration with no mapping. */
|
|
54
|
+
layer: import("@angular/core").InputSignal<"schema" | "mapping">;
|
|
55
|
+
allowTransform: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
56
|
+
suggestions: import("@angular/core").InputSignal<readonly SdApiContractSuggestion[]>;
|
|
57
|
+
autoId: import("@angular/core").InputSignal<string | null | undefined>;
|
|
58
|
+
nodeCommit: import("@angular/core").OutputEmitterRef<SdApiContractNodeCommit>;
|
|
59
|
+
protected readonly drawerRef: import("@angular/core").Signal<SdSideDrawer>;
|
|
60
|
+
protected readonly draftName: import("@angular/core").Signal<string>;
|
|
61
|
+
protected readonly discardPrompt: import("@angular/core").Signal<boolean>;
|
|
62
|
+
/** The node the author is looking at right now — the draft root, or a descendant of it. */
|
|
63
|
+
protected readonly current: import("@angular/core").Signal<SdApiContractStructuralNode | null>;
|
|
64
|
+
/** Every key on the breadcrumb. The pointer alternates `properties`/key, so keys sit on odd slots. */
|
|
65
|
+
protected readonly breadcrumb: import("@angular/core").Signal<string[]>;
|
|
66
|
+
/**
|
|
67
|
+
* What the name field shows.
|
|
68
|
+
*
|
|
69
|
+
* why một signal riêng chứ không đọc thẳng từ draft: một tên KHÔNG áp được — rỗng, hoặc trùng
|
|
70
|
+
* sibling — vẫn phải hiện ra để người dùng thấy mình vừa gõ gì và đọc được lý do bị chặn. Đọc
|
|
71
|
+
* thẳng từ draft thì ô input nhảy về tên cũ ngay khi gõ, tức là từ chối im lặng.
|
|
72
|
+
*/
|
|
73
|
+
protected readonly currentName: import("@angular/core").Signal<string>;
|
|
74
|
+
protected readonly children: import("@angular/core").Signal<{
|
|
75
|
+
key: string;
|
|
76
|
+
node: SdApiContractStructuralNode;
|
|
77
|
+
}[]>;
|
|
78
|
+
/** Siblings on the level the author is on — the root list, or the parent object's keys. */
|
|
79
|
+
protected readonly siblingNames: import("@angular/core").Signal<readonly string[]>;
|
|
80
|
+
protected readonly typeOptions: SdApiContractOption[];
|
|
81
|
+
protected readonly requiredOptions: SdApiContractOption[];
|
|
82
|
+
protected readonly transformOptions: SdApiContractOption[];
|
|
83
|
+
protected readonly title: import("@angular/core").Signal<string>;
|
|
84
|
+
protected readonly dirty: import("@angular/core").Signal<boolean>;
|
|
85
|
+
protected readonly nameError: import("@angular/core").Signal<string | null>;
|
|
86
|
+
protected readonly canSave: import("@angular/core").Signal<boolean>;
|
|
87
|
+
/**
|
|
88
|
+
* `beforeClose` guard for `<sd-side-drawer>`.
|
|
89
|
+
*
|
|
90
|
+
* why an arrow field, not a method: the drawer takes it as an input value, so it must keep `this`
|
|
91
|
+
* without the template having to bind it.
|
|
92
|
+
*/
|
|
93
|
+
protected readonly closeGuard: () => boolean;
|
|
94
|
+
openForAdd(siblingNames?: readonly string[], type?: SdApiContractDataType): void;
|
|
95
|
+
openForEdit(name: string, node: SdApiContractStructuralNode, siblingNames?: readonly string[]): void;
|
|
96
|
+
/**
|
|
97
|
+
* Types into the name field.
|
|
98
|
+
*
|
|
99
|
+
* The typed text is ALWAYS kept, then applied to the draft only when it can be. A name that cannot
|
|
100
|
+
* be applied — empty, or already taken by a sibling — stays visible and `nameError()` explains it,
|
|
101
|
+
* which is what blocks Save. Refusing the keystroke instead would leave the field showing one name
|
|
102
|
+
* while the contract holds another.
|
|
103
|
+
*/
|
|
104
|
+
protected setName(value: unknown): void;
|
|
105
|
+
protected setType(value: unknown): void;
|
|
106
|
+
protected setRequired(value: unknown): void;
|
|
107
|
+
protected setText(key: 'label' | 'description', value: unknown): void;
|
|
108
|
+
protected setTransform(value: unknown): void;
|
|
109
|
+
protected applyCurrent(node: SdApiContractStructuralNode): void;
|
|
110
|
+
protected enter(key: string): void;
|
|
111
|
+
/** `depth` counts breadcrumb entries, so 0 is the draft root. */
|
|
112
|
+
protected backTo(depth: number): void;
|
|
113
|
+
protected addChild(): void;
|
|
114
|
+
protected removeChild(key: string): void;
|
|
115
|
+
protected save(): void;
|
|
116
|
+
protected requestCancel(): void;
|
|
117
|
+
protected confirmDiscard(): void;
|
|
118
|
+
protected cancelDiscard(): void;
|
|
119
|
+
/**
|
|
120
|
+
* Blocks the close while the draft is dirty and raises an inline prompt instead.
|
|
121
|
+
*
|
|
122
|
+
* why inline chứ không `window.confirm`: một component thư viện không được dựng dialog của browser
|
|
123
|
+
* — nó không style được, không test được, và chặn cả tab.
|
|
124
|
+
*/
|
|
125
|
+
protected guardClose(): boolean;
|
|
126
|
+
protected onClosed(): void;
|
|
127
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SdApiContractNodeDrawer, never>;
|
|
128
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SdApiContractNodeDrawer, "sd-api-contract-node-drawer", never, { "layer": { "alias": "layer"; "required": false; "isSignal": true; }; "allowTransform": { "alias": "allowTransform"; "required": false; "isSignal": true; }; "suggestions": { "alias": "suggestions"; "required": false; "isSignal": true; }; "autoId": { "alias": "autoId"; "required": false; "isSignal": true; }; }, { "nodeCommit": "nodeCommit"; }, never, never, true, never>;
|
|
129
|
+
}
|
|
130
|
+
export {};
|
package/components/api-contract-builder/src/components/api-contract-node-editor.component.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type SdApiContractStructuralNode } from '../api-contract.schema';
|
|
2
|
+
import type { SdApiContractNodeEditRequest } from './api-contract-node-drawer.component';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
interface SdApiContractPropertyEntry {
|
|
5
|
+
key: string;
|
|
6
|
+
node: SdApiContractStructuralNode;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* One schema layer — `input.schema`, `req.body`, `res.body`, `output.schema` — rendered as a flat list
|
|
10
|
+
* of the fields it declares.
|
|
11
|
+
*
|
|
12
|
+
* It used to be a recursive tree of editable seven-column rows. It is now a list you read: adding and
|
|
13
|
+
* editing ask the builder to open its drawer, and only removal is applied straight away. The list is
|
|
14
|
+
* deliberately FLAT — an `object` field shows how many fields it holds and the author drills into it
|
|
15
|
+
* inside the drawer, so a deeply nested node is edited with a drawer's worth of room instead of a
|
|
16
|
+
* 100px cell.
|
|
17
|
+
*/
|
|
18
|
+
export declare class SdApiContractNodeEditor {
|
|
19
|
+
#private;
|
|
20
|
+
/** The layer's root node. */
|
|
21
|
+
node: import("@angular/core").InputSignal<SdApiContractStructuralNode>;
|
|
22
|
+
/** Diagnostic path of the layer itself, e.g. `input.schema`. */
|
|
23
|
+
basePath: import("@angular/core").InputSignal<string>;
|
|
24
|
+
disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
25
|
+
autoId: import("@angular/core").InputSignal<string | null | undefined>;
|
|
26
|
+
nodeChange: import("@angular/core").OutputEmitterRef<SdApiContractStructuralNode>;
|
|
27
|
+
editRequest: import("@angular/core").OutputEmitterRef<SdApiContractNodeEditRequest>;
|
|
28
|
+
protected readonly entries: import("@angular/core").Signal<SdApiContractPropertyEntry[]>;
|
|
29
|
+
protected requestAdd(): void;
|
|
30
|
+
protected requestEdit(key: string, node: SdApiContractStructuralNode): void;
|
|
31
|
+
protected removeProperty(key: string): void;
|
|
32
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SdApiContractNodeEditor, never>;
|
|
33
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SdApiContractNodeEditor, "sd-api-contract-node-editor", never, { "node": { "alias": "node"; "required": true; "isSignal": true; }; "basePath": { "alias": "basePath"; "required": true; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "autoId": { "alias": "autoId"; "required": false; "isSignal": true; }; }, { "nodeChange": "nodeChange"; "editRequest": "editRequest"; }, never, never, true, never>;
|
|
34
|
+
}
|
|
35
|
+
export {};
|
package/components/api-contract-builder/src/components/api-contract-node-summary.component.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { SdApiContractStructuralNode } from '../api-contract.schema';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
/**
|
|
4
|
+
* One collapsed, read-only row for a node in a layer list.
|
|
5
|
+
*
|
|
6
|
+
* The whole point is that it holds NO editable control. Editing a node happens in the drawer, so the
|
|
7
|
+
* list can stay a thing you scan rather than a wall of inputs — and so a node never has two editors
|
|
8
|
+
* writing it at once.
|
|
9
|
+
*
|
|
10
|
+
* The row shows what an author needs to spot a mistake without opening anything: the name, the
|
|
11
|
+
* declared type, whether it is required, and where its value comes from.
|
|
12
|
+
*/
|
|
13
|
+
export declare class SdApiContractNodeSummary {
|
|
14
|
+
#private;
|
|
15
|
+
name: import("@angular/core").InputSignal<string>;
|
|
16
|
+
node: import("@angular/core").InputSignal<SdApiContractStructuralNode>;
|
|
17
|
+
/** `view` mode and `disabled` both land here: the row becomes text, with no action at all. */
|
|
18
|
+
readonly: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
19
|
+
autoId: import("@angular/core").InputSignal<string | null | undefined>;
|
|
20
|
+
edit: import("@angular/core").OutputEmitterRef<void>;
|
|
21
|
+
remove: import("@angular/core").OutputEmitterRef<void>;
|
|
22
|
+
protected readonly requiredLabel: string;
|
|
23
|
+
protected readonly removeLabel: string;
|
|
24
|
+
protected readonly unmapped: import("@angular/core").Signal<boolean>;
|
|
25
|
+
/**
|
|
26
|
+
* One line describing where the value comes from.
|
|
27
|
+
*
|
|
28
|
+
* why bốn dạng khác nhau: `${input.keyword}` rút về `input.keyword` vì dấu `${}` là cú pháp chứ
|
|
29
|
+
* không phải thông tin; còn template ghép giữ NGUYÊN VĂN vì rút gọn nó sẽ sai. Literal hiện giá trị
|
|
30
|
+
* để thấy ngay, object hiện số trường để biết còn bao nhiêu phải mở ra xem.
|
|
31
|
+
*/
|
|
32
|
+
protected readonly mappingSummary: import("@angular/core").Signal<string>;
|
|
33
|
+
protected requestEdit(): void;
|
|
34
|
+
/**
|
|
35
|
+
* why stopPropagation: nút xoá nằm TRONG hàng có `(click)`, nên không chặn thì bấm xoá cũng mở
|
|
36
|
+
* drawer — người dùng bấm xoá lại thấy form hiện ra.
|
|
37
|
+
*/
|
|
38
|
+
protected requestRemove(event: Event): void;
|
|
39
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SdApiContractNodeSummary, never>;
|
|
40
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SdApiContractNodeSummary, "sd-api-contract-node-summary", never, { "name": { "alias": "name"; "required": true; "isSignal": true; }; "node": { "alias": "node"; "required": true; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "autoId": { "alias": "autoId"; "required": false; "isSignal": true; }; }, { "edit": "edit"; "remove": "remove"; }, never, never, true, never>;
|
|
41
|
+
}
|
package/components/api-contract-builder/src/components/api-contract-record-editor.component.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type SdApiContractStructuralNode } from '../api-contract.schema';
|
|
2
|
+
import type { SdApiContractNodeEditRequest } from './api-contract-node-drawer.component';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
type SdApiContractNodeRecord = Record<string, SdApiContractStructuralNode>;
|
|
5
|
+
interface SdApiContractRecordEntry {
|
|
6
|
+
key: string;
|
|
7
|
+
node: SdApiContractStructuralNode;
|
|
8
|
+
path: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* One keyed collection of nodes — `req.path` / `req.query` / `req.headers` / `res.headers` — rendered
|
|
12
|
+
* as a list you read, not a list you type into.
|
|
13
|
+
*
|
|
14
|
+
* Every entry is a collapsed row. Adding and editing both ask the builder to open its drawer; only
|
|
15
|
+
* removal is applied straight away, because there is nothing to stage about deleting a row. That is
|
|
16
|
+
* why `add()` emits an edit request rather than an entry: a half-declared field must never reach the
|
|
17
|
+
* contract just because someone clicked the add button and changed their mind.
|
|
18
|
+
*/
|
|
19
|
+
export declare class SdApiContractRecordEditor {
|
|
20
|
+
#private;
|
|
21
|
+
record: import("@angular/core").InputSignal<SdApiContractNodeRecord | undefined>;
|
|
22
|
+
/** Diagnostic path of the collection itself, e.g. `req.query`. */
|
|
23
|
+
basePath: import("@angular/core").InputSignal<string>;
|
|
24
|
+
disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
25
|
+
emptyLabel: import("@angular/core").InputSignal<string>;
|
|
26
|
+
autoId: import("@angular/core").InputSignal<string | null | undefined>;
|
|
27
|
+
recordChange: import("@angular/core").OutputEmitterRef<SdApiContractNodeRecord>;
|
|
28
|
+
editRequest: import("@angular/core").OutputEmitterRef<SdApiContractNodeEditRequest>;
|
|
29
|
+
protected readonly entries: import("@angular/core").Signal<SdApiContractRecordEntry[]>;
|
|
30
|
+
protected requestAdd(): void;
|
|
31
|
+
protected requestEdit(entry: SdApiContractRecordEntry): void;
|
|
32
|
+
protected remove(key: string): void;
|
|
33
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SdApiContractRecordEditor, never>;
|
|
34
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SdApiContractRecordEditor, "sd-api-contract-record-editor", never, { "record": { "alias": "record"; "required": false; "isSignal": true; }; "basePath": { "alias": "basePath"; "required": true; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "emptyLabel": { "alias": "emptyLabel"; "required": false; "isSignal": true; }; "autoId": { "alias": "autoId"; "required": false; "isSignal": true; }; }, { "recordChange": "recordChange"; "editRequest": "editRequest"; }, never, never, true, never>;
|
|
35
|
+
}
|
|
36
|
+
export {};
|
package/components/api-contract-builder/src/components/api-contract-source-editor.component.d.ts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { SdApiContractStructuralNode } from '../api-contract.schema';
|
|
2
|
+
import type { SdApiContractSuggestion } from './api-contract-suggestion.model';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* How a mapped node receives its value.
|
|
6
|
+
*
|
|
7
|
+
* - `source` — one whole-value reference, picked from a dropdown.
|
|
8
|
+
* - `advanced` — a raw template the dropdown cannot express, e.g. `Bearer ${env.token}`.
|
|
9
|
+
* - `static` — a literal typed in a control that matches the declared type.
|
|
10
|
+
* - `nested` — an object mapped field by field.
|
|
11
|
+
* - `none` — CHƯA GÁN. Không phải một lựa chọn trong picker: picker để trống + `required`, nên node
|
|
12
|
+
* chưa gán là lỗi thấy ngay trên hàng thay vì một giá trị trông như đã chọn.
|
|
13
|
+
*/
|
|
14
|
+
export type SdApiContractValueMode = 'source' | 'advanced' | 'static' | 'nested' | 'none';
|
|
15
|
+
interface SdApiContractOption {
|
|
16
|
+
value: string;
|
|
17
|
+
label: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Value editor for one mapped node: a mode picker plus one control chosen by the mode.
|
|
21
|
+
*
|
|
22
|
+
* `source` shows a single dropdown of the references the surrounding schemas and the injected env
|
|
23
|
+
* catalog make available — the author never types `${…}` for the common case. `advanced` keeps a raw
|
|
24
|
+
* expression field for what a dropdown cannot express (`Bearer ${env.token}`). `static` renders a
|
|
25
|
+
* control matching the declared type, including a JSON editor for `object` / `array` literals.
|
|
26
|
+
*
|
|
27
|
+
* The JSON editor for a composite literal only writes when the text parses. While it is half-typed it
|
|
28
|
+
* emits the raw string, and that string is dropped — otherwise one keystroke would turn a literal
|
|
29
|
+
* object into a garbage string in the contract.
|
|
30
|
+
*/
|
|
31
|
+
export declare class SdApiContractSourceEditor {
|
|
32
|
+
#private;
|
|
33
|
+
node: import("@angular/core").InputSignal<SdApiContractStructuralNode>;
|
|
34
|
+
suggestions: import("@angular/core").InputSignal<readonly SdApiContractSuggestion[]>;
|
|
35
|
+
disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
36
|
+
autoId: import("@angular/core").InputSignal<string | null | undefined>;
|
|
37
|
+
nodeChange: import("@angular/core").OutputEmitterRef<SdApiContractStructuralNode>;
|
|
38
|
+
protected readonly advancedPlaceholder = "Bearer ${env.token}";
|
|
39
|
+
protected readonly booleanOptions: SdApiContractOption[];
|
|
40
|
+
protected readonly mode: import("@angular/core").WritableSignal<SdApiContractValueMode>;
|
|
41
|
+
/**
|
|
42
|
+
* Giá trị hiển thị của picker.
|
|
43
|
+
*
|
|
44
|
+
* why: `none` không còn là một option, nên bind nó vào `[model]` sẽ ra một ô trống mà người dùng
|
|
45
|
+
* không hiểu tại sao. Trả `null` để picker rỗng THẬT — cộng `required`, một node chưa gán trở thành
|
|
46
|
+
* lỗi thấy được ngay trên hàng, khớp với diagnostic `mapping.node.unmapped` mà validation đã báo.
|
|
47
|
+
*/
|
|
48
|
+
protected readonly modeValue: import("@angular/core").Signal<SdApiContractValueMode | null>;
|
|
49
|
+
protected readonly modeOptions: import("@angular/core").Signal<SdApiContractOption[]>;
|
|
50
|
+
protected readonly suggestionOptions: import("@angular/core").Signal<SdApiContractSuggestion[]>;
|
|
51
|
+
/**
|
|
52
|
+
* Options for the source dropdown.
|
|
53
|
+
*
|
|
54
|
+
* why: một `source` đang lưu có thể trỏ vào trường đã bị xoá hoặc đổi tên — nó KHÔNG còn trong
|
|
55
|
+
* danh sách gợi ý. `sd-select` không tìm thấy value sẽ hiện ô rỗng, và giá trị vẫn nằm trong
|
|
56
|
+
* contract mà người dùng không thấy để sửa. Thêm một option dựng từ chính giá trị đó để nó luôn
|
|
57
|
+
* hiển thị; validation lo phần báo `mapping.reference.missing`.
|
|
58
|
+
*/
|
|
59
|
+
protected readonly sourceOptions: import("@angular/core").Signal<SdApiContractSuggestion[]>;
|
|
60
|
+
protected readonly staticText: import("@angular/core").Signal<string>;
|
|
61
|
+
protected readonly staticNumber: import("@angular/core").Signal<number | null>;
|
|
62
|
+
protected setMode(mode: unknown): void;
|
|
63
|
+
protected setSource(value: unknown): void;
|
|
64
|
+
protected setStaticScalar(value: unknown): void;
|
|
65
|
+
protected setStaticNumber(value: unknown): void;
|
|
66
|
+
/**
|
|
67
|
+
* Stores a `date` / `datetime` literal.
|
|
68
|
+
*
|
|
69
|
+
* why: `<sd-date>` / `<sd-datetime>` có thể bắn ra một `Date`. `String(new Date())` ra
|
|
70
|
+
* `Mon Aug 17 2026 …` — không parse lại được và đổi theo locale của máy tác giả, nên contract sẽ
|
|
71
|
+
* mang một giá trị không portable. Chuẩn hoá về ISO.
|
|
72
|
+
*/
|
|
73
|
+
protected setStaticTemporal(value: unknown): void;
|
|
74
|
+
/**
|
|
75
|
+
* Stores an `object` / `array` literal from the JSON editor.
|
|
76
|
+
*
|
|
77
|
+
* why: `<sd-code-editor language="json">` bắn ra STRING khi cú pháp còn dở (`{"a":`). Ghi chuỗi đó
|
|
78
|
+
* vào contract sẽ biến một literal object thành rác, nên bỏ qua và giữ giá trị hợp lệ cuối cùng —
|
|
79
|
+
* người dùng vẫn thấy nguyên văn mình đang gõ trong editor.
|
|
80
|
+
*/
|
|
81
|
+
protected setStaticJson(value: unknown): void;
|
|
82
|
+
protected setStaticBoolean(value: unknown): void;
|
|
83
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SdApiContractSourceEditor, never>;
|
|
84
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SdApiContractSourceEditor, "sd-api-contract-source-editor", never, { "node": { "alias": "node"; "required": true; "isSignal": true; }; "suggestions": { "alias": "suggestions"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "autoId": { "alias": "autoId"; "required": false; "isSignal": true; }; }, { "nodeChange": "nodeChange"; }, never, never, true, never>;
|
|
85
|
+
}
|
|
86
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { SdApiContractDataType, SdApiContractExpressionRoot } from '../api-contract.model';
|
|
2
|
+
/**
|
|
3
|
+
* One `${…}` reference the source editor can offer.
|
|
4
|
+
*
|
|
5
|
+
* Internal to the builder UI — it is derived from the contract and the injected env catalog on every
|
|
6
|
+
* edit, so it is never persisted and never part of the public surface.
|
|
7
|
+
*/
|
|
8
|
+
export interface SdApiContractSuggestion {
|
|
9
|
+
/** Ready-to-insert text, e.g. `${input.customer.id}`. */
|
|
10
|
+
expression: string;
|
|
11
|
+
/** Dotted path without the delimiters, e.g. `input.customer.id`. */
|
|
12
|
+
path: string;
|
|
13
|
+
root: SdApiContractExpressionRoot;
|
|
14
|
+
type: SdApiContractDataType;
|
|
15
|
+
/** What the picker shows. Never contains a value — a sensitive variable only shows its name. */
|
|
16
|
+
display: string;
|
|
17
|
+
}
|
|
@@ -23,6 +23,7 @@ export declare class SdBadge {
|
|
|
23
23
|
onClick: (event: Event) => void;
|
|
24
24
|
onActivateKey: (event: Event) => void;
|
|
25
25
|
effectiveColor: import("@angular/core").Signal<Color>;
|
|
26
|
+
accessibleName: import("@angular/core").Signal<string>;
|
|
26
27
|
baseColorClasses: import("@angular/core").Signal<{
|
|
27
28
|
'c-primary': boolean;
|
|
28
29
|
'c-secondary': boolean;
|
package/components/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export * from '@sdcorejs/angular/components/section';
|
|
|
13
13
|
export * from '@sdcorejs/angular/components/inform';
|
|
14
14
|
export * from '@sdcorejs/angular/components/form-generic';
|
|
15
15
|
export * from '@sdcorejs/angular/components/anchor';
|
|
16
|
+
export * from '@sdcorejs/angular/components/api-contract-builder';
|
|
16
17
|
export * from '@sdcorejs/angular/components/query-builder';
|
|
17
18
|
export * from '@sdcorejs/angular/components/org-chart';
|
|
18
19
|
export * from '@sdcorejs/angular/components/tree';
|
|
@@ -13,6 +13,8 @@ export declare class SdSection {
|
|
|
13
13
|
readonly bodyId: string;
|
|
14
14
|
constructor();
|
|
15
15
|
toggleCollapse: () => void;
|
|
16
|
+
protected onHeaderClick: (event: MouseEvent) => void;
|
|
17
|
+
protected onCollapseButtonClick: (event: MouseEvent) => void;
|
|
16
18
|
onHeaderKeydown: (event: KeyboardEvent) => void;
|
|
17
19
|
static ɵfac: i0.ɵɵFactoryDeclaration<SdSection, never>;
|
|
18
20
|
static ɵcmp: i0.ɵɵComponentDeclaration<SdSection, "sd-section", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "subTitle": { "alias": "subTitle"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "iconColor": { "alias": "iconColor"; "required": false; "isSignal": true; }; "collapsed": { "alias": "collapsed"; "required": false; "isSignal": true; }; "collapsible": { "alias": "collapsible"; "required": false; "isSignal": true; }; "hideHeader": { "alias": "hideHeader"; "required": false; "isSignal": true; }; }, { "collapsed": "collapsedChange"; }, never, ["[sdHeaderLeft]", "[sdHeaderRight]", "*", "[sdFooterLeft]", "[sdFooterRight]"], true, never>;
|