@common-grants/core 0.1.0-alpha.7 → 0.1.0-alpha.8

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/lib/api.tsp ADDED
@@ -0,0 +1,29 @@
1
+ // Import Schemas.and Routes to make them available outside the package
2
+ import "./core/index.tsp";
3
+ import "@typespec/http";
4
+
5
+ using Core;
6
+
7
+ using TypeSpec.Http;
8
+
9
+ /** The base OpenAPI specification for a CommonGrants API
10
+ *
11
+ * In order for an API to be "compliant" with the CommonGrants protocol,
12
+ * it must implement all of the routes with the "required" tag in this specification.
13
+ */
14
+ @service({
15
+ title: "CommonGrants Base API",
16
+ })
17
+ namespace CommonGrants.API;
18
+
19
+ @tag("Opportunities")
20
+ @route("/opportunities")
21
+ namespace Opportunities {
22
+ alias Router = Routes.Opportunities;
23
+
24
+ @tag("required")
25
+ op List is Router.list;
26
+
27
+ @tag("required")
28
+ op Read is Router.read;
29
+ }
@@ -1,4 +1,4 @@
1
- namespace CommonGrants.Models;
1
+ namespace Core.Fields;
2
2
 
3
3
  // ########################################
4
4
  // Field types definition
@@ -14,7 +14,7 @@ enum CustomFieldType {
14
14
  }
15
15
 
16
16
  // ########################################
17
- // Models definition
17
+ // Model definition
18
18
  // ########################################
19
19
 
20
20
  /** Model for defining custom fields that are specific to a given implementation.
@@ -1,4 +1,8 @@
1
- namespace CommonGrants.Models;
1
+ import "../types.tsp";
2
+
3
+ namespace Core.Fields;
4
+
5
+ using Core.Types;
2
6
 
3
7
  // ########################################
4
8
  // Model definition
@@ -0,0 +1,6 @@
1
+ import "./custom-field.tsp";
2
+ import "./metadata.tsp";
3
+ import "./money.tsp";
4
+ import "./event.tsp";
5
+
6
+ namespace Internals.Schemas.Fields;
@@ -1,4 +1,4 @@
1
- namespace CommonGrants.Models;
1
+ namespace Core.Fields;
2
2
 
3
3
  // ########################################
4
4
  // Model definition
@@ -1,4 +1,8 @@
1
- namespace CommonGrants.Models;
1
+ import "../types.tsp";
2
+
3
+ namespace Core.Fields;
4
+
5
+ using Core.Types;
2
6
 
3
7
  // ########################################
4
8
  // Model definition
@@ -0,0 +1,8 @@
1
+ import "./types.tsp";
2
+ import "./fields/index.tsp";
3
+ import "./models/index.tsp";
4
+ import "./routes/index.tsp";
5
+ import "./responses/index.tsp";
6
+
7
+ /** An internal namespace for the `@common-grants/core` package */
8
+ namespace Core;
@@ -1,20 +1,14 @@
1
1
  import "@typespec/json-schema";
2
2
 
3
- // Import individual models to provide a consistent interface
3
+ // Import individual schemas to provide a consistent interface
4
4
  // and make them available throughout the namespace
5
- import "./base.tsp";
6
- import "./custom-field.tsp";
7
- import "./money.tsp";
8
- import "./event.tsp";
9
- import "./metadata.tsp";
10
- import "./custom-enum.tsp";
11
5
  import "./opportunity/index.tsp";
12
6
 
13
7
  using TypeSpec.JsonSchema;
14
8
 
15
- /** Namespace for CommonGrants models that can be used in API routes */
16
- @jsonSchema // and emit these models as JSON schemas
17
- namespace CommonGrants.Models;
9
+ /** Namespace for Core that can be used in API routes */
10
+ @jsonSchema // and emit these Schemas.as JSON schemas
11
+ namespace Core.Models;
18
12
 
