@api-client/core 0.14.1 → 0.14.3

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.
Files changed (96) hide show
  1. package/build/src/browser.d.ts +1 -1
  2. package/build/src/browser.d.ts.map +1 -1
  3. package/build/src/browser.js.map +1 -1
  4. package/build/src/index.d.ts +2 -1
  5. package/build/src/index.d.ts.map +1 -1
  6. package/build/src/index.js +1 -0
  7. package/build/src/index.js.map +1 -1
  8. package/build/src/modeling/ApiFile.d.ts +23 -0
  9. package/build/src/modeling/ApiFile.d.ts.map +1 -0
  10. package/build/src/modeling/ApiFile.js +44 -0
  11. package/build/src/modeling/ApiFile.js.map +1 -0
  12. package/build/src/modeling/ApiModel.d.ts +159 -0
  13. package/build/src/modeling/ApiModel.d.ts.map +1 -0
  14. package/build/src/modeling/ApiModel.js +237 -0
  15. package/build/src/modeling/ApiModel.js.map +1 -0
  16. package/build/src/modeling/DataDomain.d.ts +1 -1
  17. package/build/src/modeling/DataDomain.d.ts.map +1 -1
  18. package/build/src/modeling/DataDomain.js +1 -3
  19. package/build/src/modeling/DataDomain.js.map +1 -1
  20. package/build/src/modeling/DomainAssociation.d.ts +35 -0
  21. package/build/src/modeling/DomainAssociation.d.ts.map +1 -1
  22. package/build/src/modeling/DomainAssociation.js +42 -5
  23. package/build/src/modeling/DomainAssociation.js.map +1 -1
  24. package/build/src/modeling/DomainEntity.js +1 -1
  25. package/build/src/modeling/DomainEntity.js.map +1 -1
  26. package/build/src/modeling/DomainFile.d.ts +1 -2
  27. package/build/src/modeling/DomainFile.d.ts.map +1 -1
  28. package/build/src/modeling/DomainFile.js +3 -41
  29. package/build/src/modeling/DomainFile.js.map +1 -1
  30. package/build/src/modeling/Semantics.d.ts +62 -7
  31. package/build/src/modeling/Semantics.d.ts.map +1 -1
  32. package/build/src/modeling/Semantics.js +76 -7
  33. package/build/src/modeling/Semantics.js.map +1 -1
  34. package/build/src/modeling/amf/ShapeGenerator.d.ts.map +1 -1
  35. package/build/src/modeling/amf/ShapeGenerator.js.map +1 -1
  36. package/build/src/modeling/types.d.ts +491 -0
  37. package/build/src/modeling/types.d.ts.map +1 -1
  38. package/build/src/modeling/types.js.map +1 -1
  39. package/build/src/models/kinds.d.ts +2 -0
  40. package/build/src/models/kinds.d.ts.map +1 -1
  41. package/build/src/models/kinds.js +2 -0
  42. package/build/src/models/kinds.js.map +1 -1
  43. package/build/src/models/store/File.d.ts +19 -2
  44. package/build/src/models/store/File.d.ts.map +1 -1
  45. package/build/src/models/store/File.js +100 -13
  46. package/build/src/models/store/File.js.map +1 -1
  47. package/build/tsconfig.tsbuildinfo +1 -1
  48. package/data/models/APIC-187.json +3 -3
  49. package/data/models/APIC-188.json +3 -3
  50. package/data/models/APIC-233.json +1 -1
  51. package/data/models/APIC-391.json +2 -2
  52. package/data/models/APIC-483.json +1 -1
  53. package/data/models/APIC-487.json +1 -1
  54. package/data/models/APIC-655.json +1 -1
  55. package/data/models/APIC-689.json +1 -1
  56. package/data/models/APIC-690.json +5 -5
  57. package/data/models/SE-10469.json +1 -1
  58. package/data/models/SE-13092.json +5 -5
  59. package/data/models/SE-22063.json +12 -2
  60. package/data/models/amf-helper-api.json +154 -14
  61. package/data/models/arc-demo-api.json +95 -15
  62. package/data/models/async-api.json +1 -1
  63. package/data/models/example-generator-api.json +361 -21
  64. package/data/models/expanded-api.json +1 -1
  65. package/data/models/flattened-api.json +1 -1
  66. package/data/models/multiple-servers.json +1 -1
  67. package/data/models/oas-3-api.json +1 -1
  68. package/data/models/oas-date.json +1 -1
  69. package/data/models/oas-types.json +1 -1
  70. package/data/models/oas-unions.json +1 -1
  71. package/data/models/petstore.json +1 -1
  72. package/data/models/raml-date.json +1 -1
  73. package/data/models/recursive.json +1 -1
  74. package/data/models/schema-api.json +62 -2
  75. package/data/models/secured-api.json +16 -16
  76. package/data/models/tracked-to-linked.json +4 -4
  77. package/package.json +3 -4
  78. package/src/modeling/ApiFile.ts +53 -0
  79. package/src/modeling/ApiModel.ts +327 -0
  80. package/src/modeling/DataDomain.ts +1 -1
  81. package/src/modeling/DomainAssociation.ts +56 -0
  82. package/src/modeling/DomainEntity.ts +1 -1
  83. package/src/modeling/DomainFile.ts +3 -40
  84. package/src/modeling/Semantics.ts +79 -7
  85. package/src/modeling/amf/ShapeGenerator.ts +1 -1
  86. package/src/modeling/types.ts +545 -0
  87. package/src/models/kinds.ts +2 -0
  88. package/src/models/store/File.ts +100 -13
  89. package/tests/unit/modeling/api_model.spec.ts +291 -0
  90. package/tests/unit/modeling/domain_asociation.spec.ts +92 -2
  91. package/tests/unit/modeling/domain_entity.spec.ts +15 -15
  92. package/tests/unit/modeling/domain_file.spec.ts +1 -11
  93. package/tests/unit/modeling/domain_model_entities.spec.ts +2 -2
  94. package/tests/unit/modeling/semantics.spec.ts +146 -0
  95. package/tests/unit/models/File/constructor.spec.ts +3 -2
  96. package/tests/unit/models/File/shortcutTo.spec.ts +1 -1
