@common-grants/core 0.1.0-alpha.6 → 0.1.0-alpha.7
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/README.md +8 -7
- package/lib/main.tsp +7 -3
- package/lib/models/custom-enum.tsp +27 -0
- package/lib/models/custom-field.tsp +22 -3
- package/lib/models/event.tsp +3 -2
- package/lib/models/index.tsp +30 -5
- package/lib/models/metadata.tsp +41 -0
- package/lib/models/money.tsp +1 -0
- package/lib/models/{funding.tsp → opportunity/funding.tsp} +14 -2
- package/lib/models/{opportunity.tsp → opportunity/index.tsp} +27 -34
- package/lib/models/opportunity/status.tsp +33 -0
- package/lib/models/opportunity/timeline.tsp +42 -0
- package/lib/responses/errors.tsp +11 -0
- package/lib/responses/success.tsp +36 -2
- package/lib/routes/opportunities.tsp +5 -5
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -48,16 +48,17 @@ model Agency extends CustomField {
|
|
|
48
48
|
|
|
49
49
|
@example("Department of Transportation")
|
|
50
50
|
value: string;
|
|
51
|
-
description: "The agency responsible for this opportunity";
|
|
52
|
-
}
|
|
53
51
|
|
|
54
|
-
|
|
55
|
-
model CustomFields extends CustomFieldMap {
|
|
56
|
-
agency: Agency;
|
|
52
|
+
description: "The agency responsible for this opportunity";
|
|
57
53
|
}
|
|
58
54
|
|
|
59
|
-
//
|
|
60
|
-
|
|
55
|
+
// Extend the `OpportunityBase` model to create a new `CustomOpportunity` model
|
|
56
|
+
// that includes the new `Agency` field in its `customFields` property
|
|
57
|
+
model CustomOpportunity extends OpportunityBase {
|
|
58
|
+
customFields: {
|
|
59
|
+
agency: Agency;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
61
62
|
```
|
|
62
63
|
|
|
63
64
|
### Override default routes
|
package/lib/main.tsp
CHANGED
|
@@ -9,13 +9,17 @@ import "./routes/index.tsp";
|
|
|
9
9
|
|
|
10
10
|
using TypeSpec.Http;
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
/** The base OpenAPI specification for a CommonGrants API
|
|
13
|
+
*
|
|
14
|
+
* In order for an API to be "compliant" with the CommonGrants protocol,
|
|
15
|
+
* it must implement all of the routes included in this base specification.
|
|
16
|
+
*/
|
|
13
17
|
@service({
|
|
14
|
-
|
|
18
|
+
title: "Base API",
|
|
15
19
|
})
|
|
16
20
|
namespace CommonGrants.API;
|
|
17
21
|
|
|
18
|
-
@tag("
|
|
22
|
+
@tag("Opportunities")
|
|
19
23
|
@route("/opportunities")
|
|
20
24
|
namespace Opportunities {
|
|
21
25
|
alias Router = Routes.Opportunities;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
namespace CommonGrants.Models;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A custom enum value, designed to be used as part of a union with known options
|
|
5
|
+
*
|
|
6
|
+
* @example How to use this CustomEnumValue in a union
|
|
7
|
+
*
|
|
8
|
+
* ```typespec
|
|
9
|
+
* union OpportunityStatus {
|
|
10
|
+
* open: {
|
|
11
|
+
* value: "open",
|
|
12
|
+
* description?: "Opportunity is actively accepting applications",
|
|
13
|
+
* },
|
|
14
|
+
* closed: {
|
|
15
|
+
* value: "closed",
|
|
16
|
+
* description?: "Opportunity is no longer accepting applications",
|
|
17
|
+
* },
|
|
18
|
+
* custom: CustomEnumValue,
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
@doc("Custom value not included in the standard list of options.")
|
|
23
|
+
model CustomEnumValue {
|
|
24
|
+
value: "custom";
|
|
25
|
+
customValue: string;
|
|
26
|
+
description: string;
|
|
27
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
namespace CommonGrants.Models;
|
|
2
2
|
|
|
3
3
|
// ########################################
|
|
4
|
-
//
|
|
4
|
+
// Field types definition
|
|
5
5
|
// ########################################
|
|
6
6
|
|
|
7
7
|
/** The set of JSON schema types supported by a custom field */
|
|
@@ -13,9 +13,27 @@ enum CustomFieldType {
|
|
|
13
13
|
array,
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
// ########################################
|
|
17
|
+
// Models definition
|
|
18
|
+
// ########################################
|
|
18
19
|
|
|
20
|
+
/** Model for defining custom fields that are specific to a given implementation.
|
|
21
|
+
*
|
|
22
|
+
* @example How to define a custom field using this model
|
|
23
|
+
*
|
|
24
|
+
* ```typespec
|
|
25
|
+
* model Agency extends CustomField {
|
|
26
|
+
* name: "agency";
|
|
27
|
+
*
|
|
28
|
+
* type: CustomFieldType.string;
|
|
29
|
+
*
|
|
30
|
+
* @example("Department of Transportation")
|
|
31
|
+
* value: string;
|
|
32
|
+
*
|
|
33
|
+
* description?: "The agency responsible for managing this opportunity";
|
|
34
|
+
* }
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
19
37
|
@example(
|
|
20
38
|
CustomFieldExamples.programArea,
|
|
21
39
|
#{ title: "String field for program area" }
|
|
@@ -24,6 +42,7 @@ model CustomFieldMap is Record<CustomField>;
|
|
|
24
42
|
CustomFieldExamples.eligibilityTypes,
|
|
25
43
|
#{ title: "Array field for eligibility types" }
|
|
26
44
|
)
|
|
45
|
+
@doc("A custom field on a model") // Overrides internal docstrings when emitting OpenAPI
|
|
27
46
|
model CustomField {
|
|
28
47
|
/** Name of the custom field */
|
|
29
48
|
name: string;
|
package/lib/models/event.tsp
CHANGED
|
@@ -4,10 +4,11 @@ namespace CommonGrants.Models;
|
|
|
4
4
|
// Model definition
|
|
5
5
|
// ########################################
|
|
6
6
|
|
|
7
|
+
/** Description of an event that has a date (and possible time) associated with it */
|
|
7
8
|
@example(EventExamples.deadline, #{ title: "Application deadline with time" })
|
|
8
9
|
@example(EventExamples.openDate, #{ title: "Opening date without time" })
|
|
9
10
|
model Event {
|
|
10
|
-
/**
|
|
11
|
+
/** Human-readable name of the event (e.g., 'Application posted', 'Question deadline') */
|
|
11
12
|
name: string;
|
|
12
13
|
|
|
13
14
|
/** Date of the event in in ISO 8601 format: YYYY-MM-DD */
|
|
@@ -16,7 +17,7 @@ model Event {
|
|
|
16
17
|
/** Time of the event in ISO 8601 format: HH:MM:SS */
|
|
17
18
|
time?: isoTime;
|
|
18
19
|
|
|
19
|
-
/**
|
|
20
|
+
/** Description of what this event represents */
|
|
20
21
|
description?: string;
|
|
21
22
|
}
|
|
22
23
|
|
package/lib/models/index.tsp
CHANGED
|
@@ -5,13 +5,38 @@ import "@typespec/json-schema";
|
|
|
5
5
|
import "./base.tsp";
|
|
6
6
|
import "./custom-field.tsp";
|
|
7
7
|
import "./money.tsp";
|
|
8
|
-
import "./funding.tsp";
|
|
9
8
|
import "./event.tsp";
|
|
10
|
-
import "./
|
|
9
|
+
import "./metadata.tsp";
|
|
10
|
+
import "./custom-enum.tsp";
|
|
11
|
+
import "./opportunity/index.tsp";
|
|
11
12
|
|
|
12
13
|
using TypeSpec.JsonSchema;
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
// and emit these models as JSON schemas
|
|
16
|
-
@jsonSchema
|
|
15
|
+
/** Namespace for CommonGrants models that can be used in API routes */
|
|
16
|
+
@jsonSchema // and emit these models as JSON schemas
|
|
17
17
|
namespace CommonGrants.Models;
|
|
18
|
+
|
|
19
|
+
/** The base model for a funding opportunity.
|
|
20
|
+
*
|
|
21
|
+
* It supports customization by extending the `customFields` property.
|
|
22
|
+
*
|
|
23
|
+
* @example How to declare a new Opportunity model with custom fields
|
|
24
|
+
*
|
|
25
|
+
* ```typespec
|
|
26
|
+
* model Agency extends CustomField {
|
|
27
|
+
* type: CustomFieldType.string;
|
|
28
|
+
*
|
|
29
|
+
* @example("Department of Transportation")
|
|
30
|
+
* value: string;
|
|
31
|
+
* }
|
|
32
|
+
*
|
|
33
|
+
* model NewFields extends CustomFieldMap {
|
|
34
|
+
* agency: Agency;
|
|
35
|
+
* }
|
|
36
|
+
*
|
|
37
|
+
* model CustomOpportunity extends OpportunityBase {
|
|
38
|
+
* customFields: NewFields;
|
|
39
|
+
* }
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
alias OpportunityBase = Opportunity.OpportunityBase;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
namespace CommonGrants.Models;
|
|
2
|
+
|
|
3
|
+
// ########################################
|
|
4
|
+
// Model definition
|
|
5
|
+
// ########################################
|
|
6
|
+
|
|
7
|
+
/** Standard system-level metadata about a given record.
|
|
8
|
+
*
|
|
9
|
+
* @example How to spread the SystemMetadata props into another record
|
|
10
|
+
*
|
|
11
|
+
* ```typespec
|
|
12
|
+
* model Opportunity {
|
|
13
|
+
* id: uuid;
|
|
14
|
+
* title: string;
|
|
15
|
+
*
|
|
16
|
+
* // Includes SystemMetadata props in the root of the Opportunity model
|
|
17
|
+
* ...SystemMetadata;
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
* */
|
|
21
|
+
@example(MetadataExample.system)
|
|
22
|
+
model SystemMetadata {
|
|
23
|
+
/** The timestamp (in UTC) at which the record was created. */
|
|
24
|
+
@visibility(Lifecycle.Read)
|
|
25
|
+
createdAt: utcDateTime;
|
|
26
|
+
|
|
27
|
+
/** The timestamp (in UTC) at which the record was last modified. */
|
|
28
|
+
@visibility(Lifecycle.Read)
|
|
29
|
+
lastModifiedAt: utcDateTime;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// ########################################
|
|
33
|
+
// Model examples
|
|
34
|
+
// ########################################
|
|
35
|
+
|
|
36
|
+
namespace MetadataExample {
|
|
37
|
+
const system = #{
|
|
38
|
+
createdAt: utcDateTime.fromISO("2025-01-01T17:01:01"),
|
|
39
|
+
lastModifiedAt: utcDateTime.fromISO("2025-01-02T17:30:00"),
|
|
40
|
+
};
|
|
41
|
+
}
|
package/lib/models/money.tsp
CHANGED
|
@@ -4,6 +4,7 @@ namespace CommonGrants.Models;
|
|
|
4
4
|
// Model definition
|
|
5
5
|
// ########################################
|
|
6
6
|
|
|
7
|
+
/** A monetary amount and the currency in which its denominated */
|
|
7
8
|
@example(MoneyExamples.usdWithCents, #{ title: "US dollars and cents" })
|
|
8
9
|
@example(
|
|
9
10
|
MoneyExamples.euroWithoutCents,
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
import "../index.tsp";
|
|
2
2
|
|
|
3
|
-
namespace CommonGrants.Models;
|
|
3
|
+
namespace CommonGrants.Models.Opportunity;
|
|
4
4
|
|
|
5
5
|
// ########################################
|
|
6
6
|
// Model definition
|
|
7
7
|
// ########################################
|
|
8
8
|
|
|
9
|
+
/** Details about the funding available for this opportunity */
|
|
9
10
|
@example(FundingExamples.allFields, #{ title: "All fields defined" })
|
|
10
11
|
@example(
|
|
11
12
|
FundingExamples.awardRange,
|
|
@@ -16,11 +17,22 @@ namespace CommonGrants.Models;
|
|
|
16
17
|
#{ title: "Total funding limit but no award range" }
|
|
17
18
|
)
|
|
18
19
|
model FundingDetails {
|
|
20
|
+
/** Total amount of funding available for this opportunity */
|
|
19
21
|
totalAmountAvailable?: Money;
|
|
22
|
+
|
|
23
|
+
/** Minimum amount of funding granted per award */
|
|
20
24
|
minAwardAmount?: Money;
|
|
25
|
+
|
|
26
|
+
/** Maximum amount of funding granted per award */
|
|
21
27
|
maxAwardAmount?: Money;
|
|
28
|
+
|
|
29
|
+
/** Minimum number of awards granted */
|
|
22
30
|
minAwardCount?: integer;
|
|
31
|
+
|
|
32
|
+
/** Maximum number of awards granted */
|
|
23
33
|
maxAwardCount?: integer;
|
|
34
|
+
|
|
35
|
+
/** Estimated number of awards that will be granted */
|
|
24
36
|
estimatedAwardCount?: integer;
|
|
25
37
|
}
|
|
26
38
|
|
|
@@ -1,55 +1,46 @@
|
|
|
1
|
-
|
|
1
|
+
import "@typespec/json-schema";
|
|
2
|
+
|
|
3
|
+
import "./status.tsp";
|
|
4
|
+
import "./funding.tsp";
|
|
5
|
+
import "./timeline.tsp";
|
|
6
|
+
|
|
7
|
+
/** Namespace for CommonGrants models that are specific to funding opportunities */
|
|
8
|
+
@JsonSchema.jsonSchema
|
|
9
|
+
namespace CommonGrants.Models.Opportunity;
|
|
2
10
|
|
|
3
11
|
// ########################################
|
|
4
12
|
// Model definition
|
|
5
13
|
// ########################################
|
|
6
14
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
* It supports customization by templating the customFields property.
|
|
10
|
-
*
|
|
11
|
-
* @template Fields A CustomFieldMap object with user-defined custom fields,
|
|
12
|
-
* that should be included in a given implementation of the Opportunity model.
|
|
13
|
-
* @example Declare a new Opportunity model with custom fields
|
|
14
|
-
*
|
|
15
|
-
* ```typespec
|
|
16
|
-
* model Agency extends CustomField {
|
|
17
|
-
* type: CustomFieldType.string;
|
|
18
|
-
* value: string;
|
|
19
|
-
* }
|
|
20
|
-
*
|
|
21
|
-
* model NewFields extends CustomFieldMap {
|
|
22
|
-
* agency: Agency;
|
|
23
|
-
* }
|
|
24
|
-
*
|
|
25
|
-
* alias CustomOpportunity = Opportunity<NewFields>;
|
|
26
|
-
* ```
|
|
27
|
-
*/
|
|
28
|
-
@example(
|
|
29
|
-
OpportunityExamples.minimal,
|
|
30
|
-
#{ title: "Minimal opportunity with required fields only" }
|
|
31
|
-
)
|
|
32
|
-
model Opportunity<Fields = CustomFieldMap> {
|
|
15
|
+
@doc("A funding opportunity") // Overrides internal docstrings when emitting OpenAPI
|
|
16
|
+
model OpportunityBase {
|
|
33
17
|
/** Globally unique id for the opportunity */
|
|
18
|
+
@visibility(Lifecycle.Read)
|
|
34
19
|
id: uuid;
|
|
35
20
|
|
|
36
|
-
/** URL for the original source of the opportunity */
|
|
37
|
-
source: url;
|
|
38
|
-
|
|
39
21
|
/** Title or name of the funding opportunity */
|
|
40
22
|
title: string;
|
|
41
23
|
|
|
24
|
+
/** Status of the opportunity */
|
|
25
|
+
status: OppStatus;
|
|
26
|
+
|
|
42
27
|
/** Description of the opportunity's purpose and scope */
|
|
43
28
|
description: string;
|
|
44
29
|
|
|
45
30
|
/** Details about the funding available */
|
|
46
31
|
fundingDetails: FundingDetails;
|
|
47
32
|
|
|
48
|
-
/** Key dates
|
|
49
|
-
|
|
33
|
+
/** Key dates for the opportunity, such as when the application opens and closes */
|
|
34
|
+
keyDates: OppTimeline;
|
|
35
|
+
|
|
36
|
+
/** URL for the original source of the opportunity */
|
|
37
|
+
source?: url;
|
|
50
38
|
|
|
51
39
|
/** Additional custom fields specific to this opportunity */
|
|
52
|
-
customFields?:
|
|
40
|
+
customFields?: Record<CustomField>;
|
|
41
|
+
|
|
42
|
+
// Spreads the fields from the Metadata model into the Opportunity model
|
|
43
|
+
...SystemMetadata;
|
|
53
44
|
}
|
|
54
45
|
|
|
55
46
|
// ########################################
|
|
@@ -64,11 +55,12 @@ namespace OpportunityExamples {
|
|
|
64
55
|
title: "Healthcare Innovation Research Grant",
|
|
65
56
|
description: "Funding for innovative healthcare delivery solutions",
|
|
66
57
|
fundingDetails: FundingExamples.allFields,
|
|
67
|
-
|
|
58
|
+
keyDates: #[EventExamples.openDate, EventExamples.deadline],
|
|
68
59
|
customFields: #{
|
|
69
60
|
programArea: CustomFieldExamples.programArea,
|
|
70
61
|
eligibilityType: CustomFieldExamples.programArea,
|
|
71
62
|
},
|
|
63
|
+
...MetadataExample.system,
|
|
72
64
|
};
|
|
73
65
|
|
|
74
66
|
/** A minimal opportunity example with only required fields */
|
|
@@ -78,5 +70,6 @@ namespace OpportunityExamples {
|
|
|
78
70
|
title: "Small Business Innovation Grant",
|
|
79
71
|
description: "Supporting small business innovation projects",
|
|
80
72
|
fundingDetails: FundingExamples.onlyLimit,
|
|
73
|
+
...MetadataExample.system,
|
|
81
74
|
};
|
|
82
75
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import "@typespec/json-schema";
|
|
2
|
+
import "@typespec/openapi3";
|
|
3
|
+
|
|
4
|
+
import "../custom-enum.tsp";
|
|
5
|
+
|
|
6
|
+
namespace CommonGrants.Models.Opportunity;
|
|
7
|
+
|
|
8
|
+
/** Union of values accepted for opportunity status */
|
|
9
|
+
@JsonSchema.oneOf
|
|
10
|
+
@OpenAPI.oneOf
|
|
11
|
+
@discriminator("value")
|
|
12
|
+
union OppStatus {
|
|
13
|
+
/** Opportunity is anticipated, but not yet accepting applications */
|
|
14
|
+
forecasted: {
|
|
15
|
+
value: "forecasted",
|
|
16
|
+
description?: "Opportunity is anticipated, but not yet accepting applications",
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
/** Opportunity is actively accepting applications */
|
|
20
|
+
open: {
|
|
21
|
+
value: "open",
|
|
22
|
+
description?: "Opportunity is actively accepting applications",
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
/** Opportunity is no longer accepting applications */
|
|
26
|
+
closed: {
|
|
27
|
+
value: "closed",
|
|
28
|
+
description?: "Opportunity is no longer accepting applications",
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
/** Custom opportunity status */
|
|
32
|
+
custom: CustomEnumValue,
|
|
33
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import "../event.tsp";
|
|
2
|
+
import "../custom-enum.tsp";
|
|
3
|
+
|
|
4
|
+
namespace CommonGrants.Models.Opportunity;
|
|
5
|
+
|
|
6
|
+
// ########################################
|
|
7
|
+
// Model definition
|
|
8
|
+
// ########################################
|
|
9
|
+
|
|
10
|
+
/** Key dates in the opportunity's timeline, such as when the application opens and closes */
|
|
11
|
+
@example(TimelineExamples.opportunity)
|
|
12
|
+
model OppTimeline {
|
|
13
|
+
/** The date (and time) at which the opportunity begins accepting applications */
|
|
14
|
+
appOpens?: Event;
|
|
15
|
+
|
|
16
|
+
/** The final deadline for submitting applications */
|
|
17
|
+
appDeadline?: Event;
|
|
18
|
+
|
|
19
|
+
/** An optional map of other key dates in the opportunity timeline
|
|
20
|
+
*
|
|
21
|
+
* Examples might include a deadline for questions, anticipated award date, etc.
|
|
22
|
+
*/
|
|
23
|
+
otherDates?: Record<Event>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// ########################################
|
|
27
|
+
// Model examples
|
|
28
|
+
// ########################################
|
|
29
|
+
|
|
30
|
+
namespace TimelineExamples {
|
|
31
|
+
const opportunity = #{
|
|
32
|
+
appOpens: EventExamples.openDate,
|
|
33
|
+
appDeadline: EventExamples.deadline,
|
|
34
|
+
otherDates: #{
|
|
35
|
+
anticipatedAward: #{
|
|
36
|
+
name: "Anticipated award date",
|
|
37
|
+
date: isoDate.fromISO("2025-03-15"),
|
|
38
|
+
description: "When we expect to announce awards for this opportunity.",
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
package/lib/responses/errors.tsp
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
namespace Responses.Error;
|
|
2
2
|
|
|
3
|
+
/** A standard error response schema, used to create custom error responses
|
|
4
|
+
*
|
|
5
|
+
* @example - How to use this model to create custom error response schemas
|
|
6
|
+
*
|
|
7
|
+
* ```
|
|
8
|
+
* import "@typespec/http"
|
|
9
|
+
*
|
|
10
|
+
* alias Unauthorized = Error & Http.UnauthorizedResponse
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
3
13
|
@error
|
|
14
|
+
@doc("A non-2xx response schema")
|
|
4
15
|
model Error {
|
|
5
16
|
@example(400)
|
|
6
17
|
status: int32;
|
|
@@ -8,7 +8,24 @@ model Success {
|
|
|
8
8
|
message: string;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
/** Template for
|
|
11
|
+
/** Template for a 200 response with data
|
|
12
|
+
*
|
|
13
|
+
* @template T The schema for the value of the `"data"` property in this response
|
|
14
|
+
* @example How to specify a custom 200 response model
|
|
15
|
+
*
|
|
16
|
+
* ```typespec
|
|
17
|
+
*
|
|
18
|
+
* // Define a model
|
|
19
|
+
* model CustomModel {
|
|
20
|
+
* id: string;
|
|
21
|
+
* description: string;
|
|
22
|
+
* }
|
|
23
|
+
*
|
|
24
|
+
* // Pass that model to the `Ok` template
|
|
25
|
+
* alias CustomModel200 = Success.Ok<CustomModel>;
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
@doc("A 200 response with data")
|
|
12
29
|
model Ok<T> extends Success {
|
|
13
30
|
// Inherit the 200 status code
|
|
14
31
|
...Http.OkResponse;
|
|
@@ -17,7 +34,24 @@ model Ok<T> extends Success {
|
|
|
17
34
|
data: T;
|
|
18
35
|
}
|
|
19
36
|
|
|
20
|
-
/** Template for paginated
|
|
37
|
+
/** Template for a 200 response with paginated list of items
|
|
38
|
+
*
|
|
39
|
+
* @template T The schema for the value of the `"items"` property in this response
|
|
40
|
+
* @example How to specify a custom paginated response model
|
|
41
|
+
*
|
|
42
|
+
* ```typespec
|
|
43
|
+
*
|
|
44
|
+
* // Define a model
|
|
45
|
+
* model CustomModel {
|
|
46
|
+
* id: string;
|
|
47
|
+
* description: string;
|
|
48
|
+
* }
|
|
49
|
+
*
|
|
50
|
+
* // Pass that model to the `Ok` template
|
|
51
|
+
* alias CustomModelResponse = Success.Paginated<CustomModel>;
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
@doc("A 200 response with a paginated list of items")
|
|
21
55
|
model Paginated<T> extends Success {
|
|
22
56
|
// Inherit the 200 status code
|
|
23
57
|
...Http.OkResponse;
|
|
@@ -52,24 +52,24 @@ interface Opportunities {
|
|
|
52
52
|
/** `GET /opportunities/` Get a paginated list of opportunities
|
|
53
53
|
*
|
|
54
54
|
* @template T Type of the paginated response model.
|
|
55
|
-
* Must be an extension of Models.
|
|
55
|
+
* Must be an extension of Models.OpportunityBase. Default is Models.OpportunityBase.
|
|
56
56
|
*/
|
|
57
57
|
@summary("List opportunities")
|
|
58
|
-
@doc("Get a paginated list of opportunities")
|
|
58
|
+
@doc("Get a paginated list of opportunities, sorted by `lastModifiedAt` with most recent first.")
|
|
59
59
|
@list
|
|
60
|
-
list<T extends Models.
|
|
60
|
+
list<T extends Models.OpportunityBase = Models.OpportunityBase>(
|
|
61
61
|
...PaginatedQuery,
|
|
62
62
|
): Success.Paginated<T> | Error.Unauthorized;
|
|
63
63
|
|
|
64
64
|
/** `GET /opportunities/<id>` View opportunity details
|
|
65
65
|
*
|
|
66
66
|
* @template T Type of the response model.
|
|
67
|
-
* Must be an extension of Models.
|
|
67
|
+
* Must be an extension of Models.OpportunityBase. Default is Models.OpportunityBase.
|
|
68
68
|
*/
|
|
69
69
|
@summary("View opportunity")
|
|
70
70
|
@doc("View additional details about an opportunity")
|
|
71
71
|
@get
|
|
72
|
-
read<T extends Models.
|
|
72
|
+
read<T extends Models.OpportunityBase = Models.OpportunityBase>(
|
|
73
73
|
@path id: Models.uuid,
|
|
74
74
|
): Success.Ok<T> | Error.NotFound | Error.Unauthorized;
|
|
75
75
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@common-grants/core",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.7",
|
|
4
4
|
"description": "TypeSpec library for defining grant opportunity data models and APIs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -31,7 +31,10 @@
|
|
|
31
31
|
"format": "prettier --write . && tsp format lib",
|
|
32
32
|
"check:lint": "eslint",
|
|
33
33
|
"check:format": "prettier --check . && tsp format lib --check",
|
|
34
|
-
"checks": "npm run check:lint && npm run check:format"
|
|
34
|
+
"checks": "npm run check:lint && npm run check:format",
|
|
35
|
+
"docs:build": "npx @redocly/cli build-docs tsp-output/@typespec/openapi3/openapi.yaml --output ./dist/redocly.html",
|
|
36
|
+
"docs:preview": "open ./dist/redocly.html",
|
|
37
|
+
"docs": "npm run typespec && npm run docs:build && npm run docs:preview"
|
|
35
38
|
},
|
|
36
39
|
"keywords": [
|
|
37
40
|
"typespec",
|