19
13
  /** The base model for a funding opportunity.
20
14
  *
@@ -23,6 +17,9 @@ namespace CommonGrants.Models;
23
17
  * @example How to declare a new Opportunity model with custom fields
24
18
  *
25
19
  * ```typespec
20
+ * using Core.Fields;
21
+ * using Core.Models;
22
+ *
26
23
  * model Agency extends CustomField {
27
24
  * type: CustomFieldType.string;
28
25
  *
@@ -1,12 +1,14 @@
1
- import "@typespec/json-schema";
2
-
3
1
  import "./status.tsp";
4
2
  import "./funding.tsp";
5
3
  import "./timeline.tsp";
4
+ import "../../fields/index.tsp";
5
+ import "../../types.tsp";
6
+
7
+ /** Namespace for Core that are specific to funding opportunities */
8
+ namespace Core.Models.Opportunity;
6
9
 
7
- /** Namespace for CommonGrants models that are specific to funding opportunities */
8
- @JsonSchema.jsonSchema
9
- namespace CommonGrants.Models.Opportunity;
10
+ using Core.Fields;
11
+ using Core.Types;
10
12
 
11
13
  // ########################################
12
14
  // Model definition
@@ -1,6 +1,9 @@
1
1
  import "../index.tsp";
2
+ import "../../fields/index.tsp";
2
3
 
3
- namespace CommonGrants.Models.Opportunity;
4
+ namespace Core.Models.Opportunity;
5
+
6
+ using Core.Fields;
4
7
 
5
8
  // ########################################
6
9
  // Model definition
@@ -0,0 +1,6 @@
1
+ import "./status.tsp";
2
+ import "./funding.tsp";
3
+ import "./timeline.tsp";
4
+ import "./base.tsp";
5
+
6
+ namespace Core.Models.Opportunity;
@@ -0,0 +1,32 @@
1
+ import "@typespec/json-schema";
2
+ import "@typespec/openapi3";
3
+
4
+ namespace Core.Models.Opportunity;
5
+
6
+ // ########################################
7
+ // Opportunity status options
8
+ // ########################################
9
+
10
+ /** The set of values accepted for opportunity status */
11
+ enum OppStatusOptions {
12
+ forecasted,
13
+ open,
14
+ closed,
15
+ custom,
16
+ }
17
+
18
+ // ########################################
19
+ // Opportunity status model
20
+ // ########################################
21
+
22
+ /** The status of the opportunity */
23
+ model OppStatus {
24
+ /** The status value */
25
+ value: OppStatusOptions;
26
+
27
+ /** A custom status value */
28
+ customValue?: string;
29
+
30
+ /** A human-readable description of the status */
31
+ description?: string;
32
+ }
@@ -1,7 +1,10 @@
1
- import "../event.tsp";
2
- import "../custom-enum.tsp";
1
+ import "../../fields/index.tsp";
2
+ import "../../types.tsp";
3
3
 
4
- namespace CommonGrants.Models.Opportunity;
4
+ namespace Core.Models.Opportunity;
5
+
6
+ using Core.Fields;
7
+ using Core.Types;
5
8
 
6
9
  // ########################################
7
10
  // Model definition
@@ -1,4 +1,6 @@
1
- namespace Responses.Error;
1
+ import "@typespec/http";
2
+
3
+ namespace Core.Responses;
2
4
 
3
5
  /** A standard error response schema, used to create custom error responses
4
6
  *
@@ -1,6 +1,6 @@
1
1
  import "@typespec/http";
2
2
 
3
- import "./errors.tsp";
3
+ import "./error.tsp";
4
4
  import "./success.tsp";
5
5
 
6
- namespace Responses;
6
+ namespace Core.Responses;
@@ -1,4 +1,6 @@
1
- namespace Responses.Success;
1
+ import "@typespec/http";
2
+
3
+ namespace Core.Responses;
2
4
 
3
5
  model Success {
4
6
  @example(200)
@@ -0,0 +1,23 @@
1
+ import "@typespec/http";
2
+ import "@typespec/rest";
3
+
4
+ // Import individual route files to provide a consistent interface
5
+ import "./opportunities.tsp";
6
+
7
+ /** A series of interfaces for CommonGrants API routes
8
+ *
9
+ * @example How to use the `Routes` namespace
10
+ *
11
+ * ```tsp
12
+ * import "@common-grants/core";
13
+ *
14
+ * using CommonGrants;
15
+ *
16
+ * namespace MyRoutes {
17
+ * alias OpportunityRouter = Routes.Opportunities;
18
+ *
19
+ * op List is OpportunityRouter.list;
20
+ * }
21
+ * ```
22
+ */
23
+ namespace Core.Routes;
@@ -1,26 +1,14 @@
1
1
  import "../models/index.tsp";
