@common-grants/core 0.1.1 → 0.2.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/README.md +10 -1
- package/lib/api.tsp +93 -1
- package/lib/core/fields/custom-field.tsp +7 -0
- package/lib/core/fields/file.tsp +49 -0
- package/lib/core/fields/index.tsp +1 -0
- package/lib/core/models/applicant-type.tsp +96 -0
- package/lib/core/models/application.tsp +60 -82
- package/lib/core/models/competition.tsp +156 -0
- package/lib/core/models/form-response.tsp +99 -0
- package/lib/core/models/form.tsp +119 -0
- package/lib/core/models/index.tsp +6 -0
- package/lib/core/models/mapping.tsp +152 -0
- package/lib/core/models/opportunity/base.tsp +13 -0
- package/lib/core/models/opportunity/status.tsp +8 -3
- package/lib/core/models/proposal.tsp +173 -0
- package/lib/core/responses/error.tsp +11 -0
- package/lib/core/responses/success.tsp +16 -0
- package/lib/core/routes/applications.tsp +66 -0
- package/lib/core/routes/competitions.tsp +50 -0
- package/lib/core/routes/form-responses.tsp +52 -0
- package/lib/core/routes/forms.tsp +38 -0
- package/lib/core/routes/index.tsp +4 -0
- package/lib/core/routes/opportunities.tsp +14 -6
- package/lib/main.tsp +12 -0
- package/package.json +3 -2
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import "../responses/index.tsp";
|
|
2
|
+
|
|
3
|
+
// Define the top-level namespace for CommonGrants routes
|
|
4
|
+
namespace CommonGrants.Routes;
|
|
5
|
+
|
|
6
|
+
// Expose the contents of the Http and Rest namespaces
|
|
7
|
+
// these include the decorators @route, @get, etc.
|
|
8
|
+
using TypeSpec.Http;
|
|
9
|
+
|
|
10
|
+
/** A re-usable interface for an Applications router
|
|
11
|
+
*
|
|
12
|
+
* To implement this interface, we recommend declaring a namespace,
|
|
13
|
+
* instantiating the router using `alias` (instead of `extends`),
|
|
14
|
+
* and decorating the namespace with `@route` and `@tag` since they aren't
|
|
15
|
+
* inherited directly from the interface.
|
|
16
|
+
*/
|
|
17
|
+
interface Applications {
|
|
18
|
+
// ##############################
|
|
19
|
+
// Start an application
|
|
20
|
+
// ##############################
|
|
21
|
+
|
|
22
|
+
@summary("Start an application")
|
|
23
|
+
@doc("Start a new application for a given competition.")
|
|
24
|
+
@post
|
|
25
|
+
@route("/start")
|
|
26
|
+
startApplication(
|
|
27
|
+
/** The ID of the competition to start an application for */
|
|
28
|
+
competitionId: Types.uuid,
|
|
29
|
+
|
|
30
|
+
/** The ID of the organization to start an application for, if applying on behalf of an organization */
|
|
31
|
+
organizationId?: Types.uuid,
|
|
32
|
+
|
|
33
|
+
/** The name of the application */
|
|
34
|
+
name: string,
|
|
35
|
+
): Responses.Created<Models.ApplicationBase> | Responses.Unauthorized;
|
|
36
|
+
|
|
37
|
+
// ###############################
|
|
38
|
+
// Get an application
|
|
39
|
+
// ###############################
|
|
40
|
+
|
|
41
|
+
@summary("View an application")
|
|
42
|
+
@doc("View an application for a given competition, along with its form responses and validation errors.")
|
|
43
|
+
@get
|
|
44
|
+
@route("/{appId}")
|
|
45
|
+
getApplication(
|
|
46
|
+
/** The ID of the application to get */
|
|
47
|
+
@path appId: Types.uuid,
|
|
48
|
+
): Responses.Ok<Models.ApplicationBase> | Responses.NotFound | Responses.Unauthorized;
|
|
49
|
+
|
|
50
|
+
// ###############################
|
|
51
|
+
// Submit an application
|
|
52
|
+
// ###############################
|
|
53
|
+
|
|
54
|
+
@summary("Submit an application")
|
|
55
|
+
@doc("Submit an application to a competition. Applications that have validation errors will be blocked from submitting until the errors are fixed.")
|
|
56
|
+
@put
|
|
57
|
+
@route("/{appId}/submit")
|
|
58
|
+
submitApplication(
|
|
59
|
+
/** The ID of the application to submit */
|
|
60
|
+
@path appId: Types.uuid,
|
|
61
|
+
):
|
|
62
|
+
| Responses.Ok<unknown>
|
|
63
|
+
| Responses.ApplicationSubmissionError
|
|
64
|
+
| Responses.NotFound
|
|
65
|
+
| Responses.Unauthorized;
|
|
66
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import "../responses/index.tsp";
|
|
2
|
+
|
|
3
|
+
// Define the top-level namespace for CommonGrants routes
|
|
4
|
+
namespace CommonGrants.Routes;
|
|
5
|
+
|
|
6
|
+
// Expose the contents of the Http and Rest namespaces
|
|
7
|
+
// these include the decorators @route, @get, etc.
|
|
8
|
+
using TypeSpec.Http;
|
|
9
|
+
|
|
10
|
+
/** A re-usable interface for a Competitions router
|
|
11
|
+
*
|
|
12
|
+
* To implement this interface, we recommend declaring a namespace,
|
|
13
|
+
* instantiating the router using `alias` (instead of `extends`),
|
|
14
|
+
* and decorating the namespace with `@route` and `@tag` since they aren't
|
|
15
|
+
* inherited directly from the interface.
|
|
16
|
+
*/
|
|
17
|
+
interface Competitions {
|
|
18
|
+
// ###############################
|
|
19
|
+
// View competition details
|
|
20
|
+
// ###############################
|
|
21
|
+
|
|
22
|
+
/** View details about a competition for a given funding opportunity.
|
|
23
|
+
*
|
|
24
|
+
* Each competition may have a distinct set of forms, be limited to a
|
|
25
|
+
* certain types of applicants, or have a different application period.
|
|
26
|
+
*/
|
|
27
|
+
@summary("View competition details")
|
|
28
|
+
@get
|
|
29
|
+
@route("/{compId}")
|
|
30
|
+
read(
|
|
31
|
+
/** The ID of the competition to view */
|
|
32
|
+
@path compId: Types.uuid,
|
|
33
|
+
): Responses.Ok<Models.CompetitionBase> | Responses.NotFound;
|
|
34
|
+
|
|
35
|
+
// ###############################
|
|
36
|
+
// Apply to a competition
|
|
37
|
+
// ###############################
|
|
38
|
+
|
|
39
|
+
@summary("Apply to a competition")
|
|
40
|
+
@doc("Apply to a given competition with all of the required information.")
|
|
41
|
+
@post
|
|
42
|
+
@route("/{compId}/apply")
|
|
43
|
+
apply(
|
|
44
|
+
/** The ID of the competition to apply to */
|
|
45
|
+
@path compId: Types.uuid,
|
|
46
|
+
|
|
47
|
+
/** The application to apply to the competition */
|
|
48
|
+
@body application: Models.ApplicationBase,
|
|
49
|
+
): Responses.Created<Models.ApplicationBase> | Responses.NotFound | Responses.Unauthorized;
|
|
50
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import "../responses/index.tsp";
|
|
2
|
+
|
|
3
|
+
// Define the top-level namespace for CommonGrants routes
|
|
4
|
+
namespace CommonGrants.Routes;
|
|
5
|
+
|
|
6
|
+
// Expose the contents of the Http and Rest namespaces
|
|
7
|
+
// these include the decorators @route, @get, etc.
|
|
8
|
+
using TypeSpec.Http;
|
|
9
|
+
|
|
10
|
+
/** A re-usable interface for an Applications router
|
|
11
|
+
*
|
|
12
|
+
* To implement this interface, we recommend declaring a namespace,
|
|
13
|
+
* instantiating the router using `alias` (instead of `extends`),
|
|
14
|
+
* and decorating the namespace with `@route` and `@tag` since they aren't
|
|
15
|
+
* inherited directly from the interface.
|
|
16
|
+
*/
|
|
17
|
+
interface FormResponses {
|
|
18
|
+
// ###############################
|
|
19
|
+
// Update form response
|
|
20
|
+
// ###############################
|
|
21
|
+
|
|
22
|
+
@summary("Respond to a form")
|
|
23
|
+
@doc("Set or update the response to a given form in an application.")
|
|
24
|
+
@put
|
|
25
|
+
@route("/{appId}/forms/{formId}")
|
|
26
|
+
setFormResponse(
|
|
27
|
+
/** The ID of the application to whose form response is being updated */
|
|
28
|
+
@path appId: Types.uuid,
|
|
29
|
+
|
|
30
|
+
/** The ID of the form whose response is being updated */
|
|
31
|
+
@path formId: Types.uuid,
|
|
32
|
+
|
|
33
|
+
/** The response to the form */
|
|
34
|
+
@body response: Record<unknown>,
|
|
35
|
+
): Responses.Ok<Models.AppFormResponse>;
|
|
36
|
+
|
|
37
|
+
// ###############################
|
|
38
|
+
// Get form response
|
|
39
|
+
// ###############################
|
|
40
|
+
|
|
41
|
+
@summary("Get a form response")
|
|
42
|
+
@doc("Get the response to a given form in an application.")
|
|
43
|
+
@get
|
|
44
|
+
@route("/{appId}/forms/{formId}")
|
|
45
|
+
getFormResponse(
|
|
46
|
+
/** The ID of the application to whose form response is being retrieved */
|
|
47
|
+
@path appId: Types.uuid,
|
|
48
|
+
|
|
49
|
+
/** The ID of the form whose response is being retrieved */
|
|
50
|
+
@path formId: Types.uuid,
|
|
51
|
+
): Responses.Ok<Models.AppFormResponse>;
|
|
52
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import "../responses/index.tsp";
|
|
2
|
+
|
|
3
|
+
// Define the top-level namespace for CommonGrants routes
|
|
4
|
+
namespace CommonGrants.Routes;
|
|
5
|
+
|
|
6
|
+
// Expose the contents of the Http and Rest namespaces
|
|
7
|
+
// these include the decorators @route, @get, etc.
|
|
8
|
+
using TypeSpec.Http;
|
|
9
|
+
|
|
10
|
+
/** A re-usable interface for an Applications router
|
|
11
|
+
*
|
|
12
|
+
* To implement this interface, we recommend declaring a namespace,
|
|
13
|
+
* instantiating the router using `alias` (instead of `extends`),
|
|
14
|
+
* and decorating the namespace with `@route` and `@tag` since they aren't
|
|
15
|
+
* inherited directly from the interface.
|
|
16
|
+
*/
|
|
17
|
+
interface Forms {
|
|
18
|
+
// ###############################
|
|
19
|
+
// Update form response
|
|
20
|
+
// ###############################
|
|
21
|
+
|
|
22
|
+
@summary("List forms")
|
|
23
|
+
@doc("Get a paginated list of forms, sorted by `lastModifiedAt` with most recent first.")
|
|
24
|
+
@get
|
|
25
|
+
list(...Pagination.PaginatedQueryParams): Responses.Paginated<Models.Form>;
|
|
26
|
+
|
|
27
|
+
// ###############################
|
|
28
|
+
// View form details
|
|
29
|
+
// ###############################
|
|
30
|
+
|
|
31
|
+
@summary("View form details")
|
|
32
|
+
@doc("View details about a given form.")
|
|
33
|
+
@get
|
|
34
|
+
read(
|
|
35
|
+
/** The ID of the form to view */
|
|
36
|
+
@path formId: Types.uuid,
|
|
37
|
+
): Responses.Ok<Models.Form>;
|
|
38
|
+
}
|
|
@@ -3,6 +3,10 @@ import "@typespec/rest";
|
|
|
3
3
|
|
|
4
4
|
// Import individual route files to provide a consistent interface
|
|
5
5
|
import "./opportunities.tsp";
|
|
6
|
+
import "./applications.tsp";
|
|
7
|
+
import "./form-responses.tsp";
|
|
8
|
+
import "./forms.tsp";
|
|
9
|
+
import "./competitions.tsp";
|
|
6
10
|
|
|
7
11
|
/** A series of routing interfaces for CommonGrants API endpoints
|
|
8
12
|
*
|
|
@@ -8,6 +8,7 @@ namespace CommonGrants.Routes;
|
|
|
8
8
|
// Expose the contents of the Http and Rest namespaces
|
|
9
9
|
// these include the decorators @route, @get, etc.
|
|
10
10
|
using TypeSpec.Http;
|
|
11
|
+
using TypeSpec.Versioning;
|
|
11
12
|
|
|
12
13
|
/** A re-usable interface for an Opportunities router
|
|
13
14
|
*
|
|
@@ -52,7 +53,7 @@ interface Opportunities {
|
|
|
52
53
|
): Responses.Paginated<T>;
|
|
53
54
|
|
|
54
55
|
// ##############################
|
|
55
|
-
// View an opportunity
|
|
56
|
+
// View an opportunity (v0.1.0)
|
|
56
57
|
// ##############################
|
|
57
58
|
|
|
58
59
|
/** `GET /opportunities/<id>` View opportunity details
|
|
@@ -60,12 +61,19 @@ interface Opportunities {
|
|
|
60
61
|
* @template T Type of the response model.
|
|
61
62
|
* Must be an extension of Schemas.OpportunityBase. Default is Schemas.OpportunityBase.
|
|
62
63
|
*/
|
|
63
|
-
@summary("View opportunity")
|
|
64
|
-
@doc("View
|
|
64
|
+
@summary("View opportunity details")
|
|
65
|
+
@doc("View details about an opportunity.")
|
|
65
66
|
@get
|
|
66
|
-
read<T extends Models.OpportunityBase = Models.
|
|
67
|
+
read<T extends Models.OpportunityBase = Models.OpportunityDetails>(
|
|
67
68
|
/** The ID of the opportunity to view */
|
|
68
|
-
@path
|
|
69
|
+
@path
|
|
70
|
+
@removed(Versions.v0_2)
|
|
71
|
+
id: Types.uuid,
|
|
72
|
+
|
|
73
|
+
/** The ID of the opportunity to view */
|
|
74
|
+
@path
|
|
75
|
+
@added(Versions.v0_2)
|
|
76
|
+
oppId: Types.uuid,
|
|
69
77
|
): Responses.Ok<T> | Responses.NotFound;
|
|
70
78
|
|
|
71
79
|
// ###############################
|
|
@@ -78,7 +86,7 @@ interface Opportunities {
|
|
|
78
86
|
* Must be an extension of Schemas.OpportunityBase. Default is Schemas.OpportunityBase.
|
|
79
87
|
*/
|
|
80
88
|
@summary("Search opportunities")
|
|
81
|
-
@doc("Search for opportunities based on the provided filters")
|
|
89
|
+
@doc("Search for opportunities based on the provided filters.")
|
|
82
90
|
@post
|
|
83
91
|
@route("/search")
|
|
84
92
|
search<T extends Models.OpportunityBase = Models.OpportunityBase>(
|
package/lib/main.tsp
CHANGED
|
@@ -3,7 +3,19 @@
|
|
|
3
3
|
// https://typespec.io/docs/extending-typespec/basics/#h-add-your-main-typespec-file
|
|
4
4
|
import "../dist/src/index.js";
|
|
5
5
|
|
|
6
|
+
// Import the core typespec files
|
|
6
7
|
import "./core/index.tsp";
|
|
7
8
|
import "./api.tsp";
|
|
8
9
|
|
|
10
|
+
// Import the versioning package
|
|
11
|
+
import "@typespec/versioning";
|
|
12
|
+
|
|
13
|
+
using Versioning;
|
|
14
|
+
|
|
15
|
+
@versioned(Versions)
|
|
9
16
|
namespace CommonGrants;
|
|
17
|
+
|
|
18
|
+
enum Versions {
|
|
19
|
+
v0_1: "0.1.0",
|
|
20
|
+
v0_2: "0.2.0",
|
|
21
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@common-grants/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "TypeSpec library for defining grant opportunity data models and APIs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -55,7 +55,8 @@
|
|
|
55
55
|
"@typespec/http": "^1.1.0",
|
|
56
56
|
"@typespec/json-schema": "1.0.0",
|
|
57
57
|
"@typespec/openapi3": "1.0.0",
|
|
58
|
-
"@typespec/rest": "0.70.0"
|
|
58
|
+
"@typespec/rest": "0.70.0",
|
|
59
|
+
"@typespec/versioning": "^0.70.0"
|
|
59
60
|
},
|
|
60
61
|
"devDependencies": {
|
|
61
62
|
"@types/node": "^20.10.6",
|