@tsonic/core 0.1.2 → 0.3.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/attributes.d.ts +157 -0
- package/package.json +1 -1
- package/types.d.ts +41 -0
package/attributes.d.ts
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
// @tsonic/core/attributes.d.ts
|
|
2
|
+
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Compiler-only attribute API for Tsonic.
|
|
7
|
+
*
|
|
8
|
+
* Design goals:
|
|
9
|
+
* - Clean, consistent, "compiler-grade" surface area.
|
|
10
|
+
* - Fully type-safe selection of targets (type / ctor / method / property).
|
|
11
|
+
* - Attributes are represented as:
|
|
12
|
+
* - A constructor reference (e.g., ObsoleteAttribute)
|
|
13
|
+
* - Optional ctor args (typed via ConstructorParameters)
|
|
14
|
+
* - Optional helper `A.attr(...)` to build an attribute descriptor (also typed).
|
|
15
|
+
*
|
|
16
|
+
* Runtime note:
|
|
17
|
+
* This module is expected to be erased/ignored by the compiler pipeline.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/** A class constructor type. */
|
|
21
|
+
export type Ctor<T = unknown, Args extends readonly any[] = readonly any[]> = new (
|
|
22
|
+
...args: Args
|
|
23
|
+
) => T;
|
|
24
|
+
|
|
25
|
+
/** Any attribute class constructor. */
|
|
26
|
+
export type AttributeCtor = Ctor<object, readonly any[]>;
|
|
27
|
+
|
|
28
|
+
/** Attribute application (constructor + ctor arguments). */
|
|
29
|
+
export interface AttributeDescriptor<C extends AttributeCtor = AttributeCtor> {
|
|
30
|
+
readonly kind: "attribute";
|
|
31
|
+
readonly ctor: C;
|
|
32
|
+
readonly args: readonly ConstructorParameters<C>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Extract instance type of a constructor. */
|
|
36
|
+
export type InstanceOf<C extends Ctor<any, any>> = C extends Ctor<infer I, any>
|
|
37
|
+
? I
|
|
38
|
+
: never;
|
|
39
|
+
|
|
40
|
+
/** Keys of T whose values are callable. */
|
|
41
|
+
export type MethodKeys<T> = {
|
|
42
|
+
[K in keyof T]-?: T[K] extends (...args: any[]) => any ? K : never;
|
|
43
|
+
}[keyof T];
|
|
44
|
+
|
|
45
|
+
/** Keys of T whose values are NOT callable (i.e., "properties"). */
|
|
46
|
+
export type PropertyKeys<T> = {
|
|
47
|
+
[K in keyof T]-?: T[K] extends (...args: any[]) => any ? never : K;
|
|
48
|
+
}[keyof T];
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Inferred "method value type" from a method selector.
|
|
52
|
+
* The selector must resolve to a function-valued member on T.
|
|
53
|
+
*/
|
|
54
|
+
export type SelectedMethodValue<T> = (...args: any[]) => any;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Fluent builder returned from A.on(Foo).
|
|
58
|
+
* Allows attaching attributes to:
|
|
59
|
+
* - the type itself
|
|
60
|
+
* - the constructor
|
|
61
|
+
* - a method
|
|
62
|
+
* - a property
|
|
63
|
+
*/
|
|
64
|
+
export interface OnBuilder<T> {
|
|
65
|
+
/** Attach attributes to the type declaration (C# class/interface). */
|
|
66
|
+
type: AttributeTargetBuilder;
|
|
67
|
+
|
|
68
|
+
/** Attach attributes to the constructor. */
|
|
69
|
+
ctor: AttributeTargetBuilder;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Select a method to annotate.
|
|
73
|
+
*
|
|
74
|
+
* The selector must be a simple member access in practice (enforced by compiler),
|
|
75
|
+
* but is typed here as: (t: T) => T[K] where K is a method key.
|
|
76
|
+
*
|
|
77
|
+
* Example:
|
|
78
|
+
* A.on(User).method(u => u.save).add(TransactionAttribute);
|
|
79
|
+
*/
|
|
80
|
+
method<K extends MethodKeys<T>>(
|
|
81
|
+
selector: (t: T) => T[K]
|
|
82
|
+
): AttributeTargetBuilder;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Select a property to annotate.
|
|
86
|
+
*
|
|
87
|
+
* Example:
|
|
88
|
+
* A.on(User).prop(u => u.name).add(JsonPropertyNameAttribute, "name");
|
|
89
|
+
*/
|
|
90
|
+
prop<K extends PropertyKeys<T>>(
|
|
91
|
+
selector: (t: T) => T[K]
|
|
92
|
+
): AttributeTargetBuilder;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Target builder that supports adding attributes.
|
|
97
|
+
* Supports two canonical forms:
|
|
98
|
+
* - add(AttrCtor, ...args)
|
|
99
|
+
* - add(A.attr(AttrCtor, ...args))
|
|
100
|
+
*/
|
|
101
|
+
export interface AttributeTargetBuilder {
|
|
102
|
+
/**
|
|
103
|
+
* Add an attribute by constructor + arguments.
|
|
104
|
+
*
|
|
105
|
+
* Example:
|
|
106
|
+
* A.on(Config).type.add(ObsoleteAttribute, "Will be removed in v2");
|
|
107
|
+
*/
|
|
108
|
+
add<C extends AttributeCtor>(
|
|
109
|
+
ctor: C,
|
|
110
|
+
...args: ConstructorParameters<C>
|
|
111
|
+
): void;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Add an attribute descriptor produced by A.attr(...).
|
|
115
|
+
*
|
|
116
|
+
* Example:
|
|
117
|
+
* A.on(Config).type.add(A.attr(ObsoleteAttribute, "Will be removed in v2"));
|
|
118
|
+
*/
|
|
119
|
+
add<C extends AttributeCtor>(descriptor: AttributeDescriptor<C>): void;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* The main entrypoint.
|
|
124
|
+
*
|
|
125
|
+
* Usage:
|
|
126
|
+
* import { attributes as A } from "@tsonic/core/attributes.js";
|
|
127
|
+
*
|
|
128
|
+
* class Config {}
|
|
129
|
+
* A.on(Config).type.add(SerializableAttribute);
|
|
130
|
+
* A.on(Config).type.add(ObsoleteAttribute, "Will be removed in v2");
|
|
131
|
+
*
|
|
132
|
+
* Emits:
|
|
133
|
+
* [System.SerializableAttribute]
|
|
134
|
+
* [System.ObsoleteAttribute("Will be removed in v2")]
|
|
135
|
+
*/
|
|
136
|
+
export interface AttributesApi {
|
|
137
|
+
/**
|
|
138
|
+
* Begin targeting a type by passing its constructor.
|
|
139
|
+
*/
|
|
140
|
+
on<C extends Ctor<any, any>>(ctor: C): OnBuilder<InstanceOf<C>>;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Build an attribute descriptor (compiler-known "attribute instance").
|
|
144
|
+
*
|
|
145
|
+
* Example:
|
|
146
|
+
* A.on(Config).type.add(A.attr(ObsoleteAttribute, "Will be removed in v2"));
|
|
147
|
+
*/
|
|
148
|
+
attr<C extends AttributeCtor>(
|
|
149
|
+
ctor: C,
|
|
150
|
+
...args: ConstructorParameters<C>
|
|
151
|
+
): AttributeDescriptor<C>;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Named export used by consumers.
|
|
156
|
+
*/
|
|
157
|
+
export declare const attributes: AttributesApi;
|
package/package.json
CHANGED
package/types.d.ts
CHANGED
|
@@ -55,3 +55,44 @@ export type ptr<T> = unknown;
|
|
|
55
55
|
// NOTE: ref<T>, out<T>, In<T> have been removed.
|
|
56
56
|
// Parameter modifiers will be expressed via syntax, not types.
|
|
57
57
|
// See spec for forthcoming ref/out/in parameter syntax.
|
|
58
|
+
|
|
59
|
+
// ============================================================================
|
|
60
|
+
// Value Type Markers
|
|
61
|
+
// ============================================================================
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Marker interface for C# struct types.
|
|
65
|
+
*
|
|
66
|
+
* Types that extend `struct` will be emitted as C# structs instead of classes.
|
|
67
|
+
* This enables value semantics and stack allocation in the generated code.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* import { struct } from "@tsonic/core/types.js";
|
|
72
|
+
*
|
|
73
|
+
* // This becomes a C# struct
|
|
74
|
+
* export interface Point extends struct {
|
|
75
|
+
* x: number;
|
|
76
|
+
* y: number;
|
|
77
|
+
* }
|
|
78
|
+
*
|
|
79
|
+
* // Use as generic constraint for nullable value types
|
|
80
|
+
* function wrap<T extends struct>(value: T | null): T | null {
|
|
81
|
+
* return value;
|
|
82
|
+
* }
|
|
83
|
+
* ```
|
|
84
|
+
*
|
|
85
|
+
* In C#, this emits:
|
|
86
|
+
* ```csharp
|
|
87
|
+
* public struct Point {
|
|
88
|
+
* public double x { get; set; }
|
|
89
|
+
* public double y { get; set; }
|
|
90
|
+
* }
|
|
91
|
+
*
|
|
92
|
+
* // With constraint: where T : struct
|
|
93
|
+
* T? Wrap<T>(T? value) where T : struct => value;
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export interface struct {
|
|
97
|
+
readonly __brand: unique symbol;
|
|
98
|
+
}
|