2
2
  import "../responses/index.tsp";
3
+ import "./utils.tsp";
3
4
 
4
5
  // Define the top-level namespace for CommonGrants routes
5
- namespace CommonGrants.Routes;
6
+ namespace Core.Routes;
6
7
 
7
8
  // Expose the contents of the Http and Rest namespaces
8
9
  // these include the decorators @route, @get, etc.
9
10
  using TypeSpec.Http;
10
- using TypeSpec.Rest;
11
- using Responses;
12
-
13
- model PaginatedQuery {
14
- /** The page to return */
15
- @query
16
- @pageIndex
17
- page?: int32 = 1;
18
-
19
- /** The number of items to return per page */
20
- @query
21
- @pageSize
22
- perPage?: int32 = 100;
23
- }
11
+ using Core;
24
12
 
25
13
  /** A re-usable interface for an Opportunities router
26
14
  *
@@ -37,14 +25,13 @@ model PaginatedQuery {
37
25
  * ```typespec
38
26
  * using TypeSpec.Http;
39
27
  *
40
- * @tag("Search")
28
+ * @tag("Opportunities")
41
29
  * @route("/opportunities/")
42
30
  * namespace Opportunities {
43
- * alias Router = Routes.Opportunities
44
- *
45
- * op list is Router.list;
46
- * op read is Router.read<CustomOpportunity>;
31
+ * alias Router = Routes.Opportunities
47
32
  *
33
+ * op list is Router.list;
34
+ * op read is Router.read<CustomOpportunity>;
48
35
  * }
49
36
  * ```
50
37
  */
@@ -52,24 +39,25 @@ interface Opportunities {
52
39
  /** `GET /opportunities/` Get a paginated list of opportunities
53
40
  *
54
41
  * @template T Type of the paginated response model.
55
- * Must be an extension of Models.OpportunityBase. Default is Models.OpportunityBase.
42
+ * Must be an extension of Schemas.OpportunityBase. Default is Schemas.OpportunityBase.
56
43
  */
57
44
  @summary("List opportunities")
58
45
  @doc("Get a paginated list of opportunities, sorted by `lastModifiedAt` with most recent first.")
59
46
  @list
60
47
  list<T extends Models.OpportunityBase = Models.OpportunityBase>(
61
- ...PaginatedQuery,
62
- ): Success.Paginated<T> | Error.Unauthorized;
48
+ ...Utils.PaginatedQuery,
49
+ ): Responses.Paginated<T> | Responses.Unauthorized;
63
50
 
64
51
  /** `GET /opportunities/<id>` View opportunity details
65
52
  *
66
53
  * @template T Type of the response model.
67
- * Must be an extension of Models.OpportunityBase. Default is Models.OpportunityBase.
54
+ * Must be an extension of Schemas.OpportunityBase. Default is Schemas.OpportunityBase.
68
55
  */
69
56
  @summary("View opportunity")
70
57
  @doc("View additional details about an opportunity")
71
58
  @get
72
59
  read<T extends Models.OpportunityBase = Models.OpportunityBase>(
73
- @path id: Models.uuid,
74
- ): Success.Ok<T> | Error.NotFound | Error.Unauthorized;
60
+ /** The ID of the opportunity to view */
61
+ @path id: Types.uuid,
62
+ ): Responses.Ok<T> | Responses.NotFound | Responses.Unauthorized;
75
63
  }
@@ -0,0 +1,19 @@
1
+ import "@typespec/http";
2
+
3
+ using TypeSpec.Http;
4
+
5
+ /** Utility models and functions for API routes */
6
+ namespace Core.Routes.Utils;
7
+
8
+ /** A set of query parameters for paginated routes */
9
+ model PaginatedQuery {
10
+ /** The page to return */
11
+ @query
12
+ @pageIndex
13
+ page?: int32 = 1;
14
+
15
+ /** The number of items to return per page */
16
+ @query
17
+ @pageSize
18
+ pageSize?: int32 = 100;
19
+ }
@@ -1,4 +1,4 @@
1
- namespace CommonGrants.Models;
1
+ namespace Core.Types;
2
2
 