@@ -185,3 +185,548 @@ export type DataDomainGraph = Graph<unknown, DomainGraphNodeType, DomainGraphEdg
185
185
  * The serialized version of the data domain graph.
186
186
  */
187
187
  export type SerializedGraph = GraphJson<unknown, object, DomainGraphEdge>
188
+
189
+ /**
190
+ * Represents a standardized, machine-readable error response body
191
+ * as defined by RFC 7807 for HTTP APIs.
192
+ */
193
+ export interface ProblemDetails {
194
+ /**
195
+ * A URI that identifies the specific problem type. Should resolve to human-readable docs.
196
+ * e.g., "https://docs.apinow.app/errors/validation-failed"
197
+ */
198
+ type: string
199
+
200
+ /**
201
+ * A short, human-readable summary of the problem type.
202
+ * e.g., "Validation Error"
203
+ */
204
+ title: string
205
+
206
+ /**
207
+ * The HTTP status code generated by the origin server for this problem.
208
+ */
209
+ status?: number
210
+
211
+ /**
212
+ * A human-readable explanation specific to this occurrence of the problem.
213
+ */
214
+ detail?: string
215
+
216
+ /**
217
+ * A URI that identifies the specific occurrence of the problem.
218
+ * Can be the API request path that caused the error.
219
+ */
220
+ instance: string
221
+ }
222
+
223
+ /**
224
+ * The set of supported filter operators for the List action.
225
+ * These are used in query parameters, e.g., ?price[gte]=100
226
+ *
227
+ * - eq: Equal
228
+ * - nq: Not Equal
229
+ * - lt: Less Than
230
+ * - lte: Less Than or Equal
231
+ * - gt: Greater Than
232
+ * - gte: Greater Than or Equal
233
+ * - ex: Checks if the field exists
234
+ * - re: Regular expression match
235
+ * - bf: Date before a specific value
236
+ * - af: Date after a specific value
237
+ * - cn: String contains substring / Array contains element
238
+ * - st: String starts with
239
+ * - end: String ends with
240
+ * - in: Value is one of the elements in the provided array
241
+ * - nin: Value is not one of the elements in the provided array
242
+ */
243
+ export type ResourceFilterOperator =
244
+ | 'eq' // Equal
245
+ | 'nq' // Not equal
246
+ | 'lt' // Less than
247
+ | 'lte' // Less than or equal
248
+ | 'gt' // Greater than
249
+ | 'gte' // Greater than or equal
250
+ | 'ex' // Checks if the field exists
251
+ | 're' // Regular expression match
252
+ | 'bf' // Date before a specific value
253
+ | 'af' // Date after a specific value
254
+ | 'cn' // String contains substring / Array contains element
255
+ | 'st' // String starts with
256
+ | 'end' // String ends with
257
+ | 'in' // Value is one of the elements in the provided array
258
+ | 'nin' // Value is not one of the elements in the provided array
259
+
260
+ /**
261
+ * The session transport configuration interface.
262
+ * This defines the properties that are common to all session transports.
263
+ */
264
+ interface SessionTransport {
265
+ /**
266
+ * Whether the session transport is enabled.
267
+ */
268
+ enabled: boolean
269
+ /**
270
+ * The kind of session transport. Each interface defines its own kind.
271
+ */
272
+ kind: string
273
+ }
274
+
275
+ /**
276
+ * Configuration for cookie-based session transport.
277
+ */
278
+ export interface CookieConfiguration extends SessionTransport {
279
+ kind: 'cookie'
280
+ /**
281
+ * The lifetime of the cookie session.
282
+ * This is a string representing the duration, e.g., "7d" for 7 days or "24h" for 24 hours.
283
+ *
284
+ * @default "7d"
285
+ */
286
+ lifetime: string
287
+ /**
288
+ * Whether the cookie can only be accessed by the server.
289
+ * This is a security feature to prevent client-side scripts from accessing the cookie.
290
+ * If set to false, the cookie can be accessed by client-side scripts.
291
+ * @default true
292
+ */
293
+ httpOnly: boolean // Defaults to true
294
+ /**
295
+ * Whether the cookie should only be sent over secure connections (HTTPS).
296
+ * This is a security feature to prevent the cookie from being sent over unencrypted connections.
297
+ * @default true
298
+ */
299
+ secure: boolean
300
+ /**
301
+ * The SameSite attribute of the cookie.
302
+ * This attribute controls whether the cookie is sent with cross-site requests.
303
+ * - 'none' means the cookie is sent with cross-site requests.
304
+ * - 'lax' means the cookie is sent with top-level navigations and will be sent along with GET
305
+ * requests initiated by third-party websites.
306
+ * @default 'none'
307
+ */
308
+ sameSite: 'none' | 'lax'
309
+ /**
310
+ * The name of the cookie.
311
+ * This is the key under which the session data will be stored in the cookie.
312
+ * @default 'as' - 'as' stands for "api session"
313
+ */
314
+ name: string
315
+ }
316
+
317
+ /**
318
+ * Configuration for JWT-based session transport.
319
+ */
320
+ export interface JwtConfiguration extends SessionTransport {
321
+ kind: 'jwt'
322
+ /**
323
+ * The lifetime of the JWT token.
324
+ * This is a string representing the duration, e.g., "7d" for 7 days or "15m" for 15 minutes.
325
+ *
326
+ * @default "7d"
327
+ */
328
+ lifetime: string
329
+ }
330
+
331
+ export interface SessionConfiguration {
332
+ /**
333
+ * The secret used to sign the JWT and cookies. Should be handled securely.
334
+ * Not visible in the UI after being set.
335
+ */
336
+ secret: string
337
+ /**
338
+ * The properties from the `User` entity to be encoded into the session payload (JWT/cookie).
339
+ * These properties become available in the `request.auth` object at runtime.
340
+ */
341
+ properties: string[]
342
+ /**
343
+ * The cookie-based session transport configuration.
344
+ */
345
+ cookie?: CookieConfiguration
346
+
347
+ /**
348
+ * The JWT-based session transport configuration.
349
+ */
350
+ jwt?: JwtConfiguration
351
+ }
352
+
353
+ /**
354
+ * Defines the authorization strategy for the API.
355
+ * It is a base interface that can be extended for different strategies.
356
+ * For MVP, we will start with Roles-Based Access Control (RBAC).
357
+ */
358
+ export interface AuthorizationConfiguration {
359
+ /**
360
+ * The authorization strategy. For MVP, we will start with RBAC.
361
+ * Post-MVP will include Permission-Based Access Control (PBAC).
362
+ * The strategy determines how users are granted access to resources.
363
+ *
364
+ * - RBAC (Roles-Based Access Control): Users are assigned roles, and permissions are granted to those roles.
365
+ * - PBAC (Permission-Based Access Control): Users are granted permissions directly, allowing for more
366
+ * granular control.
367
+ */
368
+ strategy: string
369
+ }
370
+
371
+ export interface RolesBasedAccessControl extends AuthorizationConfiguration {
372
+ strategy: 'RBAC'
373
+ /**
374
+ * The property within the designated "User" entity that defines the user's role.
375
+ * This field is used in access rules to grant permissions.
376
+ *
377
+ * This property must be marked with the "Role" data semantic in the Data Modeler.
378
+ * It is required to publish the API.
379
+ */
380
+ roleKey: string
381
+ }
382
+
383
+ /**
384
+ * Configures the strategy for authenticating end-users.
385
+ * An API can only support one authentication strategy at a time.
386
+ * This is a base interface that can be extended for different strategies.
387
+ */
388
+ export interface AuthenticationConfiguration {
389
+ /**
390
+ * The authentication method. For MVP, this is focused on username/password.
391
+ * This can be extended in the future to include 'SSO'.
392
+ */
393
+ strategy: string
394
+ }
395
+
396
+ /**
397
+ * Configuration for username/password authentication.
398
+ * This is the primary authentication method for the API (MVP).
399
+ */
400
+ export interface UsernamePasswordConfiguration extends AuthenticationConfiguration {
401
+ strategy: 'UsernamePassword'
402
+ /**
403
+ * The specific property within the User entity that holds the password.
404
+ * This property must be marked with the "Password" data semantic in the Data Modeler.
405
+ *
406
+ * This property is required to publish the API.
407
+ */
408
+ passwordKey?: string
409
+ }
410
+
411
+ /**
412
+ * Represents a Data Entity from the Data Domain that the API will expose and operate upon.
413
+ */
414
+ export interface ExposedEntity {
415
+ /**
416
+ * The key of the Data Entity from the Data Domain.
417
+ */
418
+ key: string
419
+
420
+ /**
421
+ * Optional configuration for resource-wide rate limiting and throttling.
422
+ * Defines rules to protect the resource from overuse.
423
+ */
424
+ rateLimiting?: RateLimitingConfiguration
425
+ /**
426
+ * Access control rules defining who can perform actions on this resource or collection.
427
+ * It override the top-level access rules defined in the API model.
428
+ */
429
+ accessRule?: AccessRule[]
430
+
431
+ /**
432
+ * The collection of API actions (e.g., List, Read, Create) enabled for this entity.
433
+ */
434
+ actions: ApiAction[]
435
+ }
436
+
437
+ /**
438
+ * Represents a specific, configurable API operation applied to a Data Entity.
439
+ * Corresponds to common RESTful interactions.
440
+ */
441
+ export type ApiAction = ListAction | ReadAction | CreateAction | UpdateAction | DeleteAction | SearchAction
442
+
443
+ /**
444
+ * A base interface for common properties across all actions.
445
+ */
446
+ interface Action {
447
+ /**
448
+ * The specific kind of action (e.g., 'List', 'Read', etc.)
449
+ */
450
+ kind: string
451
+ /**
452
+ * Access control rules defining who can perform this action. It is only applied if the
453
+ * authorization strategy is set to 'RBAC'.
454
+ * If no rules grant access, it's denied by default making it essentially private.
455
+ *
456
+ * Note, the API can defined top level access rules that apply to all actions. If this property is set,
457
+ * it overrides the top level access rules for this specific action.
458
+ *
459
+ * It is an ordered list, meaning the first rule that matches the user will be applied.
460
+ * If multiple rules match, the first one in the list takes precedence.
461
+ * If no rules match, the action is denied.
462
+ */
463
+ accessRule?: AccessRule[]
464
+ /**
465
+ * Optional configuration for action-wide rate limiting and throttling.
466
+ * Defines rules to protect the action from overuse.
467
+ */
468
+ rateLimiting?: RateLimitingConfiguration
469
+ }
470
+
471
+ /**
472
+ * Represents a pagination strategy for API actions that return collections of resources.
473
+ * This is a base interface that can be extended for different pagination strategies.
474
+ */
475
+ export interface PaginationStrategy {
476
+ /**
477
+ * The kind of pagination strategy. This is used to identify the specific pagination method.
478
+ * For example, 'cursor' for cursor-based pagination or 'offset' for offset-based pagination.
479
+ */
480
+ kind: string
481
+ /**
482
+ * The default page size for the pagination strategy.
483
+ * This is the number of items returned per page when no specific page size is requested.
484
+ */
485
+ pageSize?: number
486
+ }
487
+
488
+ /**
489
+ * Represents the cursor-based pagination strategy.
490
+ */
491
+ export interface CursorPaginationStrategy extends PaginationStrategy {
492
+ kind: 'cursor'
493
+ }
494
+
495
+ /**
496
+ * Represents the offset-based pagination strategy.
497
+ */
498
+ export interface OffsetPaginationStrategy extends PaginationStrategy {
499
+ kind: 'offset'
500
+ }
501
+
502
+ /**
503
+ * Enables retrieving a collection of resources.
504
+ * Endpoint: GET /[entity-collection-name]
505
+ */
506
+ export interface ListAction extends Action {
507
+ kind: 'list'
508
+ /**
509
+ * The pagination strategy used for this action.
510
+ * This defines how the results are paginated when retrieving a collection of resources.
511
+ * It can be either 'cursor' or 'offset'.
512
+ */
513
+ pagination: PaginationStrategy
514
+ /**
515
+ * Fields from the entity that can be used for filtering.
516
+ * Must be marked as "indexable" in the Data Model.
517
+ */
518
+ filterableFields: string[]
519
+ /**
520
+ * Fields from the entity that can be used for sorting.
521
+ */
522
+ sortableFields: string[]
523
+ }
524
+
525
+ /**
526
+ * Enables retrieving a single resource by its ID.
527
+ * Endpoint: GET /[entity-collection-name]/{id}
528
+ */
529
+ export interface ReadAction extends Action {
530
+ kind: 'read'
531
+ // Association handling (Link IDs vs. Embed) is defined on the
532
+ // data association itself in the Data Modeler.
533
+ }
534
+
535
+ /**
536
+ * Enables adding a new resource to a collection.
537
+ * Endpoint: POST /[entity-collection-name]
538
+ */
539
+ export interface CreateAction extends Action {
540
+ kind: 'create'
541
+ }
542
+
543
+ /**
544
+ * Enables modifying an existing resource.
545
+ * Endpoints: PUT or PATCH /[entity-collection-name]/{id}
546
+ */
547
+ export interface UpdateAction extends Action {
548
+ kind: 'update'
549
+ /**
550
+ * The allowed HTTP methods for updates. Default: PATCH only.
551
+ *
552
+ * These two methods represent the two common ways to update a resource:
553
+ * - PUT: Replaces the entire resource with the provided data.
554
+ * - PATCH: Applies a partial update to the resource, allowing for specific fields to be modified.
555
+ */
556
+ allowedMethods: ('PUT' | 'PATCH')[]
557
+ }
558
+
559
+ /**
560
+ * Enables removing an existing resource.
561
+ * Endpoint: DELETE /[entity-collection-name]/{id}
562
+ */
563
+ export interface DeleteAction extends Action {
564
+ kind: 'delete'
565
+ /**
566
+ * The strategy for deletion. Default: Soft Delete.
567
+ *
568
+ * @default 'soft'
569
+ */
570
+ strategy?: 'soft' | 'hard'
571
+ }
572
+
573
+ /**
574
+ * Enables keyword-based search across specified fields.
575
+ * Endpoint: GET /[entity-collection-name]/search
576
+ */
577
+ export interface SearchAction extends Action {
578
+ kind: 'search'
579
+ /**
580
+ * The fields within the entity to be included in the search scope.
581
+ * Must be "indexable" and typically text-based.
582
+ */
583
+ fields: string[]
584
+ }
585
+
586
+ /**
587
+ * Defines the access control policy for a specific API action.
588
+ * Based on the predefined rule types for session-based authentication.
589
+ */
590
+ export type AccessRule =
591
+ | AllowPublicAccessRule
592
+ | AllowAuthenticatedAccessRule
593
+ | MatchResourceOwnerAccessRule
594
+ | MatchUserRoleAccessRule
595
+ | MatchUserPropertyAccessRule
596
+ | MatchEmailDomainAccessRule
597
+
598
+ export interface BaseAccessRule {
599
+ /**
600
+ * The unique identifier for the access rule.
601
+ * This is used to reference the rule in the API configuration.
602
+ */
603
+ type: string
604
+ }
605
+
606
+ /**
607
+ * The action is allowed for all users, including unauthenticated ones.
608
+ * This is typically used for public APIs or resources that do not require authentication.
609
+ * It is the most permissive rule and should be used with caution.
610
+ */
611
+ export interface AllowPublicAccessRule extends BaseAccessRule {
612
+ type: 'public'
613
+ }
614
+ /**
615
+ * The action is allowed for any authenticated user.
616
+ * This rule does not impose any additional restrictions based on user properties or resource ownership.
617
+ * It is used for resources that should be accessible to all logged-in users.
618
+ */
619
+ export interface AllowAuthenticatedAccessRule extends BaseAccessRule {
620
+ type: 'authenticated'
621
+ }
622
+ /**
623
+ * The action is allowed if the authenticated user's ID matches a specific property on the resource.
624
+ * This is typically used to restrict access to resources owned by the user.
625
+ * For example, a user can only access their own profile or documents.
626
+ */
627
+ export interface MatchResourceOwnerAccessRule extends BaseAccessRule {
628
+ type: 'resourceOwner'
629
+ /**
630
+ * The property on the resource that should match the authenticated user's ID.
631
+ * This is typically the ID of the user who owns the resource.
632
+ *
633
+ * The domain model should annotate this property with the "ResourceOwnerIdentifier" semantic
634
+ * to indicate that it is used for ownership checks.
635
+ */
636
+ property: string
637
+ }
638
+
639
+ /**
640
+ * The action is allowed if the authenticated user has a specific role.
641
+ * This is used to enforce role-based access control (RBAC).
642
+ * For example, only users with the "admin" role can perform certain actions.
643
+ */
644
+ export interface MatchUserRoleAccessRule extends BaseAccessRule {
645
+ type: 'matchUserRole'
646
+ /**
647
+ * The role that the authenticated user must have to access the resource.
648
+ * This is typically a property on the user entity that defines their role.
649
+ *
650
+ * The domain model should annotate this property with the "UserRole" semantic
651
+ * to indicate that it is used for role-based access control.
652
+ */
653
+ role: string
654
+ }
655
+ /**
656
+ * The action is allowed if a specific property on the authenticated user matches an expected value.
657
+ * This is used to enforce other user-specific restrictions.
658
+ */
659
+ export interface MatchUserPropertyAccessRule extends BaseAccessRule {
660
+ type: 'matchUserProperty'
661
+ /**
662
+ * The property on the authenticated user that should match the expected value.
663
+ */
664
+ property: string
665
+ /**
666
+ * The expected value for the user property.
667
+ */
668
+ value: string
669
+ }
670
+ /**
671
+ * The action is allowed if the authenticated user's email domain matches a specific domain.
672
+ * This is used to restrict access based on the user's email address.
673
+ * For example, only users with an email address from "mycompany.com" can access certain resources.
674
+ */
675
+ export interface MatchEmailDomainAccessRule extends BaseAccessRule {
676
+ type: 'matchEmailDomain'
677
+ /**
678
+ * The email domain that the authenticated user's email must match.
679
+ */
680
+ domain: string
681
+ }
682
+
683
+ /**
684
+ * Defines the rate limiting and throttling policies for the entire API.
685
+ */
686
+ export interface RateLimitingConfiguration {
687
+ /**
688
+ * An ordered list of rules. The first rule that matches an incoming
689
+ * request will be applied.
690
+ */
691
+ rules: RateLimitRule[]
692
+ }
693
+
694
+ /**
695
+ * Represents a single rate limiting rule that applies to a specific
696
+ * type of client, using a token bucket algorithm.
697
+ */
698
+ export interface RateLimitRule {
699
+ /**
700
+ * A human-readable description of what this rule is for.
701
+ * e.g., "Limit anonymous users to 60 requests per hour."
702
+ */
703
+ description?: string
704
+
705
+ /**
706
+ * Defines how to group requests for rate limiting. This determines
707
+ * who the limit applies to.
708
+ *
709
+ * - 'ip': Keys on the client's IP address. Best for anonymous traffic.
710
+ * - 'userId': Keys on the authenticated user's ID. Best for logged-in users.
711
+ * - 'role': Applies a shared limit to all users of a specific role.
712
+ */
713
+ key: { type: 'ip' } | { type: 'userId' } | { type: 'role'; value: string }
714
+
715
+ /**
716
+ * The number of requests allowed over the defined interval.
717
+ * This is the rate at which tokens are added to the bucket.
718
+ */
719
+ rate: number
720
+
721
+ /**
722
+ * The time interval for the rate.
723
+ */
724
+ interval: 'second' | 'minute' | 'hour' | 'day'
725
+
726
+ /**
727
+ * The maximum number of requests that can be made in a burst.
728
+ * This represents the "bucket size." A larger burst allows for
729
+ * more requests to be made in a short period before throttling begins.
730
+ */
731
+ burst: number
732
+ }
@@ -20,3 +20,5 @@ export const DataCatalogKind = 'Core#DataCatalog'
20
20
  export const DataCatalogVersionKind = 'Core#DataCatalogVersion'
