@marinoscar/platform-api 0.1.0-next.21 → 0.1.0-next.22

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/CHANGELOG.md +14 -0
  2. package/dist/ai/features/ai-feature.registry.d.ts +7 -0
  3. package/dist/ai/features/ai-feature.registry.d.ts.map +1 -1
  4. package/dist/ai/features/ai-feature.registry.js +3 -0
  5. package/dist/ai/features/ai-feature.registry.js.map +1 -1
  6. package/dist/ai/keys/ai-key-resolver.service.d.ts +16 -0
  7. package/dist/ai/keys/ai-key-resolver.service.d.ts.map +1 -1
  8. package/dist/ai/keys/ai-key-resolver.service.js +44 -0
  9. package/dist/ai/keys/ai-key-resolver.service.js.map +1 -1
  10. package/dist/ai/keys/usable-models.service.d.ts +13 -1
  11. package/dist/ai/keys/usable-models.service.d.ts.map +1 -1
  12. package/dist/ai/keys/usable-models.service.js +37 -12
  13. package/dist/ai/keys/usable-models.service.js.map +1 -1
  14. package/dist/ai/runtime/ai-limits.service.d.ts +2 -1
  15. package/dist/ai/runtime/ai-limits.service.d.ts.map +1 -1
  16. package/dist/ai/runtime/ai-limits.service.js +7 -2
  17. package/dist/ai/runtime/ai-limits.service.js.map +1 -1
  18. package/dist/ai/runtime/ai-runtime.types.d.ts +46 -1
  19. package/dist/ai/runtime/ai-runtime.types.d.ts.map +1 -1
  20. package/dist/ai/runtime/ai-runtime.types.js.map +1 -1
  21. package/dist/ai/runtime/ai.service.d.ts +142 -5
  22. package/dist/ai/runtime/ai.service.d.ts.map +1 -1
  23. package/dist/ai/runtime/ai.service.js +353 -46
  24. package/dist/ai/runtime/ai.service.js.map +1 -1
  25. package/dist/ai/runtime/index.d.ts +1 -1
  26. package/dist/ai/runtime/index.d.ts.map +1 -1
  27. package/dist/ai/runtime/target-resolver.d.ts +2 -2
  28. package/dist/ai/runtime/target-resolver.d.ts.map +1 -1
  29. package/dist/ai/runtime/target-resolver.js +2 -1
  30. package/dist/ai/runtime/target-resolver.js.map +1 -1
  31. package/dist/ai/testing/conformance/ai-key-policy.suite.d.ts.map +1 -1
  32. package/dist/ai/testing/conformance/ai-key-policy.suite.js +54 -0
  33. package/dist/ai/testing/conformance/ai-key-policy.suite.js.map +1 -1
  34. package/dist/ai/testing/conformance/ai-secret-egress.suite.d.ts.map +1 -1
  35. package/dist/ai/testing/conformance/ai-secret-egress.suite.js +59 -0
  36. package/dist/ai/testing/conformance/ai-secret-egress.suite.js.map +1 -1
  37. package/dist/identity/device-auth/device-auth.service.d.ts +9 -2
  38. package/dist/identity/device-auth/device-auth.service.d.ts.map +1 -1
  39. package/dist/identity/device-auth/device-auth.service.js +44 -4
  40. package/dist/identity/device-auth/device-auth.service.js.map +1 -1
  41. package/dist/identity/device-auth/dto/device-code-request.dto.d.ts +12 -0
  42. package/dist/identity/device-auth/dto/device-code-request.dto.d.ts.map +1 -1
  43. package/dist/identity/identity.options.d.ts +25 -0
  44. package/dist/identity/identity.options.d.ts.map +1 -1
  45. package/dist/identity/identity.options.js +11 -0
  46. package/dist/identity/identity.options.js.map +1 -1
  47. package/dist/identity/index.d.ts +1 -1
  48. package/dist/identity/index.d.ts.map +1 -1
  49. package/dist/nodes/current-node.decorator.d.ts +18 -0
  50. package/dist/nodes/current-node.decorator.d.ts.map +1 -0
  51. package/dist/nodes/current-node.decorator.js +28 -0
  52. package/dist/nodes/current-node.decorator.js.map +1 -0
  53. package/dist/nodes/index.d.ts +8 -0
  54. package/dist/nodes/index.d.ts.map +1 -1
  55. package/dist/nodes/index.js +21 -2
  56. package/dist/nodes/index.js.map +1 -1
  57. package/dist/nodes/node-ownership.d.ts +34 -0
  58. package/dist/nodes/node-ownership.d.ts.map +1 -0
  59. package/dist/nodes/node-ownership.js +92 -0
  60. package/dist/nodes/node-ownership.js.map +1 -0
  61. package/dist/nodes/node-route.decorator.d.ts +31 -0
  62. package/dist/nodes/node-route.decorator.d.ts.map +1 -0
  63. package/dist/nodes/node-route.decorator.js +54 -0
  64. package/dist/nodes/node-route.decorator.js.map +1 -0
  65. package/dist/nodes/node-route.guard.d.ts +22 -0
  66. package/dist/nodes/node-route.guard.d.ts.map +1 -0
  67. package/dist/nodes/node-route.guard.js +74 -0
  68. package/dist/nodes/node-route.guard.js.map +1 -0
  69. package/dist/nodes/node-route.module.d.ts +21 -0
  70. package/dist/nodes/node-route.module.d.ts.map +1 -0
  71. package/dist/nodes/node-route.module.js +99 -0
  72. package/dist/nodes/node-route.module.js.map +1 -0
  73. package/dist/nodes/node-route.options.d.ts +59 -0
  74. package/dist/nodes/node-route.options.d.ts.map +1 -0
  75. package/dist/nodes/node-route.options.js +29 -0
  76. package/dist/nodes/node-route.options.js.map +1 -0
  77. package/dist/nodes/node-route.paths.d.ts +47 -0
  78. package/dist/nodes/node-route.paths.d.ts.map +1 -0
  79. package/dist/nodes/node-route.paths.js +129 -0
  80. package/dist/nodes/node-route.paths.js.map +1 -0
  81. package/dist/nodes/nodes.service.d.ts.map +1 -1
  82. package/dist/nodes/nodes.service.js +3 -15
  83. package/dist/nodes/nodes.service.js.map +1 -1
  84. package/dist/nodes/testing/conformance.d.ts +86 -0
  85. package/dist/nodes/testing/conformance.d.ts.map +1 -0
  86. package/dist/nodes/testing/conformance.js +230 -0
  87. package/dist/nodes/testing/conformance.js.map +1 -0
  88. package/dist/nodes/testing/discover.d.ts +13 -0
  89. package/dist/nodes/testing/discover.d.ts.map +1 -0
  90. package/dist/nodes/testing/discover.js +42 -0
  91. package/dist/nodes/testing/discover.js.map +1 -0
  92. package/dist/nodes/testing/index.d.ts +3 -0
  93. package/dist/nodes/testing/index.d.ts.map +1 -0
  94. package/dist/nodes/testing/index.js +13 -0
  95. package/dist/nodes/testing/index.js.map +1 -0
  96. package/package.json +7 -3
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ // =============================================================================
3
+ // Node ownership: the one rule, and the narrow provider an app route may use
4
+ // =============================================================================
5
+ //
6
+ // `assertNodeOwnedBy` is the rule `NodesService.assertOwnership` has always
7
+ // applied (404 for a node that does not exist, 403 for one that belongs to
8
+ // somebody else; the argument for 403 over 404 is in `nodes.service.ts`). It is
9
+ // extracted so the packaged control plane and the `@NodeRoute()` guard cannot
10
+ // drift into two opinions about who owns a node.
11
+ //
12
+ // `NodeOwnershipService` exists because `NodesService` is deliberately NOT
13
+ // exported from `NodesModule` (a feature module that could inject it could
14
+ // claim jobs or settle them outside the terminal chokepoint). This is the
15
+ // least-privilege handle: one method, read-only.
16
+ // =============================================================================
17
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
18
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
19
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
20
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
21
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
22
+ };
23
+ var __metadata = (this && this.__metadata) || function (k, v) {
24
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
25
+ };
26
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
27
+ return function (target, key) { decorator(target, key, paramIndex); }
28
+ };
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.NodeOwnershipService = void 0;
31
+ exports.assertNodeOwnedBy = assertNodeOwnedBy;
32
+ const common_1 = require("@nestjs/common");
33
+ const index_1 = require("../core/index");
34
+ /**
35
+ * Loads node `nodeId` and proves `userId` owns it.
36
+ *
37
+ * @param prisma - anything with the `workerNode` delegate.
38
+ * @param userId - the authenticated owner.
39
+ * @param nodeId - the node's id.
40
+ * @returns the verified node row.
41
+ * @throws NotFoundException when the node does not exist; ForbiddenException when another user owns it.
42
+ *
43
+ * @stability stable
44
+ */
45
+ async function assertNodeOwnedBy(prisma, userId, nodeId) {
46
+ const node = await prisma.workerNode.findUnique({ where: { id: nodeId } });
47
+ if (!node) {
48
+ throw new common_1.NotFoundException({
49
+ message: `Worker node ${nodeId} was not found.`,
50
+ details: { nodeId },
51
+ });
52
+ }
53
+ if (node.createdById !== userId) {
54
+ throw new common_1.ForbiddenException({
55
+ message: `Worker node ${nodeId} belongs to another user. Check that this credential and ` +
56
+ `this node id came from the same registration.`,
57
+ details: { nodeId },
58
+ });
59
+ }
60
+ return node;
61
+ }
62
+ /**
63
+ * The ownership check an app's node-plane code may inject: the same rule as
64
+ * the packaged control plane, with none of the rest of `NodesService`. Provided
65
+ * and exported by `NodeRouteModule`.
66
+ *
67
+ * @stability stable
68
+ */
69
+ let NodeOwnershipService = class NodeOwnershipService {
70
+ prisma;
71
+ constructor(prisma) {
72
+ this.prisma = prisma;
73
+ }
74
+ /**
75
+ * Proves `userId` owns node `nodeId`.
76
+ *
77
+ * @param userId - the authenticated owner.
78
+ * @param nodeId - the node's id.
79
+ * @returns the verified node row.
80
+ * @throws NotFoundException (missing node) or ForbiddenException (not yours).
81
+ */
82
+ assertOwnership(userId, nodeId) {
83
+ return assertNodeOwnedBy(this.prisma, userId, nodeId);
84
+ }
85
+ };
86
+ exports.NodeOwnershipService = NodeOwnershipService;
87
+ exports.NodeOwnershipService = NodeOwnershipService = __decorate([
88
+ (0, common_1.Injectable)(),
89
+ __param(0, (0, common_1.Inject)(index_1.PLATFORM_PRISMA)),
90
+ __metadata("design:paramtypes", [Object])
91
+ ], NodeOwnershipService);
92
+ //# sourceMappingURL=node-ownership.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-ownership.js","sourceRoot":"","sources":["../../src/nodes/node-ownership.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,6EAA6E;AAC7E,gFAAgF;AAChF,EAAE;AACF,4EAA4E;AAC5E,2EAA2E;AAC3E,gFAAgF;AAChF,8EAA8E;AAC9E,iDAAiD;AACjD,EAAE;AACF,2EAA2E;AAC3E,2EAA2E;AAC3E,0EAA0E;AAC1E,iDAAiD;AACjD,gFAAgF;;;;;;;;;;;;;;;AAkBhF,8CAoBC;AApCD,2CAA2F;AAE3F,yCAAgD;AAGhD;;;;;;;;;;GAUG;AACI,KAAK,UAAU,iBAAiB,CAAC,MAAsC,EAAE,MAAc,EAAE,MAAc;IAC5G,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IAE3E,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,0BAAiB,CAAC;YAC1B,OAAO,EAAE,eAAe,MAAM,iBAAiB;YAC/C,OAAO,EAAE,EAAE,MAAM,EAAE;SACpB,CAAC,CAAC;IACL,CAAC;IAED,IAAI,IAAI,CAAC,WAAW,KAAK,MAAM,EAAE,CAAC;QAChC,MAAM,IAAI,2BAAkB,CAAC;YAC3B,OAAO,EACL,eAAe,MAAM,2DAA2D;gBAChF,+CAA+C;YACjD,OAAO,EAAE,EAAE,MAAM,EAAE;SACpB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AAEI,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;IACuB;IAAtD,YAAsD,MAAkB;QAAlB,WAAM,GAAN,MAAM,CAAY;IAAG,CAAC;IAE5E;;;;;;;OAOG;IACH,eAAe,CAAC,MAAc,EAAE,MAAc;QAC5C,OAAO,iBAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACxD,CAAC;CACF,CAAA;AAdY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,mBAAU,GAAE;IAEE,WAAA,IAAA,eAAM,EAAC,uBAAe,CAAC,CAAA;;GADzB,oBAAoB,CAchC"}
@@ -0,0 +1,31 @@
1
+ import { type NodeRouteOptions } from './node-route.options';
2
+ /**
3
+ * Marks an app controller (or handler) as a node-plane route. Its path must be
4
+ * under `NODE_ROUTE_PREFIX` (`/api/nodes`) and must not overlap
5
+ * `RESERVED_NODE_SUBPATHS` (checked at bootstrap by `NodeRouteModule` and by
6
+ * the `nodes` conformance suite). The controller's module imports
7
+ * `NodeRouteModule`, which provides the guard.
8
+ *
9
+ * The decorator applies `@Auth({ permissions })` too, so a controller needs no
10
+ * separate `@Auth()`.
11
+ *
12
+ * @param options - see {@link NodeRouteOptions}.
13
+ * @returns a class and method decorator.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * @Controller('nodes/:id/reports')
18
+ * @NodeRoute({ credentials: ['nod'] })
19
+ * export class ReportsController {
20
+ * @Get('latest')
21
+ * latest(@CurrentNode() node: WorkerNode) {
22
+ * return this.reports.latestFor(node);
23
+ * }
24
+ * }
25
+ * ```
26
+ *
27
+ * @extensionPoint hook
28
+ * @stability experimental
29
+ */
30
+ export declare function NodeRoute(options?: NodeRouteOptions): ClassDecorator & MethodDecorator;
31
+ //# sourceMappingURL=node-route.decorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-route.decorator.d.ts","sourceRoot":"","sources":["../../src/nodes/node-route.decorator.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAgD,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG3G;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,cAAc,GAAG,eAAe,CAO1F"}
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ // =============================================================================
3
+ // @NodeRoute(): an app route on the node plane
4
+ // =============================================================================
5
+ //
6
+ // WHAT IT IS. `JwtAuthGuard` is the outer fence: a `nod_` credential reaches
7
+ // `/api/nodes` and what is under it, nothing else. `@NodeRoute()` is the inner
8
+ // one an app controller mounted there opts into. It composes `@Auth()` (the
9
+ // platform node plane's permission, by default) with `NodeRouteGuard`, which
10
+ // narrows the admitted credential kinds and PROVES the caller owns the node
11
+ // named in the path before the handler runs, so no handler can forget to.
12
+ //
13
+ // It only narrows. It never widens what `JwtAuthGuard` admits, and the prefix
14
+ // allowlist stays authoritative.
15
+ // =============================================================================
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.NodeRoute = NodeRoute;
18
+ const common_1 = require("@nestjs/common");
19
+ const index_1 = require("../identity/index");
20
+ const node_route_options_1 = require("./node-route.options");
21
+ const node_route_guard_1 = require("./node-route.guard");
22
+ /**
23
+ * Marks an app controller (or handler) as a node-plane route. Its path must be
24
+ * under `NODE_ROUTE_PREFIX` (`/api/nodes`) and must not overlap
25
+ * `RESERVED_NODE_SUBPATHS` (checked at bootstrap by `NodeRouteModule` and by
26
+ * the `nodes` conformance suite). The controller's module imports
27
+ * `NodeRouteModule`, which provides the guard.
28
+ *
29
+ * The decorator applies `@Auth({ permissions })` too, so a controller needs no
30
+ * separate `@Auth()`.
31
+ *
32
+ * @param options - see {@link NodeRouteOptions}.
33
+ * @returns a class and method decorator.
34
+ *
35
+ * @example
36
+ * ```ts
37
+ * @Controller('nodes/:id/reports')
38
+ * @NodeRoute({ credentials: ['nod'] })
39
+ * export class ReportsController {
40
+ * @Get('latest')
41
+ * latest(@CurrentNode() node: WorkerNode) {
42
+ * return this.reports.latestFor(node);
43
+ * }
44
+ * }
45
+ * ```
46
+ *
47
+ * @extensionPoint hook
48
+ * @stability experimental
49
+ */
50
+ function NodeRoute(options = {}) {
51
+ const resolved = (0, node_route_options_1.resolveNodeRouteOptions)(options);
52
+ return (0, common_1.applyDecorators)((0, common_1.SetMetadata)(node_route_options_1.NODE_ROUTE_METADATA, resolved), (0, index_1.Auth)({ permissions: [...resolved.permissions] }), (0, common_1.UseGuards)(node_route_guard_1.NodeRouteGuard));
53
+ }
54
+ //# sourceMappingURL=node-route.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-route.decorator.js","sourceRoot":"","sources":["../../src/nodes/node-route.decorator.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,+CAA+C;AAC/C,gFAAgF;AAChF,EAAE;AACF,6EAA6E;AAC7E,+EAA+E;AAC/E,4EAA4E;AAC5E,6EAA6E;AAC7E,4EAA4E;AAC5E,0EAA0E;AAC1E,EAAE;AACF,8EAA8E;AAC9E,iCAAiC;AACjC,gFAAgF;;AAoChF,8BAOC;AAzCD,2CAAyE;AAEzE,6CAAyC;AACzC,6DAA2G;AAC3G,yDAAoD;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,SAAgB,SAAS,CAAC,UAA4B,EAAE;IACtD,MAAM,QAAQ,GAAG,IAAA,4CAAuB,EAAC,OAAO,CAAC,CAAC;IAClD,OAAO,IAAA,wBAAe,EACpB,IAAA,oBAAW,EAAC,wCAAmB,EAAE,QAAQ,CAAC,EAC1C,IAAA,YAAI,EAAC,EAAE,WAAW,EAAE,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAU,EAAE,CAAC,EACzD,IAAA,kBAAS,EAAC,iCAAc,CAAC,CACU,CAAC;AACxC,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { CanActivate, ExecutionContext } from '@nestjs/common';
2
+ import { Reflector } from '@nestjs/core';
3
+ import { NodeOwnershipService } from './node-ownership';
4
+ /**
5
+ * Applied by `@NodeRoute()`, after `JwtAuthGuard`: refuses a credential kind
6
+ * the route did not admit (403), then, when the route names a node, loads it
7
+ * and proves the caller owns it (404 missing, 403 not yours; the packaged
8
+ * control plane's own semantics) and hands it to `@CurrentNode()`.
9
+ *
10
+ * @stability experimental
11
+ */
12
+ export declare class NodeRouteGuard implements CanActivate {
13
+ private readonly reflector;
14
+ private readonly ownership;
15
+ constructor(reflector: Reflector, ownership: NodeOwnershipService);
16
+ /**
17
+ * @param context - the execution context.
18
+ * @returns `true` to admit; throws 400, 403 or 404 otherwise.
19
+ */
20
+ canActivate(context: ExecutionContext): Promise<boolean>;
21
+ }
22
+ //# sourceMappingURL=node-route.guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-route.guard.d.ts","sourceRoot":"","sources":["../../src/nodes/node-route.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EACX,gBAAgB,EAGjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAKzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAcxD;;;;;;;GAOG;AACH,qBACa,cAAe,YAAW,WAAW;IAE9C,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS;gBADT,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,oBAAoB;IAGlD;;;OAGG;IACG,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;CA8B/D"}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.NodeRouteGuard = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const core_1 = require("@nestjs/core");
15
+ const current_node_decorator_1 = require("./current-node.decorator");
16
+ const node_route_options_1 = require("./node-route.options");
17
+ const node_ownership_1 = require("./node-ownership");
18
+ const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
19
+ const KIND = { node: 'nod', pat: 'pat', jwt: 'jwt' };
20
+ /**
21
+ * Applied by `@NodeRoute()`, after `JwtAuthGuard`: refuses a credential kind
22
+ * the route did not admit (403), then, when the route names a node, loads it
23
+ * and proves the caller owns it (404 missing, 403 not yours; the packaged
24
+ * control plane's own semantics) and hands it to `@CurrentNode()`.
25
+ *
26
+ * @stability experimental
27
+ */
28
+ let NodeRouteGuard = class NodeRouteGuard {
29
+ reflector;
30
+ ownership;
31
+ constructor(reflector, ownership) {
32
+ this.reflector = reflector;
33
+ this.ownership = ownership;
34
+ }
35
+ /**
36
+ * @param context - the execution context.
37
+ * @returns `true` to admit; throws 400, 403 or 404 otherwise.
38
+ */
39
+ async canActivate(context) {
40
+ const options = this.reflector.getAllAndOverride(node_route_options_1.NODE_ROUTE_METADATA, [
41
+ context.getHandler(),
42
+ context.getClass(),
43
+ ]);
44
+ // Unreachable through the decorator; fail closed rather than admit.
45
+ if (!options)
46
+ throw new common_1.ForbiddenException('Route is not a declared node route.');
47
+ const request = context.switchToHttp().getRequest();
48
+ const credential = request.authCredential ? KIND[request.authCredential.kind] : undefined;
49
+ if (!credential || !options.credentials.includes(credential)) {
50
+ throw new common_1.ForbiddenException({
51
+ message: 'This credential kind is not accepted on this route.',
52
+ details: { accepted: [...options.credentials] },
53
+ });
54
+ }
55
+ if (options.nodeParam === false)
56
+ return true;
57
+ const userId = (request.requestUser ?? request.user)?.id;
58
+ if (!userId)
59
+ throw new common_1.ForbiddenException('No user in request');
60
+ const nodeId = request.params?.[options.nodeParam];
61
+ if (!nodeId || !UUID.test(nodeId)) {
62
+ throw new common_1.BadRequestException({ message: `Route parameter "${options.nodeParam}" must be a node id (uuid).` });
63
+ }
64
+ request[current_node_decorator_1.NODE_ROUTE_REQUEST_KEY] = await this.ownership.assertOwnership(userId, nodeId);
65
+ return true;
66
+ }
67
+ };
68
+ exports.NodeRouteGuard = NodeRouteGuard;
69
+ exports.NodeRouteGuard = NodeRouteGuard = __decorate([
70
+ (0, common_1.Injectable)(),
71
+ __metadata("design:paramtypes", [core_1.Reflector,
72
+ node_ownership_1.NodeOwnershipService])
73
+ ], NodeRouteGuard);
74
+ //# sourceMappingURL=node-route.guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-route.guard.js","sourceRoot":"","sources":["../../src/nodes/node-route.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAMwB;AACxB,uCAAyC;AAGzC,qEAAkE;AAClE,6DAAoH;AACpH,qDAAwD;AAExD,MAAM,IAAI,GAAG,iEAAiE,CAAC;AAU/E,MAAM,IAAI,GAA4D,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;AAE9G;;;;;;;GAOG;AAEI,IAAM,cAAc,GAApB,MAAM,cAAc;IAEN;IACA;IAFnB,YACmB,SAAoB,EACpB,SAA+B;QAD/B,cAAS,GAAT,SAAS,CAAW;QACpB,cAAS,GAAT,SAAS,CAAsB;IAC/C,CAAC;IAEJ;;;OAGG;IACH,KAAK,CAAC,WAAW,CAAC,OAAyB;QACzC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAuC,wCAAmB,EAAE;YAC1G,OAAO,CAAC,UAAU,EAAE;YACpB,OAAO,CAAC,QAAQ,EAAE;SACnB,CAAC,CAAC;QACH,oEAAoE;QACpE,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,2BAAkB,CAAC,qCAAqC,CAAC,CAAC;QAElF,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAoB,CAAC;QACtE,MAAM,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC1F,IAAI,CAAC,UAAU,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAC7D,MAAM,IAAI,2BAAkB,CAAC;gBAC3B,OAAO,EAAE,qDAAqD;gBAC9D,OAAO,EAAE,EAAE,QAAQ,EAAE,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,EAAE;aAChD,CAAC,CAAC;QACL,CAAC;QAED,IAAI,OAAO,CAAC,SAAS,KAAK,KAAK;YAAE,OAAO,IAAI,CAAC;QAE7C,MAAM,MAAM,GAAG,CAAC,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACzD,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,2BAAkB,CAAC,oBAAoB,CAAC,CAAC;QAEhE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,4BAAmB,CAAC,EAAE,OAAO,EAAE,oBAAoB,OAAO,CAAC,SAAS,6BAA6B,EAAE,CAAC,CAAC;QACjH,CAAC;QAED,OAAO,CAAC,+CAAsB,CAAC,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACvF,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AAxCY,wCAAc;yBAAd,cAAc;IAD1B,IAAA,mBAAU,GAAE;qCAGmB,gBAAS;QACT,qCAAoB;GAHvC,cAAc,CAwC1B"}
@@ -0,0 +1,21 @@
1
+ import type { Type } from '@nestjs/common';
2
+ /**
3
+ * The problems with the `@NodeRoute()` controllers given, one message each.
4
+ *
5
+ * @param controllers - controller classes.
6
+ * @returns the violations; empty when every node route is placed correctly.
7
+ *
8
+ * @stability experimental
9
+ */
10
+ export declare function findNodeRoutePlacementProblems(controllers: ReadonlyArray<Type<unknown>>): string[];
11
+ /**
12
+ * Provides and exports `NodeRouteGuard` and `NodeOwnershipService`, and runs the
13
+ * placement check at bootstrap. Import it where a `@NodeRoute()` controller is
14
+ * declared.
15
+ *
16
+ * @extensionPoint component
17
+ * @stability experimental
18
+ */
19
+ export declare class NodeRouteModule {
20
+ }
21
+ //# sourceMappingURL=node-route.module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-route.module.d.ts","sourceRoot":"","sources":["../../src/nodes/node-route.module.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAE3C;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAAC,WAAW,EAAE,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,MAAM,EAAE,CAkBlG;AAkBD;;;;;;;GAOG;AACH,qBAKa,eAAe;CAAG"}
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ // =============================================================================
3
+ // NodeRouteModule: what a feature module imports to use @NodeRoute()
4
+ // =============================================================================
5
+ //
6
+ // `NodesModule` does not export `NodesService` (a feature module that could
7
+ // inject it could claim and settle jobs). This module is the narrow door: it
8
+ // provides `NodeRouteGuard` (the guard `@NodeRoute()` applies is instantiated
9
+ // in the module of the controller that uses it) and `NodeOwnershipService`
10
+ // (the ownership rule alone), and it fails the application at bootstrap when a
11
+ // `@NodeRoute()` controller sits outside `/api/nodes` or overlaps a reserved
12
+ // sub-path. Import it in each module that declares a node route controller.
13
+ // =============================================================================
14
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
15
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
16
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
17
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
18
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
19
+ };
20
+ var __metadata = (this && this.__metadata) || function (k, v) {
21
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.NodeRouteModule = void 0;
25
+ exports.findNodeRoutePlacementProblems = findNodeRoutePlacementProblems;
26
+ const common_1 = require("@nestjs/common");
27
+ const core_1 = require("@nestjs/core");
28
+ const index_1 = require("../identity/index");
29
+ const node_route_options_1 = require("./node-route.options");
30
+ const node_route_paths_1 = require("./node-route.paths");
31
+ const node_ownership_1 = require("./node-ownership");
32
+ const node_route_guard_1 = require("./node-route.guard");
33
+ /**
34
+ * The problems with the `@NodeRoute()` controllers given, one message each.
35
+ *
36
+ * @param controllers - controller classes.
37
+ * @returns the violations; empty when every node route is placed correctly.
38
+ *
39
+ * @stability experimental
40
+ */
41
+ function findNodeRoutePlacementProblems(controllers) {
42
+ const problems = [];
43
+ for (const controller of controllers) {
44
+ const classDeclared = Reflect.getMetadata(node_route_options_1.NODE_ROUTE_METADATA, controller) !== undefined;
45
+ for (const route of (0, node_route_paths_1.controllerRoutes)(controller)) {
46
+ const handler = controller.prototype[route.handler];
47
+ if (!classDeclared && Reflect.getMetadata(node_route_options_1.NODE_ROUTE_METADATA, handler) === undefined)
48
+ continue;
49
+ if (route.nodeSegments === null) {
50
+ problems.push(`${route.id} is a @NodeRoute() but its path "/${route.path}" is not under ${index_1.NODE_ROUTE_PREFIX}.`);
51
+ continue;
52
+ }
53
+ const reserved = (0, node_route_paths_1.reservedNodeSubpathOverlap)(route.nodeSegments);
54
+ if (reserved !== null) {
55
+ problems.push(`${route.id} (${index_1.NODE_ROUTE_PREFIX}/${route.nodeSegments.join('/')}) overlaps the platform-reserved sub-path "${reserved}".`);
56
+ }
57
+ }
58
+ }
59
+ return problems;
60
+ }
61
+ let NodeRoutePlacementCheck = class NodeRoutePlacementCheck {
62
+ discovery;
63
+ constructor(discovery) {
64
+ this.discovery = discovery;
65
+ }
66
+ onApplicationBootstrap() {
67
+ const controllers = this.discovery
68
+ .getControllers()
69
+ .map((wrapper) => wrapper.metatype)
70
+ .filter((type) => typeof type === 'function');
71
+ const problems = findNodeRoutePlacementProblems(controllers);
72
+ if (problems.length > 0) {
73
+ throw new Error(`Invalid @NodeRoute() placement:\n- ${problems.join('\n- ')}`);
74
+ }
75
+ }
76
+ };
77
+ NodeRoutePlacementCheck = __decorate([
78
+ (0, common_1.Injectable)(),
79
+ __metadata("design:paramtypes", [core_1.DiscoveryService])
80
+ ], NodeRoutePlacementCheck);
81
+ /**
82
+ * Provides and exports `NodeRouteGuard` and `NodeOwnershipService`, and runs the
83
+ * placement check at bootstrap. Import it where a `@NodeRoute()` controller is
84
+ * declared.
85
+ *
86
+ * @extensionPoint component
87
+ * @stability experimental
88
+ */
89
+ let NodeRouteModule = class NodeRouteModule {
90
+ };
91
+ exports.NodeRouteModule = NodeRouteModule;
92
+ exports.NodeRouteModule = NodeRouteModule = __decorate([
93
+ (0, common_1.Module)({
94
+ imports: [core_1.DiscoveryModule],
95
+ providers: [node_ownership_1.NodeOwnershipService, node_route_guard_1.NodeRouteGuard, NodeRoutePlacementCheck],
96
+ exports: [node_ownership_1.NodeOwnershipService, node_route_guard_1.NodeRouteGuard],
97
+ })
98
+ ], NodeRouteModule);
99
+ //# sourceMappingURL=node-route.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-route.module.js","sourceRoot":"","sources":["../../src/nodes/node-route.module.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,qEAAqE;AACrE,gFAAgF;AAChF,EAAE;AACF,4EAA4E;AAC5E,6EAA6E;AAC7E,8EAA8E;AAC9E,2EAA2E;AAC3E,+EAA+E;AAC/E,6EAA6E;AAC7E,4EAA4E;AAC5E,gFAAgF;;;;;;;;;;;;AAoBhF,wEAkBC;AApCD,2CAA4E;AAC5E,uCAAiE;AAEjE,6CAAsD;AACtD,6DAA2D;AAC3D,yDAAkF;AAClF,qDAAwD;AACxD,yDAAoD;AAGpD;;;;;;;GAOG;AACH,SAAgB,8BAA8B,CAAC,WAAyC;IACtF,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,MAAM,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,wCAAmB,EAAE,UAAU,CAAC,KAAK,SAAS,CAAC;QACzF,KAAK,MAAM,KAAK,IAAI,IAAA,mCAAgB,EAAC,UAAU,CAAC,EAAE,CAAC;YACjD,MAAM,OAAO,GAAI,UAAU,CAAC,SAAqC,CAAC,KAAK,CAAC,OAAO,CAAW,CAAC;YAC3F,IAAI,CAAC,aAAa,IAAI,OAAO,CAAC,WAAW,CAAC,wCAAmB,EAAE,OAAO,CAAC,KAAK,SAAS;gBAAE,SAAS;YAChG,IAAI,KAAK,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;gBAChC,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,EAAE,qCAAqC,KAAK,CAAC,IAAI,kBAAkB,yBAAiB,GAAG,CAAC,CAAC;gBAChH,SAAS;YACX,CAAC;YACD,MAAM,QAAQ,GAAG,IAAA,6CAA0B,EAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAChE,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;gBACtB,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,EAAE,KAAK,yBAAiB,IAAI,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,8CAA8C,QAAQ,IAAI,CAAC,CAAC;YAC7I,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,IACM,uBAAuB,GAD7B,MACM,uBAAuB;IACE;IAA7B,YAA6B,SAA2B;QAA3B,cAAS,GAAT,SAAS,CAAkB;IAAG,CAAC;IAE5D,sBAAsB;QACpB,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS;aAC/B,cAAc,EAAE;aAChB,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAgC,CAAC;aAC1D,MAAM,CAAC,CAAC,IAAI,EAAyB,EAAE,CAAC,OAAO,IAAI,KAAK,UAAU,CAAC,CAAC;QACvE,MAAM,QAAQ,GAAG,8BAA8B,CAAC,WAAW,CAAC,CAAC;QAC7D,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,sCAAsC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACjF,CAAC;IACH,CAAC;CACF,CAAA;AAbK,uBAAuB;IAD5B,IAAA,mBAAU,GAAE;qCAE6B,uBAAgB;GADpD,uBAAuB,CAa5B;AAED;;;;;;;GAOG;AAMI,IAAM,eAAe,GAArB,MAAM,eAAe;CAAG,CAAA;AAAlB,0CAAe;0BAAf,eAAe;IAL3B,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,sBAAe,CAAC;QAC1B,SAAS,EAAE,CAAC,qCAAoB,EAAE,iCAAc,EAAE,uBAAuB,CAAC;QAC1E,OAAO,EAAE,CAAC,qCAAoB,EAAE,iCAAc,CAAC;KAChD,CAAC;GACW,eAAe,CAAG"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * The credential kinds a node route can admit: `nod` (a worker-node
3
+ * credential), `pat` (a personal access token) and `jwt` (a session token).
4
+ *
5
+ * @stability stable
6
+ */
7
+ export type NodeRouteCredential = 'nod' | 'pat' | 'jwt';
8
+ /**
9
+ * Options of {@link NodeRoute}.
10
+ *
11
+ * @stability stable
12
+ */
13
+ export interface NodeRouteOptions {
14
+ /**
15
+ * Credential kinds admitted. Default `['nod', 'pat', 'jwt']`, as on the
16
+ * platform's own node routes. `['nod']` makes the route node-only: a human's
17
+ * PAT or session is refused with 403.
18
+ */
19
+ credentials?: ReadonlyArray<NodeRouteCredential>;
20
+ /**
21
+ * The route parameter holding the node id; node ownership is enforced before
22
+ * the handler runs. Default `'id'`. `false` for a route that names no node
23
+ * (it then has no `CurrentNode()`).
24
+ */
25
+ nodeParam?: string | false;
26
+ /** Permissions required, as `@Auth({ permissions })`. Default `['nodes:write']`, the platform node plane's. */
27
+ permissions?: string[];
28
+ }
29
+ /**
30
+ * The options of a node route with the defaults applied.
31
+ *
32
+ * @stability experimental
33
+ */
34
+ export interface ResolvedNodeRouteOptions {
35
+ /** The admitted credential kinds. */
36
+ readonly credentials: ReadonlyArray<NodeRouteCredential>;
37
+ /** The route parameter holding the node id, or `false`. */
38
+ readonly nodeParam: string | false;
39
+ /** The permissions required. */
40
+ readonly permissions: readonly string[];
41
+ }
42
+ /**
43
+ * Metadata key under which {@link NodeRoute} records its resolved options.
44
+ *
45
+ * @stability experimental
46
+ */
47
+ export declare const NODE_ROUTE_METADATA = "platform:node-route";
48
+ /** The default admitted credential kinds. */
49
+ export declare const DEFAULT_NODE_ROUTE_CREDENTIALS: ReadonlyArray<NodeRouteCredential>;
50
+ /**
51
+ * Resolves the options a route declared against the defaults.
52
+ *
53
+ * @param options - what was passed to {@link NodeRoute}.
54
+ * @returns the effective options.
55
+ *
56
+ * @stability experimental
57
+ */
58
+ export declare function resolveNodeRouteOptions(options?: NodeRouteOptions): ResolvedNodeRouteOptions;
59
+ //# sourceMappingURL=node-route.options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-route.options.d.ts","sourceRoot":"","sources":["../../src/nodes/node-route.options.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAExD;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,WAAW,CAAC,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IACjD;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC3B,+GAA+G;IAC/G,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,qCAAqC;IACrC,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IACzD,2DAA2D;IAC3D,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,KAAK,CAAC;IACnC,gCAAgC;IAChC,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,wBAAwB,CAAC;AAEzD,6CAA6C;AAC7C,eAAO,MAAM,8BAA8B,EAAE,aAAa,CAAC,mBAAmB,CAAwC,CAAC;AAEvH;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,gBAAqB,GAAG,wBAAwB,CAMhG"}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_NODE_ROUTE_CREDENTIALS = exports.NODE_ROUTE_METADATA = void 0;
4
+ exports.resolveNodeRouteOptions = resolveNodeRouteOptions;
5
+ const nodes_permissions_1 = require("./nodes.permissions");
6
+ /**
7
+ * Metadata key under which {@link NodeRoute} records its resolved options.
8
+ *
9
+ * @stability experimental
10
+ */
11
+ exports.NODE_ROUTE_METADATA = 'platform:node-route';
12
+ /** The default admitted credential kinds. */
13
+ exports.DEFAULT_NODE_ROUTE_CREDENTIALS = Object.freeze(['nod', 'pat', 'jwt']);
14
+ /**
15
+ * Resolves the options a route declared against the defaults.
16
+ *
17
+ * @param options - what was passed to {@link NodeRoute}.
18
+ * @returns the effective options.
19
+ *
20
+ * @stability experimental
21
+ */
22
+ function resolveNodeRouteOptions(options = {}) {
23
+ return {
24
+ credentials: options.credentials && options.credentials.length > 0 ? [...options.credentials] : exports.DEFAULT_NODE_ROUTE_CREDENTIALS,
25
+ nodeParam: options.nodeParam === undefined ? 'id' : options.nodeParam,
26
+ permissions: options.permissions ?? [nodes_permissions_1.NODES_PERMISSIONS.NODES_WRITE.id],
27
+ };
28
+ }
29
+ //# sourceMappingURL=node-route.options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-route.options.js","sourceRoot":"","sources":["../../src/nodes/node-route.options.ts"],"names":[],"mappings":";;;AAgEA,0DAMC;AAtED,2DAAwD;AA8CxD;;;;GAIG;AACU,QAAA,mBAAmB,GAAG,qBAAqB,CAAC;AAEzD,6CAA6C;AAChC,QAAA,8BAA8B,GAAuC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAEvH;;;;;;;GAOG;AACH,SAAgB,uBAAuB,CAAC,UAA4B,EAAE;IACpE,OAAO;QACL,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,sCAA8B;QAC9H,SAAS,EAAE,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS;QACrE,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,CAAC,qCAAiB,CAAC,WAAW,CAAC,EAAE,CAAC;KACvE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,47 @@
1
+ import type { Type } from '@nestjs/common';
2
+ /**
3
+ * The sub-paths of `/api/nodes` the platform owns, relative to the collection,
4
+ * with `:param` for a path parameter. `''` is the collection itself; a trailing
5
+ * `/*` reserves everything beneath. A `@NodeRoute()` route that overlaps one
6
+ * (a parameter overlaps a literal, the HTTP method is ignored) fails at
7
+ * bootstrap and in the `nodes` conformance suite. Mount an app feature on a
8
+ * sub-path NOT listed here, for example `nodes/:id/<feature>/...`.
9
+ *
10
+ * @stability stable
11
+ */
12
+ export declare const RESERVED_NODE_SUBPATHS: readonly string[];
13
+ /**
14
+ * One route of a controller, as the node-route checks see it.
15
+ *
16
+ * @stability experimental
17
+ */
18
+ export interface NodeControllerRoute {
19
+ /** `Controller#handler`. */
20
+ readonly id: string;
21
+ /** The handler's method name. */
22
+ readonly handler: string;
23
+ /** The full path without the global prefix, for example `nodes/:id/backup/changes`. */
24
+ readonly path: string;
25
+ /** The segments of `path` after the `nodes` collection, for example `[':id', 'backup', 'changes']`; `null` when the route is not under `/api/nodes`. */
26
+ readonly nodeSegments: readonly string[] | null;
27
+ }
28
+ /**
29
+ * Every route of `controller` with its full path. A leading `api` segment (the
30
+ * global prefix) is dropped, so `api/nodes/x` and `nodes/x` read the same.
31
+ *
32
+ * @param controller - a controller class.
33
+ * @returns one entry per handler per declared path.
34
+ *
35
+ * @stability experimental
36
+ */
37
+ export declare function controllerRoutes(controller: Type<unknown>): NodeControllerRoute[];
38
+ /**
39
+ * The reserved sub-path a route overlaps, or `null`.
40
+ *
41
+ * @param nodeSegments - the route's segments after `nodes`.
42
+ * @returns the entry of {@link RESERVED_NODE_SUBPATHS} it collides with.
43
+ *
44
+ * @stability stable
45
+ */
46
+ export declare function reservedNodeSubpathOverlap(nodeSegments: readonly string[]): string | null;
47
+ //# sourceMappingURL=node-route.paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-route.paths.d.ts","sourceRoot":"","sources":["../../src/nodes/node-route.paths.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAK3C;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,EAYlD,CAAC;AAEH;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,iCAAiC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,uFAAuF;IACvF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,wJAAwJ;IACxJ,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;CACjD;AAeD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,mBAAmB,EAAE,CAyBjF;AAmBD;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAUzF"}