@common-grants/core 0.1.0-alpha.10
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 +132 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +3 -0
- package/dist/src/lib.d.ts +13 -0
- package/dist/src/lib.js +10 -0
- package/lib/api.tsp +32 -0
- package/lib/core/fields/custom-field.tsp +85 -0
- package/lib/core/fields/event.tsp +47 -0
- package/lib/core/fields/index.tsp +20 -0
- package/lib/core/fields/metadata.tsp +42 -0
- package/lib/core/fields/money.tsp +43 -0
- package/lib/core/filters/base.tsp +82 -0
- package/lib/core/filters/date.tsp +38 -0
- package/lib/core/filters/index.tsp +37 -0
- package/lib/core/filters/money.tsp +38 -0
- package/lib/core/filters/numeric.tsp +50 -0
- package/lib/core/filters/string.tsp +31 -0
- package/lib/core/index.tsp +8 -0
- package/lib/core/models/index.tsp +22 -0
- package/lib/core/models/opportunity/base.tsp +72 -0
- package/lib/core/models/opportunity/funding.tsp +71 -0
- package/lib/core/models/opportunity/index.tsp +7 -0
- package/lib/core/models/opportunity/search.tsp +102 -0
- package/lib/core/models/opportunity/status.tsp +52 -0
- package/lib/core/models/opportunity/timeline.tsp +46 -0
- package/lib/core/pagination.tsp +55 -0
- package/lib/core/responses/error.tsp +30 -0
- package/lib/core/responses/index.tsp +24 -0
- package/lib/core/responses/success.tsp +141 -0
- package/lib/core/routes/index.tsp +22 -0
- package/lib/core/routes/opportunities.tsp +98 -0
- package/lib/core/sorting.tsp +71 -0
- package/lib/core/types.tsp +42 -0
- package/lib/main.tsp +9 -0
- package/package.json +73 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import "../models/index.tsp";
|
|
2
|
+
import "../responses/index.tsp";
|
|
3
|
+
import "../pagination.tsp";
|
|
4
|
+
|
|
5
|
+
// Define the top-level namespace for CommonGrants routes
|
|
6
|
+
namespace CommonGrants.Routes;
|
|
7
|
+
|
|
8
|
+
// Expose the contents of the Http and Rest namespaces
|
|
9
|
+
// these include the decorators @route, @get, etc.
|
|
10
|
+
using TypeSpec.Http;
|
|
11
|
+
|
|
12
|
+
/** A re-usable interface for an Opportunities router
|
|
13
|
+
*
|
|
14
|
+
* To implement this interface, we recommend declaring a namespace,
|
|
15
|
+
* instantiating the router using `alias` (instead of `extends`),
|
|
16
|
+
* and decorating the namespace with `@route` and `@tag` since they aren't
|
|
17
|
+
* inherited directly from the interface.
|
|
18
|
+
*
|
|
19
|
+
* For more information, see
|
|
20
|
+
* [TypeSpec docs](https://typespec.io/docs/language-basics/interfaces/#templating-interface-operations)
|
|
21
|
+
*
|
|
22
|
+
* @example Using the the default type for the list operation and
|
|
23
|
+
* a custom model for the read operation:
|
|
24
|
+
* ```typespec
|
|
25
|
+
* using TypeSpec.Http;
|
|
26
|
+
*
|
|
27
|
+
* @tag("Opportunities")
|
|
28
|
+
* @route("/opportunities/")
|
|
29
|
+
* namespace Opportunities {
|
|
30
|
+
* alias Router = Routes.Opportunities
|
|
31
|
+
*
|
|
32
|
+
* op list is Router.list;
|
|
33
|
+
* op read is Router.read<CustomOpportunity>;
|
|
34
|
+
* }
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
interface Opportunities {
|
|
38
|
+
// ###############################
|
|
39
|
+
// List opportunities
|
|
40
|
+
// ###############################
|
|
41
|
+
|
|
42
|
+
/** `GET /opportunities/` Get a paginated list of opportunities
|
|
43
|
+
*
|
|
44
|
+
* @template T Type of the paginated response model.
|
|
45
|
+
* Must be an extension of Schemas.OpportunityBase. Default is Schemas.OpportunityBase.
|
|
46
|
+
*/
|
|
47
|
+
@summary("List opportunities")
|
|
48
|
+
@doc("Get a paginated list of opportunities, sorted by `lastModifiedAt` with most recent first.")
|
|
49
|
+
@list
|
|
50
|
+
list<T extends Models.OpportunityBase = Models.OpportunityBase>(
|
|
51
|
+
...Pagination.PaginatedQueryParams,
|
|
52
|
+
): Responses.Paginated<T> | Responses.Unauthorized;
|
|
53
|
+
|
|
54
|
+
// ##############################
|
|
55
|
+
// View an opportunity
|
|
56
|
+
// ##############################
|
|
57
|
+
|
|
58
|
+
/** `GET /opportunities/<id>` View opportunity details
|
|
59
|
+
*
|
|
60
|
+
* @template T Type of the response model.
|
|
61
|
+
* Must be an extension of Schemas.OpportunityBase. Default is Schemas.OpportunityBase.
|
|
62
|
+
*/
|
|
63
|
+
@summary("View opportunity")
|
|
64
|
+
@doc("View additional details about an opportunity")
|
|
65
|
+
@get
|
|
66
|
+
read<T extends Models.OpportunityBase = Models.OpportunityBase>(
|
|
67
|
+
/** The ID of the opportunity to view */
|
|
68
|
+
@path id: Types.uuid,
|
|
69
|
+
): Responses.Ok<T> | Responses.NotFound | Responses.Unauthorized;
|
|
70
|
+
|
|
71
|
+
// ###############################
|
|
72
|
+
// Search opportunities
|
|
73
|
+
// ###############################
|
|
74
|
+
|
|
75
|
+
/** `POST /opportunities/search` Search opportunities
|
|
76
|
+
*
|
|
77
|
+
* @template T Type of the response model.
|
|
78
|
+
* Must be an extension of Schemas.OpportunityBase. Default is Schemas.OpportunityBase.
|
|
79
|
+
*/
|
|
80
|
+
@summary("Search opportunities")
|
|
81
|
+
@doc("Search for opportunities based on the provided filters")
|
|
82
|
+
@post
|
|
83
|
+
@route("/search")
|
|
84
|
+
search<T extends Models.OpportunityBase = Models.OpportunityBase>(
|
|
85
|
+
/** Filters to apply to the opportunity search
|
|
86
|
+
*
|
|
87
|
+
* Multiple filter conditions will be combined with AND logic, so that
|
|
88
|
+
* results only include opportunities that match all of the provided filters.
|
|
89
|
+
*/
|
|
90
|
+
filters?: Models.OppFilters,
|
|
91
|
+
|
|
92
|
+
/** The sort order to apply to the results */
|
|
93
|
+
sorting?: Models.OppSorting,
|
|
94
|
+
|
|
95
|
+
/** Pagination instructions for the results */
|
|
96
|
+
pagination?: Pagination.PaginatedBodyParams,
|
|
97
|
+
): Responses.Filtered<T, Models.OppFilters> | Responses.Unauthorized;
|
|
98
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import "@typespec/http";
|
|
2
|
+
|
|
3
|
+
using TypeSpec.Http;
|
|
4
|
+
|
|
5
|
+
/** Models for sorting
|
|
6
|
+
*
|
|
7
|
+
* @example How to use the `Sorting` namespace
|
|
8
|
+
* ```typespec
|
|
9
|
+
*
|
|
10
|
+
* using CommonGrants // Exposes the `Sorting` and `Responses` namespaces
|
|
11
|
+
* using TypeSpec.Http;
|
|
12
|
+
*
|
|
13
|
+
* @route("/foo/")
|
|
14
|
+
* @get
|
|
15
|
+
* op list(sorting: Sorting.SortQueryParams): Responses.Sorted<MyModel>;
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
namespace CommonGrants.Sorting;
|
|
19
|
+
|
|
20
|
+
enum SortOrder {
|
|
21
|
+
asc,
|
|
22
|
+
desc,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Query parameters for sorting */
|
|
26
|
+
model SortQueryParams {
|
|
27
|
+
/** The field to sort by */
|
|
28
|
+
@query
|
|
29
|
+
@example("lastModifiedAt")
|
|
30
|
+
sortBy: string;
|
|
31
|
+
|
|
32
|
+
/** Implementation-defined sort key */
|
|
33
|
+
@query
|
|
34
|
+
@example("customField")
|
|
35
|
+
customSortBy?: string;
|
|
36
|
+
|
|
37
|
+
/** The order to sort by */
|
|
38
|
+
@query
|
|
39
|
+
@example(SortOrder.asc)
|
|
40
|
+
sortOrder?: SortOrder;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Sorting parameters included in the request body */
|
|
44
|
+
model SortBodyParams {
|
|
45
|
+
/** The field to sort by */
|
|
46
|
+
@example("lastModifiedAt")
|
|
47
|
+
sortBy: unknown;
|
|
48
|
+
|
|
49
|
+
/** Implementation-defined sort key */
|
|
50
|
+
@example("customField")
|
|
51
|
+
customSortBy?: string;
|
|
52
|
+
|
|
53
|
+
/** The order to sort by */
|
|
54
|
+
@example(SortOrder.asc)
|
|
55
|
+
sortOrder?: SortOrder;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Information about the sort order of the items returned */
|
|
59
|
+
model SortInfo {
|
|
60
|
+
/** The field to sort by */
|
|
61
|
+
@example("lastModifiedAt")
|
|
62
|
+
sortBy: string;
|
|
63
|
+
|
|
64
|
+
/** Implementation-defined sort key */
|
|
65
|
+
@example("customField")
|
|
66
|
+
customSortBy?: string;
|
|
67
|
+
|
|
68
|
+
/** The order to sort by */
|
|
69
|
+
@example(SortOrder.asc)
|
|
70
|
+
sortOrder?: SortOrder;
|
|
71
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** A collection of base data types used throughout the CommonGrants API
|
|
2
|
+
*
|
|
3
|
+
* @example How to use the `Types` namespace
|
|
4
|
+
*
|
|
5
|
+
* ```typespec
|
|
6
|
+
* import "@common-grants/core";
|
|
7
|
+
*
|
|
8
|
+
* using CommonGrants; // exposes the Types namespace
|
|
9
|
+
*
|
|
10
|
+
* model MyModel {
|
|
11
|
+
* @example("30a12e5e-5940-4c08-921c-17a8960fcf4b")
|
|
12
|
+
* id: Types.uuid;
|
|
13
|
+
*
|
|
14
|
+
* @example(Types.isoDate.fromISO("2025-01-01"))
|
|
15
|
+
* keyDate: Types.isoDate;
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
namespace CommonGrants.Types;
|
|
20
|
+
|
|
21
|
+
/** A time on a clock, without a timezone, in ISO 8601 format HH:mm:ss */
|
|
22
|
+
@example(isoTime.fromISO("17:00:00"))
|
|
23
|
+
scalar isoTime extends plainTime;
|
|
24
|
+
|
|
25
|
+
/** A date on a calendar in ISO 8601 format YYYY-MM-DD */
|
|
26
|
+
@example(isoDate.fromISO("2025-01-01"))
|
|
27
|
+
scalar isoDate extends plainDate;
|
|
28
|
+
|
|
29
|
+
/** A universally unique identifier */
|
|
30
|
+
@example("30a12e5e-5940-4c08-921c-17a8960fcf4b")
|
|
31
|
+
@format("uuid")
|
|
32
|
+
scalar uuid extends string;
|
|
33
|
+
|
|
34
|
+
/** A decimal number (with variable scale) encoded as a string, to avoid floating point issues */
|
|
35
|
+
@pattern(
|
|
36
|
+
"^-?[0-9]+\\.?[0-9]*$",
|
|
37
|
+
"Must be a valid decimal number represented as a string"
|
|
38
|
+
)
|
|
39
|
+
@example("100", #{ title: "Scale 0" })
|
|
40
|
+
@example("100.5", #{ title: "Scale 1" })
|
|
41
|
+
@example("-100.5", #{ title: "Negative, scale 2" })
|
|
42
|
+
scalar decimalString extends string;
|
package/lib/main.tsp
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Import the JS entry point for this library
|
|
2
|
+
// For more details see:
|
|
3
|
+
// https://typespec.io/docs/extending-typespec/basics/#h-add-your-main-typespec-file
|
|
4
|
+
import "../dist/src/index.js";
|
|
5
|
+
|
|
6
|
+
import "./core/index.tsp";
|
|
7
|
+
import "./api.tsp";
|
|
8
|
+
|
|
9
|
+
namespace CommonGrants;
|
package/package.json
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@common-grants/core",
|
|
3
|
+
"version": "0.1.0-alpha.10",
|
|
4
|
+
"description": "TypeSpec library for defining grant opportunity data models and APIs",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/src/index.js",
|
|
7
|
+
"types": "dist/src/index.d.ts",
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"typespec": "./lib/main.tsp",
|
|
14
|
+
"default": "./dist/src/index.js",
|
|
15
|
+
"types": "./dist/src/index.d.ts"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist/src/**/*.js",
|
|
20
|
+
"dist/src/**/*.d.ts",
|
|
21
|
+
"lib/**/*.tsp",
|
|
22
|
+
"!src/**/*.test.*"
|
|
23
|
+
],
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "git+https://github.com/HHS/simpler-grants-protocol.git",
|
|
27
|
+
"directory": "specs"
|
|
28
|
+
},
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/HHS/simpler-grants-protocol/issues"
|
|
31
|
+
},
|
|
32
|
+
"homepage": "https://github.com/HHS/simpler-grants-protocol/tree/main/specs#readme",
|
|
33
|
+
"scripts": {
|
|
34
|
+
"prepublishOnly": "bash scripts/prepublish-checks.sh",
|
|
35
|
+
"clean": "rimraf dist tsp-output",
|
|
36
|
+
"build": "tsc -p .",
|
|
37
|
+
"watch": "tsc -p . --watch",
|
|
38
|
+
"typespec": "tsp compile lib/main.tsp",
|
|
39
|
+
"prepare": "npm run build",
|
|
40
|
+
"lint": "eslint . --fix",
|
|
41
|
+
"format": "prettier --write . && tsp format lib",
|
|
42
|
+
"check:lint": "eslint",
|
|
43
|
+
"check:format": "prettier --check . && tsp format lib --check",
|
|
44
|
+
"checks": "npm run check:lint && npm run check:format",
|
|
45
|
+
"docs:build": "npx @redocly/cli build-docs tsp-output/@typespec/openapi3/openapi.yaml --output ./dist/redocly.html",
|
|
46
|
+
"docs:preview": "open ./dist/redocly.html",
|
|
47
|
+
"docs": "npm run typespec && npm run docs:build && npm run docs:preview"
|
|
48
|
+
},
|
|
49
|
+
"keywords": [
|
|
50
|
+
"typespec",
|
|
51
|
+
"api",
|
|
52
|
+
"grants",
|
|
53
|
+
"opportunities"
|
|
54
|
+
],
|
|
55
|
+
"author": "CommonGrants",
|
|
56
|
+
"license": "CC0-1.0",
|
|
57
|
+
"peerDependencies": {
|
|
58
|
+
"@typespec/compiler": "^0.63.0",
|
|
59
|
+
"@typespec/http": "^0.63.0",
|
|
60
|
+
"@typespec/json-schema": "^0.63.0",
|
|
61
|
+
"@typespec/openapi3": "^0.63.0",
|
|
62
|
+
"@typespec/rest": "^0.63.0"
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"@types/node": "^20.10.6",
|
|
66
|
+
"eslint": "^9.18.0",
|
|
67
|
+
"prettier": "^3.4.2",
|
|
68
|
+
"rimraf": "^5.0.5",
|
|
69
|
+
"source-map-support": "^0.5.21",
|
|
70
|
+
"typescript": "^5.3.3",
|
|
71
|
+
"typescript-eslint": "^8.20.0"
|
|
72
|
+
}
|
|
73
|
+
}
|