3
3
  /** A time on a clock, without a timezone, in ISO 8601 format HH:mm:ss */
4
4
  @example(isoTime.fromISO("17:00:00"))
package/lib/main.tsp CHANGED
@@ -3,27 +3,92 @@
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 Models and Routes to make them available outside the package
7
- import "./models/index.tsp";
8
- import "./routes/index.tsp";
6
+ // Import items from the Core namespace to make them available outside the package
7
+ import "./core/index.tsp";
8
+ import "./api.tsp";
9
9
 
10
- using TypeSpec.Http;
10
+ namespace CommonGrants;
11
11
 
12
- /** The base OpenAPI specification for a CommonGrants API
12
+ /** Base data types, e.g. `uuid` and `isoDate`, used to build more complex fields and models
13
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.
14
+ * @example How to use the `Types` namespace
15
+ *
16
+ * ```tsp
17
+ * import "@common-grants/core";
18
+ *
19
+ * using CommonGrants; // exposes the Types namespace
20
+ *
21
+ * model MyModel {
22
+ * id: Types.uuid;
23
+ * createdAt: Types.isoDate;
24
+ * }
25
+ * ```
26
+ */
27
+ alias Types = Core.Types;
28
+
29
+ /** A standard set of fields, e.g. `money` that can be reused across models
30
+ *
31
+ * @example How to use the `Fields` namespace
32
+ *
33
+ * ```tsp
34
+ * import "@common-grants/core";
35
+ *
36
+ * using CommonGrants; // exposes the Fields namespace
37
+ *
38
+ * model MyModel {
39
+ * amount: Fields.money;
40
+ * }
41
+ * ```
42
+ */
43
+ alias Fields = Core.Fields;
44
+
45
+ /** A standardized set of response schemas for CommonGrants API routes
46
+ *
47
+ * @example How to use the `Responses` namespace
48
+ *
49
+ * ```tsp
50
+ * import "@typespec/http";
51
+ * import "@common-grants/core";
52
+ *
53
+ * using CommonGrants; // exposes the Responses namespace
54
+ * using TypeSpec.Http;
55
+ *
56
+ * @route("/pets")
57
+ * namespace Pets {
58
+ * @get
59
+ * getPets(): Responses.Ok<Pet> | Responses.Unauthorized;
60
+ * }
61
+ * ```
16
62
  */
17
- @service({
18
- title: "Base API",
19
- })
20
- namespace CommonGrants.API;
63
+ alias Responses = Core.Responses;
21
64
 
22
- @tag("Opportunities")
23
- @route("/opportunities")
24
- namespace Opportunities {
25
- alias Router = Routes.Opportunities;
65
+ /** A collection of models for the CommonGrants API
66
+ *
67
+ * @example How to use the `Models` namespace
68
+ *
69
+ * ```tsp
70
+ * import "@common-grants/core";
71
+ *
72
+ * using CommonGrants; // exposes the Models namespace
73
+ *
74
+ * model MyModel extends Models.OpportunityBase {}
75
+ * ```
76
+ */
77
+ alias Models = Core.Models;
26
78
 
27
- op List is Router.list;
28
- op Read is Router.read;
29
- }
79
+ /** A series of routing interfaces for CommonGrants API endpoints
80
+ *
81
+ * @example How to use the `Routes` namespace
82
+ *
83
+ * ```tsp
84
+ * import "@common-grants/core";
85
+ *
86
+ * using CommonGrants; // exposes the Routes namespace
87
+ *
88
+ * namespace MyRoutes {
89
+ * alias OpportunityRouter = Routes.Opportunities;
90
+ *
91
+ * op List is OpportunityRouter.list;
92
+ * }
93
+ */
94
+ alias Routes = Core.Routes;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@common-grants/core",
3
- "version": "0.1.0-alpha.7",
3
+ "version": "0.1.0-alpha.8",
4
4
  "description": "TypeSpec library for defining grant opportunity data models and APIs",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -1,27 +0,0 @@
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,33 +0,0 @@
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
- }
@@ -1,8 +0,0 @@
1
- import "@typespec/http";
2
- import "@typespec/rest";
3
-
4
- // Import individual route files to provide a consistent interface
5
- import "./opportunities.tsp";
6
-
7
- // Define the
8
- namespace CommonGrants.Routes;