21
21
  export const OrganizationKind = 'Core#Organization'
22
22
  export const InvitationKind = 'Core#Invitation'
23
+ export const ApiModelKind = 'Core#ApiModel'
24
+ export const ApiFileKind = 'Core#ApiFile'
@@ -181,6 +181,45 @@ export class StoredFile {
181
181
  this[shortcutTargetSymbol] = value
182
182
  }
183
183
 
184
+ /**
185
+ * Creates a file schema object with the given properties.
186
+ * The `key` is generated if not set.
187
+ *
188
+ * @param input The input to create the file schema.
189
+ * @returns The file schema object.
190
+ */
191
+ static createSchema(input: Partial<IStoredFile> = {}): IStoredFile {
192
+ const { key = nanoid(), kind, iconColor, shortcutTarget } = input
193
+ const result: IStoredFile = {
194
+ key,
195
+ kind: kind || '',
196
+ info: Thing.fromJSON(input.info, { name: 'Unnamed file' }).toJSON(),
197
+ }
198
+ if (iconColor) {
199
+ result.iconColor = iconColor
200
+ }
201
+ if (shortcutTarget) {
202
+ result.isShortcut = true
203
+ result.shortcutTarget = shortcutTarget
204
+ }
205
+ return result
206
+ }
207
+
208
+ constructor(state: IStoredFile) {
209
+ this.kind = state.kind
210
+ this.key = state.key
211
+ this.info = new Thing(state.info)
212
+ if (state.iconColor) {
213
+ this.iconColor = state.iconColor
214
+ }
215
+ if (state.shortcutTarget) {
216
+ this.shortcutTarget = state.shortcutTarget
217
+ }
218
+ }
219
+
220
+ /**
221
+ * @deprecated Use `createSchema()` and setup values in the constructor instead.
222
+ */
184
223
  new(init: IStoredFile): this {
185
224
  const { key = nanoid(), info, kind, iconColor, shortcutTarget } = init
186
225
  this.key = key
@@ -409,6 +448,64 @@ export class File extends StoredFile {
409
448
  return this[permissionsSymbol]
410
449
  }
411
450
 
451
+ static override createSchema(input: Partial<IFile> = {}): IFile {
452
+ const result = StoredFile.createSchema(input) as IFile
453
+ if (Array.isArray(input.parents)) {
454
+ result.parents = [...input.parents]
455
+ } else {
456
+ result.parents = []
457
+ }
458
+ if (Array.isArray(input.permissionIds)) {
459
+ result.permissionIds = [...input.permissionIds]
460
+ } else {
461
+ result.permissionIds = []
462
+ }
463
+ if (Array.isArray(input.permissions)) {
464
+ result.permissions = input.permissions.map((i) => ({ ...i }))
465
+ } else {
466
+ result.permissions = []
467
+ }
468
+ if (input.capabilities) {
469
+ result.capabilities = { ...input.capabilities }
470
+ }
471
+ if (input.lastModified) {
472
+ result.lastModified = { ...input.lastModified }
473
+ } else {
474
+ result.lastModified = { user: '', time: 0, byMe: false }
475
+ }
476
+ if (typeof input.deleted === 'boolean') {
477
+ result.deleted = input.deleted
478
+ result.deletedInfo = input.deletedInfo ? { ...input.deletedInfo } : undefined
479
+ }
480
+ if (Array.isArray(input.labels)) {
481
+ result.labels = [...input.labels]
482
+ }
483
+ if (typeof input.shortcutTarget === 'string') {
484
+ result.shortcutTarget = input.shortcutTarget
485
+ }
486
+ return result
487
+ }
488
+
489
+ constructor(state?: Partial<IFile>) {
490
+ const init = File.createSchema(state)
491
+ super(init)
492
+ this[parentsSymbol] = [...init.parents]
493
+ this[permissionIdsSymbol] = [...init.permissionIds]
494
+ this[permissionsSymbol] = init.permissions.map((i) => ({ ...i }))
495
+ this[capabilitiesSymbol] = init.capabilities ? { ...init.capabilities } : undefined
496
+ this[lastModifiedSymbol] = Object.freeze({ ...init.lastModified })
497
+ if (typeof init.deleted === 'boolean') {
498
+ this[deletedSymbol] = init.deleted
499
+ this[deletedInfoSymbol] = init.deletedInfo ? Object.freeze({ ...init.deletedInfo }) : undefined
500
+ }
501
+ if (Array.isArray(init.labels)) {
502
+ this.labels = [...init.labels]
503
+ }
504
+ }
505
+
506
+ /**
507
+ * @deprecated Use `createSchema()` and setup values in the constructor instead.
508
+ */
412
509
  override new(init: IFile): this {
413
510
  super.new(init)
414
511
  const { permissions = [], parents = [], permissionIds = [], deleted, deletedInfo, lastModified, labels } = init
@@ -453,20 +550,10 @@ export class File extends StoredFile {
453
550
 
454
551
  /**
455
552
  * @param name The name to set.
456
- * @param owner The user id that is the owner of the file.
553
+ * @param kind The kind of the file to create.
457
554
  */
458
- static fromName(name: string, kind = ''): File {
459
- const key = nanoid()
460
- const definition = new File()
461
- definition.new({
462
- key,
463
- kind,
464
- info: Thing.fromName(name).toJSON(),
465
- parents: [],
466
- permissionIds: [],
467
- permissions: [],
468
- lastModified: { user: '', time: 0, byMe: false },
469
- })
555
+ static fromName(name: string, kind: string): File {
556
+ const definition = new File({ kind, info: { name } })
470
557
  return definition
471
558
  }
472
559