@decohere/scaffold 0.0.1-dev.88 → 0.0.1-dev.90

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 (37) hide show
  1. package/commonjs/src/auth0-configure.action.js +30 -0
  2. package/commonjs/src/auth0-configure.command.js +26 -0
  3. package/commonjs/src/auth0-login.action.js +30 -0
  4. package/commonjs/src/auth0-login.command.js +25 -0
  5. package/commonjs/src/auth0.command.js +24 -0
  6. package/commonjs/src/auth0.module.js +30 -0
  7. package/commonjs/src/index.js +13 -1
  8. package/commonjs/src/program.js +10 -1
  9. package/commonjs/src/webapi/auth0-commands.js +252 -0
  10. package/commonjs/src/webapi/authorize-scopes.js +81 -0
  11. package/commonjs/src/webapi/features/auth.feature.js +3 -30
  12. package/commonjs/src/webapi/features/auth0-cli.js +41 -2
  13. package/commonjs/src/webapi/workspace-readme.js +2 -2
  14. package/es6/src/auth0-configure.action.js +20 -0
  15. package/es6/src/auth0-configure.command.js +16 -0
  16. package/es6/src/auth0-login.action.js +20 -0
  17. package/es6/src/auth0-login.command.js +15 -0
  18. package/es6/src/auth0.command.js +14 -0
  19. package/es6/src/auth0.module.js +20 -0
  20. package/es6/src/index.js +4 -1
  21. package/es6/src/program.js +10 -1
  22. package/es6/src/webapi/auth0-commands.js +187 -0
  23. package/es6/src/webapi/authorize-scopes.js +57 -0
  24. package/es6/src/webapi/features/auth.feature.js +3 -30
  25. package/es6/src/webapi/features/auth0-cli.js +36 -3
  26. package/es6/src/webapi/workspace-readme.js +2 -2
  27. package/package.json +3 -3
  28. package/types/src/auth0-configure.action.d.ts +7 -0
  29. package/types/src/auth0-configure.command.d.ts +6 -0
  30. package/types/src/auth0-login.action.d.ts +4 -0
  31. package/types/src/auth0-login.command.d.ts +6 -0
  32. package/types/src/auth0.command.d.ts +6 -0
  33. package/types/src/auth0.module.d.ts +18 -0
  34. package/types/src/index.d.ts +4 -0
  35. package/types/src/webapi/auth0-commands.d.ts +11 -0
  36. package/types/src/webapi/authorize-scopes.d.ts +7 -0
  37. package/types/src/webapi/features/auth0-cli.d.ts +4 -0
@@ -0,0 +1,20 @@
1
+ function _ts_decorate(decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ 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;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ }
7
+ import { injectable } from "@decohere/crucible/decorators";
8
+ import { ActionResponse } from "@decohere/nexus/cli";
9
+ import { runAuth0Login } from "./webapi/auth0-commands.js";
10
+ export class Auth0LoginAction {
11
+ async run() {
12
+ runAuth0Login();
13
+ return ActionResponse.Success("login");
14
+ }
15
+ }
16
+ Auth0LoginAction = _ts_decorate([
17
+ injectable()
18
+ ], Auth0LoginAction);
19
+
20
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjYWZmb2xkL3NyYy9hdXRoMC1sb2dpbi5hY3Rpb24udHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW5qZWN0YWJsZSB9IGZyb20gXCJAZGVjb2hlcmUvY3J1Y2libGUvZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgdHlwZSBBY3Rpb24sIEFjdGlvblJlc3BvbnNlIH0gZnJvbSBcIkBkZWNvaGVyZS9uZXh1cy9jbGlcIjtcbmltcG9ydCB7IHJ1bkF1dGgwTG9naW4gfSBmcm9tIFwiLi93ZWJhcGkvYXV0aDAtY29tbWFuZHMuanNcIjtcblxuQGluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEF1dGgwTG9naW5BY3Rpb24gaW1wbGVtZW50cyBBY3Rpb24ge1xuXHRwdWJsaWMgYXN5bmMgcnVuKCk6IFByb21pc2U8QWN0aW9uUmVzcG9uc2U+IHtcblx0XHRydW5BdXRoMExvZ2luKCk7XG5cdFx0cmV0dXJuIEFjdGlvblJlc3BvbnNlLlN1Y2Nlc3MoXCJsb2dpblwiKTtcblx0fVxufVxuIl0sIm5hbWVzIjpbImluamVjdGFibGUiLCJBY3Rpb25SZXNwb25zZSIsInJ1bkF1dGgwTG9naW4iLCJBdXRoMExvZ2luQWN0aW9uIiwicnVuIiwiU3VjY2VzcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsU0FBU0EsVUFBVSxRQUFRLGdDQUFnQztBQUMzRCxTQUFzQkMsY0FBYyxRQUFRLHNCQUFzQjtBQUNsRSxTQUFTQyxhQUFhLFFBQVEsNkJBQTZCO0FBRzNELE9BQU8sTUFBTUM7SUFDWixNQUFhQyxNQUErQjtRQUMzQ0Y7UUFDQSxPQUFPRCxlQUFlSSxPQUFPLENBQUM7SUFDL0I7QUFDRCJ9
@@ -0,0 +1,15 @@
1
+ import { DecohereCommand } from "@decohere/nexus/cli";
2
+ import { Auth0LoginAction } from "./auth0-login.action.js";
3
+ export class Auth0LoginCommand extends DecohereCommand {
4
+ get actions() {
5
+ return [
6
+ Auth0LoginAction
7
+ ];
8
+ }
9
+ constructor(name){
10
+ super(name);
11
+ this.description("Authenticate the Auth0 CLI (device URL; tokens persist on the host)");
12
+ }
13
+ }
14
+
15
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjYWZmb2xkL3NyYy9hdXRoMC1sb2dpbi5jb21tYW5kLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERlY29oZXJlQ29tbWFuZCB9IGZyb20gXCJAZGVjb2hlcmUvbmV4dXMvY2xpXCI7XG5pbXBvcnQgeyBBdXRoMExvZ2luQWN0aW9uIH0gZnJvbSBcIi4vYXV0aDAtbG9naW4uYWN0aW9uLmpzXCI7XG5cbmV4cG9ydCBjbGFzcyBBdXRoMExvZ2luQ29tbWFuZCBleHRlbmRzIERlY29oZXJlQ29tbWFuZCB7XG5cdHB1YmxpYyBvdmVycmlkZSBnZXQgYWN0aW9ucygpIHtcblx0XHRyZXR1cm4gW0F1dGgwTG9naW5BY3Rpb25dO1xuXHR9XG5cblx0cHVibGljIGNvbnN0cnVjdG9yKG5hbWU6IHN0cmluZykge1xuXHRcdHN1cGVyKG5hbWUpO1xuXHRcdHRoaXMuZGVzY3JpcHRpb24oXCJBdXRoZW50aWNhdGUgdGhlIEF1dGgwIENMSSAoZGV2aWNlIFVSTDsgdG9rZW5zIHBlcnNpc3Qgb24gdGhlIGhvc3QpXCIpO1xuXHR9XG59XG4iXSwibmFtZXMiOlsiRGVjb2hlcmVDb21tYW5kIiwiQXV0aDBMb2dpbkFjdGlvbiIsIkF1dGgwTG9naW5Db21tYW5kIiwiYWN0aW9ucyIsIm5hbWUiLCJkZXNjcmlwdGlvbiJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsZUFBZSxRQUFRLHNCQUFzQjtBQUN0RCxTQUFTQyxnQkFBZ0IsUUFBUSwwQkFBMEI7QUFFM0QsT0FBTyxNQUFNQywwQkFBMEJGO0lBQ3RDLElBQW9CRyxVQUFVO1FBQzdCLE9BQU87WUFBQ0Y7U0FBaUI7SUFDMUI7SUFFQSxZQUFtQkcsSUFBWSxDQUFFO1FBQ2hDLEtBQUssQ0FBQ0E7UUFDTixJQUFJLENBQUNDLFdBQVcsQ0FBQztJQUNsQjtBQUNEIn0=
@@ -0,0 +1,14 @@
1
+ import { DecohereCommand } from "@decohere/nexus/cli";
2
+ export class Auth0Command extends DecohereCommand {
3
+ constructor(commands, handler){
4
+ super(Auth0Command);
5
+ this.description("Log in to Auth0 and update a scaffolded client");
6
+ this.exitOverride();
7
+ this.registerSubcommand(commands, handler);
8
+ }
9
+ run(_actions, _options) {
10
+ return this.help();
11
+ }
12
+ }
13
+
14
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjYWZmb2xkL3NyYy9hdXRoMC5jb21tYW5kLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgQWN0aW9ucyB9IGZyb20gXCJAZGVjb2hlcmUvbmV4dXMvY2xpXCI7XG5pbXBvcnQge1xuXHR0eXBlIENvbW1hbmRIYW5kbGVyLFxuXHR0eXBlIENvbW1hbmRSZXNwb25zZSxcblx0dHlwZSBDb21tYW5kVHlwZSxcblx0RGVjb2hlcmVDb21tYW5kLFxufSBmcm9tIFwiQGRlY29oZXJlL25leHVzL2NsaVwiO1xuXG5leHBvcnQgY2xhc3MgQXV0aDBDb21tYW5kIGV4dGVuZHMgRGVjb2hlcmVDb21tYW5kIHtcblx0cHVibGljIGNvbnN0cnVjdG9yKGNvbW1hbmRzOiBSZWNvcmQ8c3RyaW5nLCBDb21tYW5kVHlwZT4sIGhhbmRsZXI6IENvbW1hbmRIYW5kbGVyKSB7XG5cdFx0c3VwZXIoQXV0aDBDb21tYW5kKTtcblx0XHR0aGlzLmRlc2NyaXB0aW9uKFwiTG9nIGluIHRvIEF1dGgwIGFuZCB1cGRhdGUgYSBzY2FmZm9sZGVkIGNsaWVudFwiKTtcblx0XHR0aGlzLmV4aXRPdmVycmlkZSgpO1xuXHRcdHRoaXMucmVnaXN0ZXJTdWJjb21tYW5kKGNvbW1hbmRzLCBoYW5kbGVyKTtcblx0fVxuXG5cdHB1YmxpYyBydW4oX2FjdGlvbnM6IEFjdGlvbnMsIF9vcHRpb25zOiBuZXZlcik6IFByb21pc2U8Q29tbWFuZFJlc3BvbnNlPiB7XG5cdFx0cmV0dXJuIHRoaXMuaGVscCgpO1xuXHR9XG59XG4iXSwibmFtZXMiOlsiRGVjb2hlcmVDb21tYW5kIiwiQXV0aDBDb21tYW5kIiwiY29tbWFuZHMiLCJoYW5kbGVyIiwiZGVzY3JpcHRpb24iLCJleGl0T3ZlcnJpZGUiLCJyZWdpc3RlclN1YmNvbW1hbmQiLCJydW4iLCJfYWN0aW9ucyIsIl9vcHRpb25zIiwiaGVscCJdLCJtYXBwaW5ncyI6IkFBQ0EsU0FJQ0EsZUFBZSxRQUNULHNCQUFzQjtBQUU3QixPQUFPLE1BQU1DLHFCQUFxQkQ7SUFDakMsWUFBbUJFLFFBQXFDLEVBQUVDLE9BQXVCLENBQUU7UUFDbEYsS0FBSyxDQUFDRjtRQUNOLElBQUksQ0FBQ0csV0FBVyxDQUFDO1FBQ2pCLElBQUksQ0FBQ0MsWUFBWTtRQUNqQixJQUFJLENBQUNDLGtCQUFrQixDQUFDSixVQUFVQztJQUNuQztJQUVPSSxJQUFJQyxRQUFpQixFQUFFQyxRQUFlLEVBQTRCO1FBQ3hFLE9BQU8sSUFBSSxDQUFDQyxJQUFJO0lBQ2pCO0FBQ0QifQ==
@@ -0,0 +1,20 @@
1
+ import { ModuleManifest } from "@decohere/nexus/cli";
2
+ import { Auth0Command } from "./auth0.command.js";
3
+ import { Auth0ConfigureAction } from "./auth0-configure.action.js";
4
+ import { Auth0ConfigureCommand } from "./auth0-configure.command.js";
5
+ import { Auth0LoginAction } from "./auth0-login.action.js";
6
+ import { Auth0LoginCommand } from "./auth0-login.command.js";
7
+ export class Auth0Module extends ModuleManifest {
8
+ id = "auth0";
9
+ command = Auth0Command;
10
+ commands = {
11
+ login: Auth0LoginCommand,
12
+ configure: Auth0ConfigureCommand
13
+ };
14
+ actions = {
15
+ login: Auth0LoginAction,
16
+ configure: Auth0ConfigureAction
17
+ };
18
+ }
19
+
20
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjYWZmb2xkL3NyYy9hdXRoMC5tb2R1bGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTW9kdWxlTWFuaWZlc3QgfSBmcm9tIFwiQGRlY29oZXJlL25leHVzL2NsaVwiO1xuaW1wb3J0IHsgQXV0aDBDb21tYW5kIH0gZnJvbSBcIi4vYXV0aDAuY29tbWFuZC5qc1wiO1xuaW1wb3J0IHsgQXV0aDBDb25maWd1cmVBY3Rpb24gfSBmcm9tIFwiLi9hdXRoMC1jb25maWd1cmUuYWN0aW9uLmpzXCI7XG5pbXBvcnQgeyBBdXRoMENvbmZpZ3VyZUNvbW1hbmQgfSBmcm9tIFwiLi9hdXRoMC1jb25maWd1cmUuY29tbWFuZC5qc1wiO1xuaW1wb3J0IHsgQXV0aDBMb2dpbkFjdGlvbiB9IGZyb20gXCIuL2F1dGgwLWxvZ2luLmFjdGlvbi5qc1wiO1xuaW1wb3J0IHsgQXV0aDBMb2dpbkNvbW1hbmQgfSBmcm9tIFwiLi9hdXRoMC1sb2dpbi5jb21tYW5kLmpzXCI7XG5cbmV4cG9ydCBjbGFzcyBBdXRoME1vZHVsZSBleHRlbmRzIE1vZHVsZU1hbmlmZXN0IHtcblx0cHVibGljIHJlYWRvbmx5IGlkID0gXCJhdXRoMFwiO1xuXHRwdWJsaWMgcmVhZG9ubHkgY29tbWFuZCA9IEF1dGgwQ29tbWFuZDtcblx0cHVibGljIHJlYWRvbmx5IGNvbW1hbmRzID0geyBsb2dpbjogQXV0aDBMb2dpbkNvbW1hbmQsIGNvbmZpZ3VyZTogQXV0aDBDb25maWd1cmVDb21tYW5kIH07XG5cdHB1YmxpYyByZWFkb25seSBhY3Rpb25zID0geyBsb2dpbjogQXV0aDBMb2dpbkFjdGlvbiwgY29uZmlndXJlOiBBdXRoMENvbmZpZ3VyZUFjdGlvbiB9O1xufVxuIl0sIm5hbWVzIjpbIk1vZHVsZU1hbmlmZXN0IiwiQXV0aDBDb21tYW5kIiwiQXV0aDBDb25maWd1cmVBY3Rpb24iLCJBdXRoMENvbmZpZ3VyZUNvbW1hbmQiLCJBdXRoMExvZ2luQWN0aW9uIiwiQXV0aDBMb2dpbkNvbW1hbmQiLCJBdXRoME1vZHVsZSIsImlkIiwiY29tbWFuZCIsImNvbW1hbmRzIiwibG9naW4iLCJjb25maWd1cmUiLCJhY3Rpb25zIl0sIm1hcHBpbmdzIjoiQUFBQSxTQUFTQSxjQUFjLFFBQVEsc0JBQXNCO0FBQ3JELFNBQVNDLFlBQVksUUFBUSxxQkFBcUI7QUFDbEQsU0FBU0Msb0JBQW9CLFFBQVEsOEJBQThCO0FBQ25FLFNBQVNDLHFCQUFxQixRQUFRLCtCQUErQjtBQUNyRSxTQUFTQyxnQkFBZ0IsUUFBUSwwQkFBMEI7QUFDM0QsU0FBU0MsaUJBQWlCLFFBQVEsMkJBQTJCO0FBRTdELE9BQU8sTUFBTUMsb0JBQW9CTjtJQUNoQk8sS0FBSyxRQUFRO0lBQ2JDLFVBQVVQLGFBQWE7SUFDdkJRLFdBQVc7UUFBRUMsT0FBT0w7UUFBbUJNLFdBQVdSO0lBQXNCLEVBQUU7SUFDMUVTLFVBQVU7UUFBRUYsT0FBT047UUFBa0JPLFdBQVdUO0lBQXFCLEVBQUU7QUFDeEYifQ==
package/es6/src/index.js CHANGED
@@ -1,8 +1,11 @@
1
1
  export { AddModule } from "./add.module.js";
2
2
  export { AddApiAction } from "./add-api.action.js";
3
+ export { Auth0Module } from "./auth0.module.js";
4
+ export { Auth0ConfigureAction } from "./auth0-configure.action.js";
5
+ export { Auth0LoginAction } from "./auth0-login.action.js";
3
6
  export { CreateModule } from "./create.module.js";
4
7
  export { runCli } from "./program.js";
5
8
  export { scaffoldApi } from "./webapi/create-api.js";
6
9
  export { WebapiAction } from "./webapi.action.js";
7
10
 
8
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjYWZmb2xkL3NyYy9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgeyBBZGRNb2R1bGUgfSBmcm9tIFwiLi9hZGQubW9kdWxlLmpzXCI7XG5leHBvcnQgdHlwZSB7IEFkZEFwaU9wdGlvbnMgfSBmcm9tIFwiLi9hZGQtYXBpLmFjdGlvbi5qc1wiO1xuZXhwb3J0IHsgQWRkQXBpQWN0aW9uIH0gZnJvbSBcIi4vYWRkLWFwaS5hY3Rpb24uanNcIjtcbmV4cG9ydCB7IENyZWF0ZU1vZHVsZSB9IGZyb20gXCIuL2NyZWF0ZS5tb2R1bGUuanNcIjtcbmV4cG9ydCB7IHJ1bkNsaSB9IGZyb20gXCIuL3Byb2dyYW0uanNcIjtcbmV4cG9ydCB0eXBlIHsgQXBpT3B0aW9ucyB9IGZyb20gXCIuL3dlYmFwaS9jcmVhdGUtYXBpLmpzXCI7XG5leHBvcnQgeyBzY2FmZm9sZEFwaSB9IGZyb20gXCIuL3dlYmFwaS9jcmVhdGUtYXBpLmpzXCI7XG5leHBvcnQgdHlwZSB7IFdlYmFwaU9wdGlvbnMgfSBmcm9tIFwiLi93ZWJhcGkuYWN0aW9uLmpzXCI7XG5leHBvcnQgeyBXZWJhcGlBY3Rpb24gfSBmcm9tIFwiLi93ZWJhcGkuYWN0aW9uLmpzXCI7XG4iXSwibmFtZXMiOlsiQWRkTW9kdWxlIiwiQWRkQXBpQWN0aW9uIiwiQ3JlYXRlTW9kdWxlIiwicnVuQ2xpIiwic2NhZmZvbGRBcGkiLCJXZWJhcGlBY3Rpb24iXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLFNBQVMsUUFBUSxrQkFBa0I7QUFFNUMsU0FBU0MsWUFBWSxRQUFRLHNCQUFzQjtBQUNuRCxTQUFTQyxZQUFZLFFBQVEscUJBQXFCO0FBQ2xELFNBQVNDLE1BQU0sUUFBUSxlQUFlO0FBRXRDLFNBQVNDLFdBQVcsUUFBUSx5QkFBeUI7QUFFckQsU0FBU0MsWUFBWSxRQUFRLHFCQUFxQiJ9
11
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjYWZmb2xkL3NyYy9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgeyBBZGRNb2R1bGUgfSBmcm9tIFwiLi9hZGQubW9kdWxlLmpzXCI7XG5leHBvcnQgdHlwZSB7IEFkZEFwaU9wdGlvbnMgfSBmcm9tIFwiLi9hZGQtYXBpLmFjdGlvbi5qc1wiO1xuZXhwb3J0IHsgQWRkQXBpQWN0aW9uIH0gZnJvbSBcIi4vYWRkLWFwaS5hY3Rpb24uanNcIjtcbmV4cG9ydCB7IEF1dGgwTW9kdWxlIH0gZnJvbSBcIi4vYXV0aDAubW9kdWxlLmpzXCI7XG5leHBvcnQgdHlwZSB7IEF1dGgwQ29uZmlndXJlT3B0aW9ucyB9IGZyb20gXCIuL2F1dGgwLWNvbmZpZ3VyZS5hY3Rpb24uanNcIjtcbmV4cG9ydCB7IEF1dGgwQ29uZmlndXJlQWN0aW9uIH0gZnJvbSBcIi4vYXV0aDAtY29uZmlndXJlLmFjdGlvbi5qc1wiO1xuZXhwb3J0IHsgQXV0aDBMb2dpbkFjdGlvbiB9IGZyb20gXCIuL2F1dGgwLWxvZ2luLmFjdGlvbi5qc1wiO1xuZXhwb3J0IHsgQ3JlYXRlTW9kdWxlIH0gZnJvbSBcIi4vY3JlYXRlLm1vZHVsZS5qc1wiO1xuZXhwb3J0IHsgcnVuQ2xpIH0gZnJvbSBcIi4vcHJvZ3JhbS5qc1wiO1xuZXhwb3J0IHR5cGUgeyBBcGlPcHRpb25zIH0gZnJvbSBcIi4vd2ViYXBpL2NyZWF0ZS1hcGkuanNcIjtcbmV4cG9ydCB7IHNjYWZmb2xkQXBpIH0gZnJvbSBcIi4vd2ViYXBpL2NyZWF0ZS1hcGkuanNcIjtcbmV4cG9ydCB0eXBlIHsgV2ViYXBpT3B0aW9ucyB9IGZyb20gXCIuL3dlYmFwaS5hY3Rpb24uanNcIjtcbmV4cG9ydCB7IFdlYmFwaUFjdGlvbiB9IGZyb20gXCIuL3dlYmFwaS5hY3Rpb24uanNcIjtcbiJdLCJuYW1lcyI6WyJBZGRNb2R1bGUiLCJBZGRBcGlBY3Rpb24iLCJBdXRoME1vZHVsZSIsIkF1dGgwQ29uZmlndXJlQWN0aW9uIiwiQXV0aDBMb2dpbkFjdGlvbiIsIkNyZWF0ZU1vZHVsZSIsInJ1bkNsaSIsInNjYWZmb2xkQXBpIiwiV2ViYXBpQWN0aW9uIl0sIm1hcHBpbmdzIjoiQUFBQSxTQUFTQSxTQUFTLFFBQVEsa0JBQWtCO0FBRTVDLFNBQVNDLFlBQVksUUFBUSxzQkFBc0I7QUFDbkQsU0FBU0MsV0FBVyxRQUFRLG9CQUFvQjtBQUVoRCxTQUFTQyxvQkFBb0IsUUFBUSw4QkFBOEI7QUFDbkUsU0FBU0MsZ0JBQWdCLFFBQVEsMEJBQTBCO0FBQzNELFNBQVNDLFlBQVksUUFBUSxxQkFBcUI7QUFDbEQsU0FBU0MsTUFBTSxRQUFRLGVBQWU7QUFFdEMsU0FBU0MsV0FBVyxRQUFRLHlCQUF5QjtBQUVyRCxTQUFTQyxZQUFZLFFBQVEscUJBQXFCIn0=
@@ -1,5 +1,6 @@
1
1
  import { Command, CommanderError } from "commander";
2
2
  import { CreateCliError } from "./webapi/api-name.js";
3
+ import { runAuth0Configure, runAuth0Login } from "./webapi/auth0-commands.js";
3
4
  import { addWebapiFeatureOptions, collectName, runScaffoldApi, toApiOptions } from "./webapi/cli-options.js";
4
5
  export function createProgram() {
5
6
  const program = new Command();
@@ -17,6 +18,14 @@ export function createProgram() {
17
18
  add: true
18
19
  }));
19
20
  });
21
+ const auth0 = program.command("auth0").description("Log in to Auth0 and update a scaffolded client");
22
+ auth0.command("login").description("Authenticate the Auth0 CLI (device URL; tokens persist on the host)").action(()=>{
23
+ runAuth0Login();
24
+ });
25
+ auth0.command("configure").description("Update Auth0 API permissions and Postman SPA from @Authorize in this workspace").action((_opts, cmd)=>{
26
+ const d = cmd.optsWithGlobals().d;
27
+ runAuth0Configure(typeof d === "string" ? d : ".");
28
+ });
20
29
  return program;
21
30
  }
22
31
  export async function runCli(argv = process.argv) {
@@ -36,4 +45,4 @@ export async function runCli(argv = process.argv) {
36
45
  process.exit(process.exitCode ?? 0);
37
46
  }
38
47
 
39
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjYWZmb2xkL3NyYy9wcm9ncmFtLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1hbmQsIENvbW1hbmRlckVycm9yIH0gZnJvbSBcImNvbW1hbmRlclwiO1xuaW1wb3J0IHsgQ3JlYXRlQ2xpRXJyb3IgfSBmcm9tIFwiLi93ZWJhcGkvYXBpLW5hbWUuanNcIjtcbmltcG9ydCB7XG5cdGFkZFdlYmFwaUZlYXR1cmVPcHRpb25zLFxuXHRjb2xsZWN0TmFtZSxcblx0cnVuU2NhZmZvbGRBcGksXG5cdHRvQXBpT3B0aW9ucyxcbn0gZnJvbSBcIi4vd2ViYXBpL2NsaS1vcHRpb25zLmpzXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVQcm9ncmFtKCk6IENvbW1hbmQge1xuXHRjb25zdCBwcm9ncmFtID0gbmV3IENvbW1hbmQoKTtcblx0cHJvZ3JhbS5leGl0T3ZlcnJpZGUoKTtcblx0cHJvZ3JhbVxuXHRcdC5uYW1lKFwiZGVjb2hlcmVcIilcblx0XHQuZGVzY3JpcHRpb24oXCJEZWNvaGVyZSBDTElcIilcblx0XHQub3B0aW9uKFwiLWQgPGRpcmVjdG9yeT5cIiwgXCJUYXJnZXQgZGlyZWN0b3J5IChkZWZhdWx0OiBjdXJyZW50IGRpcmVjdG9yeSlcIiwgXCIuXCIpO1xuXG5cdGNvbnN0IGNyZWF0ZSA9IHByb2dyYW0uY29tbWFuZChcImNyZWF0ZVwiKS5kZXNjcmlwdGlvbihcIkNyZWF0ZSBhIG5ldyBEZWNvaGVyZSB3b3Jrc3BhY2VcIik7XG5cdGFkZFdlYmFwaUZlYXR1cmVPcHRpb25zKFxuXHRcdGNyZWF0ZVxuXHRcdFx0LmNvbW1hbmQoXCJ3ZWJhcGlcIilcblx0XHRcdC5hcmd1bWVudChcIltkaXJlY3RvcnldXCIsIFwiVGFyZ2V0IGRpcmVjdG9yeSAoZGVmYXVsdDogLWQgb3IgY3VycmVudCBkaXJlY3RvcnkpXCIpXG5cdFx0XHQub3B0aW9uKFxuXHRcdFx0XHRcIi0tbmFtZSA8c2x1Zz5cIixcblx0XHRcdFx0XCJBUEkgbmFtZSB1bmRlciBwcm9qZWN0cy8gKHJlcGVhdGFibGU7IGRlZmF1bHQ6IGFwaSlcIixcblx0XHRcdFx0Y29sbGVjdE5hbWUsXG5cdFx0XHRcdFtdIGFzIHN0cmluZ1tdLFxuXHRcdFx0KSxcblx0KS5hY3Rpb24oYXN5bmMgKGRpcmVjdG9yeTogc3RyaW5nIHwgdW5kZWZpbmVkLCBfb3B0czogdW5rbm93biwgY21kOiBDb21tYW5kKSA9PiB7XG5cdFx0YXdhaXQgcnVuU2NhZmZvbGRBcGkodG9BcGlPcHRpb25zKGRpcmVjdG9yeSwgY21kLm9wdHNXaXRoR2xvYmFscygpKSk7XG5cdH0pO1xuXG5cdGFkZFdlYmFwaUZlYXR1cmVPcHRpb25zKFxuXHRcdHByb2dyYW1cblx0XHRcdC5jb21tYW5kKFwiYWRkXCIpXG5cdFx0XHQuZGVzY3JpcHRpb24oXCJBZGQgdG8gYW4gZXhpc3RpbmcgRGVjb2hlcmUgd29ya3NwYWNlXCIpXG5cdFx0XHQuY29tbWFuZChcImFwaVwiKVxuXHRcdFx0LmFyZ3VtZW50KFwiPG5hbWU+XCIsIFwiQVBJIG5hbWUgdW5kZXIgcHJvamVjdHMvXCIpLFxuXHQpLmFjdGlvbihhc3luYyAobmFtZTogc3RyaW5nLCBfb3B0czogdW5rbm93biwgY21kOiBDb21tYW5kKSA9PiB7XG5cdFx0YXdhaXQgcnVuU2NhZmZvbGRBcGkoXG5cdFx0XHR0b0FwaU9wdGlvbnModW5kZWZpbmVkLCBjbWQub3B0c1dpdGhHbG9iYWxzKCksIHsgbmFtZXM6IFtuYW1lXSwgYWRkOiB0cnVlIH0pLFxuXHRcdCk7XG5cdH0pO1xuXG5cdHJldHVybiBwcm9ncmFtO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuQ2xpKGFyZ3Y6IHN0cmluZ1tdID0gcHJvY2Vzcy5hcmd2KTogUHJvbWlzZTx2b2lkPiB7XG5cdHRyeSB7XG5cdFx0YXdhaXQgY3JlYXRlUHJvZ3JhbSgpLnBhcnNlQXN5bmMoYXJndik7XG5cdH0gY2F0Y2ggKGVycikge1xuXHRcdGlmIChlcnIgaW5zdGFuY2VvZiBDb21tYW5kZXJFcnJvcikge1xuXHRcdFx0cHJvY2Vzcy5leGl0KGVyci5leGl0Q29kZSk7XG5cdFx0fVxuXHRcdGlmIChlcnIgaW5zdGFuY2VvZiBDcmVhdGVDbGlFcnJvcikge1xuXHRcdFx0Y29uc29sZS5lcnJvcihgXFxuICAke2Vyci5tZXNzYWdlfVxcbmApO1xuXHRcdFx0cHJvY2Vzcy5leGl0KDEpO1xuXHRcdH1cblx0XHRjb25zb2xlLmVycm9yKGVycik7XG5cdFx0cHJvY2Vzcy5leGl0KDEpO1xuXHR9XG5cdHByb2Nlc3MuZXhpdChwcm9jZXNzLmV4aXRDb2RlID8/IDApO1xufVxuIl0sIm5hbWVzIjpbIkNvbW1hbmQiLCJDb21tYW5kZXJFcnJvciIsIkNyZWF0ZUNsaUVycm9yIiwiYWRkV2ViYXBpRmVhdHVyZU9wdGlvbnMiLCJjb2xsZWN0TmFtZSIsInJ1blNjYWZmb2xkQXBpIiwidG9BcGlPcHRpb25zIiwiY3JlYXRlUHJvZ3JhbSIsInByb2dyYW0iLCJleGl0T3ZlcnJpZGUiLCJuYW1lIiwiZGVzY3JpcHRpb24iLCJvcHRpb24iLCJjcmVhdGUiLCJjb21tYW5kIiwiYXJndW1lbnQiLCJhY3Rpb24iLCJkaXJlY3RvcnkiLCJfb3B0cyIsImNtZCIsIm9wdHNXaXRoR2xvYmFscyIsInVuZGVmaW5lZCIsIm5hbWVzIiwiYWRkIiwicnVuQ2xpIiwiYXJndiIsInByb2Nlc3MiLCJwYXJzZUFzeW5jIiwiZXJyIiwiZXhpdCIsImV4aXRDb2RlIiwiY29uc29sZSIsImVycm9yIiwibWVzc2FnZSJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsT0FBTyxFQUFFQyxjQUFjLFFBQVEsWUFBWTtBQUNwRCxTQUFTQyxjQUFjLFFBQVEsdUJBQXVCO0FBQ3RELFNBQ0NDLHVCQUF1QixFQUN2QkMsV0FBVyxFQUNYQyxjQUFjLEVBQ2RDLFlBQVksUUFDTiwwQkFBMEI7QUFFakMsT0FBTyxTQUFTQztJQUNmLE1BQU1DLFVBQVUsSUFBSVI7SUFDcEJRLFFBQVFDLFlBQVk7SUFDcEJELFFBQ0VFLElBQUksQ0FBQyxZQUNMQyxXQUFXLENBQUMsZ0JBQ1pDLE1BQU0sQ0FBQyxrQkFBa0IsaURBQWlEO0lBRTVFLE1BQU1DLFNBQVNMLFFBQVFNLE9BQU8sQ0FBQyxVQUFVSCxXQUFXLENBQUM7SUFDckRSLHdCQUNDVSxPQUNFQyxPQUFPLENBQUMsVUFDUkMsUUFBUSxDQUFDLGVBQWUsdURBQ3hCSCxNQUFNLENBQ04saUJBQ0EsdURBQ0FSLGFBQ0EsRUFBRSxHQUVIWSxNQUFNLENBQUMsT0FBT0MsV0FBK0JDLE9BQWdCQztRQUM5RCxNQUFNZCxlQUFlQyxhQUFhVyxXQUFXRSxJQUFJQyxlQUFlO0lBQ2pFO0lBRUFqQix3QkFDQ0ssUUFDRU0sT0FBTyxDQUFDLE9BQ1JILFdBQVcsQ0FBQyx5Q0FDWkcsT0FBTyxDQUFDLE9BQ1JDLFFBQVEsQ0FBQyxVQUFVLDZCQUNwQkMsTUFBTSxDQUFDLE9BQU9OLE1BQWNRLE9BQWdCQztRQUM3QyxNQUFNZCxlQUNMQyxhQUFhZSxXQUFXRixJQUFJQyxlQUFlLElBQUk7WUFBRUUsT0FBTztnQkFBQ1o7YUFBSztZQUFFYSxLQUFLO1FBQUs7SUFFNUU7SUFFQSxPQUFPZjtBQUNSO0FBRUEsT0FBTyxlQUFlZ0IsT0FBT0MsT0FBaUJDLFFBQVFELElBQUk7SUFDekQsSUFBSTtRQUNILE1BQU1sQixnQkFBZ0JvQixVQUFVLENBQUNGO0lBQ2xDLEVBQUUsT0FBT0csS0FBSztRQUNiLElBQUlBLGVBQWUzQixnQkFBZ0I7WUFDbEN5QixRQUFRRyxJQUFJLENBQUNELElBQUlFLFFBQVE7UUFDMUI7UUFDQSxJQUFJRixlQUFlMUIsZ0JBQWdCO1lBQ2xDNkIsUUFBUUMsS0FBSyxDQUFDLENBQUMsSUFBSSxFQUFFSixJQUFJSyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ3BDUCxRQUFRRyxJQUFJLENBQUM7UUFDZDtRQUNBRSxRQUFRQyxLQUFLLENBQUNKO1FBQ2RGLFFBQVFHLElBQUksQ0FBQztJQUNkO0lBQ0FILFFBQVFHLElBQUksQ0FBQ0gsUUFBUUksUUFBUSxJQUFJO0FBQ2xDIn0=
48
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjYWZmb2xkL3NyYy9wcm9ncmFtLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1hbmQsIENvbW1hbmRlckVycm9yIH0gZnJvbSBcImNvbW1hbmRlclwiO1xuaW1wb3J0IHsgQ3JlYXRlQ2xpRXJyb3IgfSBmcm9tIFwiLi93ZWJhcGkvYXBpLW5hbWUuanNcIjtcbmltcG9ydCB7IHJ1bkF1dGgwQ29uZmlndXJlLCBydW5BdXRoMExvZ2luIH0gZnJvbSBcIi4vd2ViYXBpL2F1dGgwLWNvbW1hbmRzLmpzXCI7XG5pbXBvcnQge1xuXHRhZGRXZWJhcGlGZWF0dXJlT3B0aW9ucyxcblx0Y29sbGVjdE5hbWUsXG5cdHJ1blNjYWZmb2xkQXBpLFxuXHR0b0FwaU9wdGlvbnMsXG59IGZyb20gXCIuL3dlYmFwaS9jbGktb3B0aW9ucy5qc1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUHJvZ3JhbSgpOiBDb21tYW5kIHtcblx0Y29uc3QgcHJvZ3JhbSA9IG5ldyBDb21tYW5kKCk7XG5cdHByb2dyYW0uZXhpdE92ZXJyaWRlKCk7XG5cdHByb2dyYW1cblx0XHQubmFtZShcImRlY29oZXJlXCIpXG5cdFx0LmRlc2NyaXB0aW9uKFwiRGVjb2hlcmUgQ0xJXCIpXG5cdFx0Lm9wdGlvbihcIi1kIDxkaXJlY3Rvcnk+XCIsIFwiVGFyZ2V0IGRpcmVjdG9yeSAoZGVmYXVsdDogY3VycmVudCBkaXJlY3RvcnkpXCIsIFwiLlwiKTtcblxuXHRjb25zdCBjcmVhdGUgPSBwcm9ncmFtLmNvbW1hbmQoXCJjcmVhdGVcIikuZGVzY3JpcHRpb24oXCJDcmVhdGUgYSBuZXcgRGVjb2hlcmUgd29ya3NwYWNlXCIpO1xuXHRhZGRXZWJhcGlGZWF0dXJlT3B0aW9ucyhcblx0XHRjcmVhdGVcblx0XHRcdC5jb21tYW5kKFwid2ViYXBpXCIpXG5cdFx0XHQuYXJndW1lbnQoXCJbZGlyZWN0b3J5XVwiLCBcIlRhcmdldCBkaXJlY3RvcnkgKGRlZmF1bHQ6IC1kIG9yIGN1cnJlbnQgZGlyZWN0b3J5KVwiKVxuXHRcdFx0Lm9wdGlvbihcblx0XHRcdFx0XCItLW5hbWUgPHNsdWc+XCIsXG5cdFx0XHRcdFwiQVBJIG5hbWUgdW5kZXIgcHJvamVjdHMvIChyZXBlYXRhYmxlOyBkZWZhdWx0OiBhcGkpXCIsXG5cdFx0XHRcdGNvbGxlY3ROYW1lLFxuXHRcdFx0XHRbXSBhcyBzdHJpbmdbXSxcblx0XHRcdCksXG5cdCkuYWN0aW9uKGFzeW5jIChkaXJlY3Rvcnk6IHN0cmluZyB8IHVuZGVmaW5lZCwgX29wdHM6IHVua25vd24sIGNtZDogQ29tbWFuZCkgPT4ge1xuXHRcdGF3YWl0IHJ1blNjYWZmb2xkQXBpKHRvQXBpT3B0aW9ucyhkaXJlY3RvcnksIGNtZC5vcHRzV2l0aEdsb2JhbHMoKSkpO1xuXHR9KTtcblxuXHRhZGRXZWJhcGlGZWF0dXJlT3B0aW9ucyhcblx0XHRwcm9ncmFtXG5cdFx0XHQuY29tbWFuZChcImFkZFwiKVxuXHRcdFx0LmRlc2NyaXB0aW9uKFwiQWRkIHRvIGFuIGV4aXN0aW5nIERlY29oZXJlIHdvcmtzcGFjZVwiKVxuXHRcdFx0LmNvbW1hbmQoXCJhcGlcIilcblx0XHRcdC5hcmd1bWVudChcIjxuYW1lPlwiLCBcIkFQSSBuYW1lIHVuZGVyIHByb2plY3RzL1wiKSxcblx0KS5hY3Rpb24oYXN5bmMgKG5hbWU6IHN0cmluZywgX29wdHM6IHVua25vd24sIGNtZDogQ29tbWFuZCkgPT4ge1xuXHRcdGF3YWl0IHJ1blNjYWZmb2xkQXBpKFxuXHRcdFx0dG9BcGlPcHRpb25zKHVuZGVmaW5lZCwgY21kLm9wdHNXaXRoR2xvYmFscygpLCB7IG5hbWVzOiBbbmFtZV0sIGFkZDogdHJ1ZSB9KSxcblx0XHQpO1xuXHR9KTtcblxuXHRjb25zdCBhdXRoMCA9IHByb2dyYW1cblx0XHQuY29tbWFuZChcImF1dGgwXCIpXG5cdFx0LmRlc2NyaXB0aW9uKFwiTG9nIGluIHRvIEF1dGgwIGFuZCB1cGRhdGUgYSBzY2FmZm9sZGVkIGNsaWVudFwiKTtcblx0YXV0aDBcblx0XHQuY29tbWFuZChcImxvZ2luXCIpXG5cdFx0LmRlc2NyaXB0aW9uKFwiQXV0aGVudGljYXRlIHRoZSBBdXRoMCBDTEkgKGRldmljZSBVUkw7IHRva2VucyBwZXJzaXN0IG9uIHRoZSBob3N0KVwiKVxuXHRcdC5hY3Rpb24oKCkgPT4ge1xuXHRcdFx0cnVuQXV0aDBMb2dpbigpO1xuXHRcdH0pO1xuXHRhdXRoMFxuXHRcdC5jb21tYW5kKFwiY29uZmlndXJlXCIpXG5cdFx0LmRlc2NyaXB0aW9uKFxuXHRcdFx0XCJVcGRhdGUgQXV0aDAgQVBJIHBlcm1pc3Npb25zIGFuZCBQb3N0bWFuIFNQQSBmcm9tIEBBdXRob3JpemUgaW4gdGhpcyB3b3Jrc3BhY2VcIixcblx0XHQpXG5cdFx0LmFjdGlvbigoX29wdHM6IHVua25vd24sIGNtZDogQ29tbWFuZCkgPT4ge1xuXHRcdFx0Y29uc3QgZCA9IGNtZC5vcHRzV2l0aEdsb2JhbHMoKS5kO1xuXHRcdFx0cnVuQXV0aDBDb25maWd1cmUodHlwZW9mIGQgPT09IFwic3RyaW5nXCIgPyBkIDogXCIuXCIpO1xuXHRcdH0pO1xuXG5cdHJldHVybiBwcm9ncmFtO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuQ2xpKGFyZ3Y6IHN0cmluZ1tdID0gcHJvY2Vzcy5hcmd2KTogUHJvbWlzZTx2b2lkPiB7XG5cdHRyeSB7XG5cdFx0YXdhaXQgY3JlYXRlUHJvZ3JhbSgpLnBhcnNlQXN5bmMoYXJndik7XG5cdH0gY2F0Y2ggKGVycikge1xuXHRcdGlmIChlcnIgaW5zdGFuY2VvZiBDb21tYW5kZXJFcnJvcikge1xuXHRcdFx0cHJvY2Vzcy5leGl0KGVyci5leGl0Q29kZSk7XG5cdFx0fVxuXHRcdGlmIChlcnIgaW5zdGFuY2VvZiBDcmVhdGVDbGlFcnJvcikge1xuXHRcdFx0Y29uc29sZS5lcnJvcihgXFxuICAke2Vyci5tZXNzYWdlfVxcbmApO1xuXHRcdFx0cHJvY2Vzcy5leGl0KDEpO1xuXHRcdH1cblx0XHRjb25zb2xlLmVycm9yKGVycik7XG5cdFx0cHJvY2Vzcy5leGl0KDEpO1xuXHR9XG5cdHByb2Nlc3MuZXhpdChwcm9jZXNzLmV4aXRDb2RlID8/IDApO1xufVxuIl0sIm5hbWVzIjpbIkNvbW1hbmQiLCJDb21tYW5kZXJFcnJvciIsIkNyZWF0ZUNsaUVycm9yIiwicnVuQXV0aDBDb25maWd1cmUiLCJydW5BdXRoMExvZ2luIiwiYWRkV2ViYXBpRmVhdHVyZU9wdGlvbnMiLCJjb2xsZWN0TmFtZSIsInJ1blNjYWZmb2xkQXBpIiwidG9BcGlPcHRpb25zIiwiY3JlYXRlUHJvZ3JhbSIsInByb2dyYW0iLCJleGl0T3ZlcnJpZGUiLCJuYW1lIiwiZGVzY3JpcHRpb24iLCJvcHRpb24iLCJjcmVhdGUiLCJjb21tYW5kIiwiYXJndW1lbnQiLCJhY3Rpb24iLCJkaXJlY3RvcnkiLCJfb3B0cyIsImNtZCIsIm9wdHNXaXRoR2xvYmFscyIsInVuZGVmaW5lZCIsIm5hbWVzIiwiYWRkIiwiYXV0aDAiLCJkIiwicnVuQ2xpIiwiYXJndiIsInByb2Nlc3MiLCJwYXJzZUFzeW5jIiwiZXJyIiwiZXhpdCIsImV4aXRDb2RlIiwiY29uc29sZSIsImVycm9yIiwibWVzc2FnZSJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsT0FBTyxFQUFFQyxjQUFjLFFBQVEsWUFBWTtBQUNwRCxTQUFTQyxjQUFjLFFBQVEsdUJBQXVCO0FBQ3RELFNBQVNDLGlCQUFpQixFQUFFQyxhQUFhLFFBQVEsNkJBQTZCO0FBQzlFLFNBQ0NDLHVCQUF1QixFQUN2QkMsV0FBVyxFQUNYQyxjQUFjLEVBQ2RDLFlBQVksUUFDTiwwQkFBMEI7QUFFakMsT0FBTyxTQUFTQztJQUNmLE1BQU1DLFVBQVUsSUFBSVY7SUFDcEJVLFFBQVFDLFlBQVk7SUFDcEJELFFBQ0VFLElBQUksQ0FBQyxZQUNMQyxXQUFXLENBQUMsZ0JBQ1pDLE1BQU0sQ0FBQyxrQkFBa0IsaURBQWlEO0lBRTVFLE1BQU1DLFNBQVNMLFFBQVFNLE9BQU8sQ0FBQyxVQUFVSCxXQUFXLENBQUM7SUFDckRSLHdCQUNDVSxPQUNFQyxPQUFPLENBQUMsVUFDUkMsUUFBUSxDQUFDLGVBQWUsdURBQ3hCSCxNQUFNLENBQ04saUJBQ0EsdURBQ0FSLGFBQ0EsRUFBRSxHQUVIWSxNQUFNLENBQUMsT0FBT0MsV0FBK0JDLE9BQWdCQztRQUM5RCxNQUFNZCxlQUFlQyxhQUFhVyxXQUFXRSxJQUFJQyxlQUFlO0lBQ2pFO0lBRUFqQix3QkFDQ0ssUUFDRU0sT0FBTyxDQUFDLE9BQ1JILFdBQVcsQ0FBQyx5Q0FDWkcsT0FBTyxDQUFDLE9BQ1JDLFFBQVEsQ0FBQyxVQUFVLDZCQUNwQkMsTUFBTSxDQUFDLE9BQU9OLE1BQWNRLE9BQWdCQztRQUM3QyxNQUFNZCxlQUNMQyxhQUFhZSxXQUFXRixJQUFJQyxlQUFlLElBQUk7WUFBRUUsT0FBTztnQkFBQ1o7YUFBSztZQUFFYSxLQUFLO1FBQUs7SUFFNUU7SUFFQSxNQUFNQyxRQUFRaEIsUUFDWk0sT0FBTyxDQUFDLFNBQ1JILFdBQVcsQ0FBQztJQUNkYSxNQUNFVixPQUFPLENBQUMsU0FDUkgsV0FBVyxDQUFDLHVFQUNaSyxNQUFNLENBQUM7UUFDUGQ7SUFDRDtJQUNEc0IsTUFDRVYsT0FBTyxDQUFDLGFBQ1JILFdBQVcsQ0FDWCxrRkFFQUssTUFBTSxDQUFDLENBQUNFLE9BQWdCQztRQUN4QixNQUFNTSxJQUFJTixJQUFJQyxlQUFlLEdBQUdLLENBQUM7UUFDakN4QixrQkFBa0IsT0FBT3dCLE1BQU0sV0FBV0EsSUFBSTtJQUMvQztJQUVELE9BQU9qQjtBQUNSO0FBRUEsT0FBTyxlQUFla0IsT0FBT0MsT0FBaUJDLFFBQVFELElBQUk7SUFDekQsSUFBSTtRQUNILE1BQU1wQixnQkFBZ0JzQixVQUFVLENBQUNGO0lBQ2xDLEVBQUUsT0FBT0csS0FBSztRQUNiLElBQUlBLGVBQWUvQixnQkFBZ0I7WUFDbEM2QixRQUFRRyxJQUFJLENBQUNELElBQUlFLFFBQVE7UUFDMUI7UUFDQSxJQUFJRixlQUFlOUIsZ0JBQWdCO1lBQ2xDaUMsUUFBUUMsS0FBSyxDQUFDLENBQUMsSUFBSSxFQUFFSixJQUFJSyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ3BDUCxRQUFRRyxJQUFJLENBQUM7UUFDZDtRQUNBRSxRQUFRQyxLQUFLLENBQUNKO1FBQ2RGLFFBQVFHLElBQUksQ0FBQztJQUNkO0lBQ0FILFFBQVFHLElBQUksQ0FBQ0gsUUFBUUksUUFBUSxJQUFJO0FBQ2xDIn0=
@@ -0,0 +1,187 @@
1
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { basename, join, resolve } from "node:path";
3
+ import { CreateCliError, isDecohereWorkspace } from "./api-name.js";
4
+ import { discoverAuthorizeScopes, mergeApiScopes, postmanRequestedScopes } from "./authorize-scopes.js";
5
+ import * as auth0Cli from "./features/auth0-cli.js";
6
+ /** Same Postman OAuth callbacks as `PostmanFeature`. */ const POSTMAN_CALLBACKS = [
7
+ "https://oauth.pstmn.io/v1/callback",
8
+ "https://oauth.pstmn.io/v1/browser-callback"
9
+ ];
10
+ const SPA_SUFFIX = " Postman";
11
+ export const AUTH0_CLI_INSTALL_MESSAGE = "The Auth0 CLI is required.\n" + " It is bundled in the Decohere create image (`npx @decohere/create auth0 login`).\n" + " Host install: brew install auth0/auth0-cli/auth0\n" + " Or visit: https://github.com/auth0/auth0-cli";
12
+ function fail(message) {
13
+ throw new CreateCliError(message);
14
+ }
15
+ /** Throw if the `auth0` binary is missing. */ export function requireInstalled() {
16
+ if (auth0Cli.isInstalled()) return;
17
+ fail(AUTH0_CLI_INSTALL_MESSAGE);
18
+ }
19
+ /**
20
+ * Log in when there is no tenant session or the Management API token is expired.
21
+ * Returns the active tenant.
22
+ */ export function ensureLoggedIn() {
23
+ requireInstalled();
24
+ process.stdout.write("\n Checking Auth0 credentials...");
25
+ let tenants = auth0Cli.listTenants();
26
+ if (tenants.length === 0) {
27
+ process.stdout.write(" not logged in.\n");
28
+ console.log(" Logging in to Auth0 (open the URL in your browser)...");
29
+ if (!auth0Cli.login()) fail("Auth0 login failed.");
30
+ tenants = auth0Cli.listTenants();
31
+ }
32
+ try {
33
+ auth0Cli.listApis();
34
+ process.stdout.write(" ok.\n");
35
+ } catch (err) {
36
+ if (err instanceof auth0Cli.Auth0AuthError) {
37
+ process.stdout.write(" token expired.\n");
38
+ console.log(" Re-authenticating (open the URL in your browser)...");
39
+ if (!auth0Cli.login()) fail("Auth0 login failed.");
40
+ tenants = auth0Cli.listTenants();
41
+ }
42
+ }
43
+ const active = tenants.find((t)=>t.active) ?? tenants[0];
44
+ if (active == null) fail("No Auth0 tenant after login.");
45
+ return active;
46
+ }
47
+ export function runAuth0Login() {
48
+ requireInstalled();
49
+ console.log(" Logging in to Auth0 (open the URL in your browser)...");
50
+ if (!auth0Cli.login()) fail("Auth0 login failed.");
51
+ const tenants = auth0Cli.listTenants();
52
+ const active = tenants.find((t)=>t.active) ?? tenants[0];
53
+ if (active == null) fail("No Auth0 tenant after login.");
54
+ console.log(`\n ✓ Auth0 tenant: https://${active.name}`);
55
+ console.log(" Tokens are stored in ~/.config/auth0 (mounted into the create image).");
56
+ console.log(" Next: npx @decohere/create auth0 configure");
57
+ }
58
+ export function runAuth0Configure(directory = ".") {
59
+ const targetDir = resolve(directory);
60
+ if (!isDecohereWorkspace(targetDir)) {
61
+ throw new CreateCliError(`Not a Decohere workspace: ${targetDir}. Scaffold one first with \`npx @decohere/create webapi\`.`);
62
+ }
63
+ const active = ensureLoggedIn();
64
+ const issuerBaseUrl = `https://${active.name}`;
65
+ const projectName = process.env.DECOHERE_PROJECT_NAME?.trim() || basename(targetDir);
66
+ const envPath = join(targetDir, ".env");
67
+ const existing = readEnvFile(envPath);
68
+ const existingAudience = existing.AUTH0_AUDIENCE?.trim();
69
+ const discovered = discoverAuthorizeScopes(targetDir);
70
+ let existingScopes = [];
71
+ if (existingAudience) {
72
+ try {
73
+ existingScopes = auth0Cli.listApiScopes(existingAudience);
74
+ } catch (err) {
75
+ if (err instanceof auth0Cli.Auth0AuthError) throw err;
76
+ }
77
+ }
78
+ const apiScopes = resolveApiScopes(discovered, existingScopes);
79
+ console.log(discovered.length > 0 ? ` ✓ Scanned @Authorize — ${discovered.length} scope(s) from controllers` : " ✓ No @Authorize in projects/*/src — keeping existing / Hello scopes");
80
+ let audience = existingAudience;
81
+ if (audience) {
82
+ try {
83
+ auth0Cli.updateApiScopes(audience, apiScopes);
84
+ console.log(` ✓ API scopes ensured (${apiScopes.join(", ")})`);
85
+ } catch (err) {
86
+ console.error(` ✗ Failed to update API scopes: ${err instanceof Error ? err.message : err}`);
87
+ }
88
+ } else {
89
+ const identifier = `https://api.${projectName}`;
90
+ console.log(`\n Creating Auth0 API ${identifier}...`);
91
+ audience = auth0Cli.createApi(`${projectName} API`, identifier, apiScopes).identifier;
92
+ console.log(` ✓ API created: ${audience}`);
93
+ }
94
+ const appName = `${projectName}${SPA_SUFFIX}`;
95
+ const app = auth0Cli.ensureSpaApp(appName, [
96
+ ...POSTMAN_CALLBACKS
97
+ ]);
98
+ console.log(app.reused ? ` ✓ Reusing Auth0 SPA app (${app.client_id})` : ` ✓ Auth0 SPA app created (${app.client_id})`);
99
+ try {
100
+ auth0Cli.enableConnectionForClient(auth0Cli.DB_CONNECTION_NAME, app.client_id);
101
+ console.log(` ✓ Enabled ${auth0Cli.DB_CONNECTION_NAME} on SPA`);
102
+ } catch (err) {
103
+ console.error(` ✗ Failed to enable DB connection on SPA: ${err instanceof Error ? err.message : err}`);
104
+ }
105
+ upsertEnv(envPath, {
106
+ AUTH0_ISSUER_BASE_URL: issuerBaseUrl,
107
+ AUTH0_AUDIENCE: audience
108
+ });
109
+ console.log(` ✓ Wrote AUTH0_ISSUER_BASE_URL and AUTH0_AUDIENCE to .env`);
110
+ const adminSub = existing.AUTH0_ADMIN_USER_SUB?.trim();
111
+ if (adminSub) {
112
+ try {
113
+ auth0Cli.assignUserPermissions(adminSub, audience, apiScopes);
114
+ console.log(` ✓ Assigned ${apiScopes.length} API permission(s) to admin user`);
115
+ } catch (err) {
116
+ console.error(` ✗ Failed to assign admin permissions: ${err instanceof Error ? err.message : err}`);
117
+ }
118
+ }
119
+ const domain = issuerBaseUrl.replace(/^https?:\/\//, "");
120
+ patchPostmanAuth(targetDir, projectName, {
121
+ domain,
122
+ audience,
123
+ clientId: app.client_id,
124
+ scopes: postmanRequestedScopes(apiScopes)
125
+ });
126
+ }
127
+ function readEnvFile(path) {
128
+ if (!existsSync(path)) return {};
129
+ const out = {};
130
+ for (const line of readFileSync(path, "utf8").split("\n")){
131
+ const trimmed = line.trim();
132
+ if (trimmed === "" || trimmed.startsWith("#")) continue;
133
+ const eq = line.indexOf("=");
134
+ if (eq <= 0) continue;
135
+ out[line.slice(0, eq).trim()] = line.slice(eq + 1);
136
+ }
137
+ return out;
138
+ }
139
+ function resolveApiScopes(discovered, existing) {
140
+ const merged = mergeApiScopes(discovered, existing);
141
+ return merged.length > 0 ? merged : [
142
+ ...auth0Cli.HELLO_API_SCOPES
143
+ ].sort();
144
+ }
145
+ function upsertEnv(path, entries) {
146
+ let text = existsSync(path) ? readFileSync(path, "utf8") : "";
147
+ for (const [key, value] of Object.entries(entries)){
148
+ const re = new RegExp(`^${key}=.*$`, "m");
149
+ if (re.test(text)) {
150
+ text = text.replace(re, `${key}=${value}`);
151
+ } else {
152
+ text = `${text}${text === "" || text.endsWith("\n") ? "" : "\n"}${key}=${value}\n`;
153
+ }
154
+ }
155
+ if (text !== "" && !text.endsWith("\n")) text = `${text}\n`;
156
+ writeFileSync(path, text);
157
+ }
158
+ function patchPostmanAuth(targetDir, projectName, auth) {
159
+ const envYaml = join(targetDir, "postman/environments", `${projectName}-Local.environment.yaml`);
160
+ if (existsSync(envYaml)) {
161
+ let yaml = readFileSync(envYaml, "utf8");
162
+ yaml = replaceYamlKeyedValue(yaml, "auth0Domain", auth.domain);
163
+ yaml = replaceYamlKeyedValue(yaml, "auth0Audience", auth.audience);
164
+ yaml = replaceYamlKeyedValue(yaml, "auth0ClientId", auth.clientId);
165
+ yaml = replaceYamlKeyedValue(yaml, "authUrl", `https://${auth.domain}/authorize?audience=${auth.audience}`);
166
+ yaml = replaceYamlKeyedValue(yaml, "accessTokenUrl", `https://${auth.domain}/oauth/token`);
167
+ yaml = replaceYamlKeyedValue(yaml, "scope", auth.scopes);
168
+ writeFileSync(envYaml, yaml);
169
+ console.log(` ✓ Updated Postman environment auth0ClientId (${auth.clientId})`);
170
+ console.log(` ✓ Updated Postman token scopes`);
171
+ }
172
+ const collectionDef = join(targetDir, "postman/collections", `${projectName} WebAPI`, ".resources/definition.yaml");
173
+ if (existsSync(collectionDef)) {
174
+ let yaml = readFileSync(collectionDef, "utf8");
175
+ yaml = yaml.replace(/^(\s*clientId:\s*).+$/m, `$1${JSON.stringify(auth.clientId)}`);
176
+ yaml = yaml.replace(/^(\s*scope:\s*).+$/m, `$1${JSON.stringify(auth.scopes)}`);
177
+ writeFileSync(collectionDef, yaml);
178
+ }
179
+ }
180
+ /** Replace `key: <name>` / `value: …` pairs in Postman Local View environment YAML. */ function replaceYamlKeyedValue(yaml, key, value) {
181
+ const quoted = JSON.stringify(value);
182
+ const re = new RegExp(`(key:\\s*${key}\\s*\\n\\s*value:\\s*)[^\\n]+`, "m");
183
+ if (!re.test(yaml)) return yaml;
184
+ return yaml.replace(re, `$1${quoted}`);
185
+ }
186
+
187
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjYWZmb2xkL3NyYy93ZWJhcGkvYXV0aDAtY29tbWFuZHMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZXhpc3RzU3luYywgcmVhZEZpbGVTeW5jLCB3cml0ZUZpbGVTeW5jIH0gZnJvbSBcIm5vZGU6ZnNcIjtcbmltcG9ydCB7IGJhc2VuYW1lLCBqb2luLCByZXNvbHZlIH0gZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHsgQ3JlYXRlQ2xpRXJyb3IsIGlzRGVjb2hlcmVXb3Jrc3BhY2UgfSBmcm9tIFwiLi9hcGktbmFtZS5qc1wiO1xuaW1wb3J0IHtcblx0ZGlzY292ZXJBdXRob3JpemVTY29wZXMsXG5cdG1lcmdlQXBpU2NvcGVzLFxuXHRwb3N0bWFuUmVxdWVzdGVkU2NvcGVzLFxufSBmcm9tIFwiLi9hdXRob3JpemUtc2NvcGVzLmpzXCI7XG5pbXBvcnQgKiBhcyBhdXRoMENsaSBmcm9tIFwiLi9mZWF0dXJlcy9hdXRoMC1jbGkuanNcIjtcblxuLyoqIFNhbWUgUG9zdG1hbiBPQXV0aCBjYWxsYmFja3MgYXMgYFBvc3RtYW5GZWF0dXJlYC4gKi9cbmNvbnN0IFBPU1RNQU5fQ0FMTEJBQ0tTID0gW1xuXHRcImh0dHBzOi8vb2F1dGgucHN0bW4uaW8vdjEvY2FsbGJhY2tcIixcblx0XCJodHRwczovL29hdXRoLnBzdG1uLmlvL3YxL2Jyb3dzZXItY2FsbGJhY2tcIixcbl0gYXMgY29uc3Q7XG5cbmNvbnN0IFNQQV9TVUZGSVggPSBcIiBQb3N0bWFuXCI7XG5cbmV4cG9ydCBjb25zdCBBVVRIMF9DTElfSU5TVEFMTF9NRVNTQUdFID1cblx0XCJUaGUgQXV0aDAgQ0xJIGlzIHJlcXVpcmVkLlxcblwiICtcblx0XCIgIEl0IGlzIGJ1bmRsZWQgaW4gdGhlIERlY29oZXJlIGNyZWF0ZSBpbWFnZSAoYG5weCBAZGVjb2hlcmUvY3JlYXRlIGF1dGgwIGxvZ2luYCkuXFxuXCIgK1xuXHRcIiAgSG9zdCBpbnN0YWxsOiBicmV3IGluc3RhbGwgYXV0aDAvYXV0aDAtY2xpL2F1dGgwXFxuXCIgK1xuXHRcIiAgT3IgdmlzaXQ6IGh0dHBzOi8vZ2l0aHViLmNvbS9hdXRoMC9hdXRoMC1jbGlcIjtcblxuZnVuY3Rpb24gZmFpbChtZXNzYWdlOiBzdHJpbmcpOiBuZXZlciB7XG5cdHRocm93IG5ldyBDcmVhdGVDbGlFcnJvcihtZXNzYWdlKTtcbn1cblxuLyoqIFRocm93IGlmIHRoZSBgYXV0aDBgIGJpbmFyeSBpcyBtaXNzaW5nLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVJbnN0YWxsZWQoKTogdm9pZCB7XG5cdGlmIChhdXRoMENsaS5pc0luc3RhbGxlZCgpKSByZXR1cm47XG5cdGZhaWwoQVVUSDBfQ0xJX0lOU1RBTExfTUVTU0FHRSk7XG59XG5cbi8qKlxuICogTG9nIGluIHdoZW4gdGhlcmUgaXMgbm8gdGVuYW50IHNlc3Npb24gb3IgdGhlIE1hbmFnZW1lbnQgQVBJIHRva2VuIGlzIGV4cGlyZWQuXG4gKiBSZXR1cm5zIHRoZSBhY3RpdmUgdGVuYW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZW5zdXJlTG9nZ2VkSW4oKTogYXV0aDBDbGkuQXV0aDBUZW5hbnQge1xuXHRyZXF1aXJlSW5zdGFsbGVkKCk7XG5cblx0cHJvY2Vzcy5zdGRvdXQud3JpdGUoXCJcXG4gIENoZWNraW5nIEF1dGgwIGNyZWRlbnRpYWxzLi4uXCIpO1xuXHRsZXQgdGVuYW50cyA9IGF1dGgwQ2xpLmxpc3RUZW5hbnRzKCk7XG5cdGlmICh0ZW5hbnRzLmxlbmd0aCA9PT0gMCkge1xuXHRcdHByb2Nlc3Muc3Rkb3V0LndyaXRlKFwiIG5vdCBsb2dnZWQgaW4uXFxuXCIpO1xuXHRcdGNvbnNvbGUubG9nKFwiICBMb2dnaW5nIGluIHRvIEF1dGgwIChvcGVuIHRoZSBVUkwgaW4geW91ciBicm93c2VyKS4uLlwiKTtcblx0XHRpZiAoIWF1dGgwQ2xpLmxvZ2luKCkpIGZhaWwoXCJBdXRoMCBsb2dpbiBmYWlsZWQuXCIpO1xuXHRcdHRlbmFudHMgPSBhdXRoMENsaS5saXN0VGVuYW50cygpO1xuXHR9XG5cblx0dHJ5IHtcblx0XHRhdXRoMENsaS5saXN0QXBpcygpO1xuXHRcdHByb2Nlc3Muc3Rkb3V0LndyaXRlKFwiIG9rLlxcblwiKTtcblx0fSBjYXRjaCAoZXJyKSB7XG5cdFx0aWYgKGVyciBpbnN0YW5jZW9mIGF1dGgwQ2xpLkF1dGgwQXV0aEVycm9yKSB7XG5cdFx0XHRwcm9jZXNzLnN0ZG91dC53cml0ZShcIiB0b2tlbiBleHBpcmVkLlxcblwiKTtcblx0XHRcdGNvbnNvbGUubG9nKFwiICBSZS1hdXRoZW50aWNhdGluZyAob3BlbiB0aGUgVVJMIGluIHlvdXIgYnJvd3NlcikuLi5cIik7XG5cdFx0XHRpZiAoIWF1dGgwQ2xpLmxvZ2luKCkpIGZhaWwoXCJBdXRoMCBsb2dpbiBmYWlsZWQuXCIpO1xuXHRcdFx0dGVuYW50cyA9IGF1dGgwQ2xpLmxpc3RUZW5hbnRzKCk7XG5cdFx0fVxuXHR9XG5cblx0Y29uc3QgYWN0aXZlID0gdGVuYW50cy5maW5kKCh0KSA9PiB0LmFjdGl2ZSkgPz8gdGVuYW50c1swXTtcblx0aWYgKGFjdGl2ZSA9PSBudWxsKSBmYWlsKFwiTm8gQXV0aDAgdGVuYW50IGFmdGVyIGxvZ2luLlwiKTtcblx0cmV0dXJuIGFjdGl2ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJ1bkF1dGgwTG9naW4oKTogdm9pZCB7XG5cdHJlcXVpcmVJbnN0YWxsZWQoKTtcblx0Y29uc29sZS5sb2coXCIgIExvZ2dpbmcgaW4gdG8gQXV0aDAgKG9wZW4gdGhlIFVSTCBpbiB5b3VyIGJyb3dzZXIpLi4uXCIpO1xuXHRpZiAoIWF1dGgwQ2xpLmxvZ2luKCkpIGZhaWwoXCJBdXRoMCBsb2dpbiBmYWlsZWQuXCIpO1xuXHRjb25zdCB0ZW5hbnRzID0gYXV0aDBDbGkubGlzdFRlbmFudHMoKTtcblx0Y29uc3QgYWN0aXZlID0gdGVuYW50cy5maW5kKCh0KSA9PiB0LmFjdGl2ZSkgPz8gdGVuYW50c1swXTtcblx0aWYgKGFjdGl2ZSA9PSBudWxsKSBmYWlsKFwiTm8gQXV0aDAgdGVuYW50IGFmdGVyIGxvZ2luLlwiKTtcblx0Y29uc29sZS5sb2coYFxcbiAg4pyTIEF1dGgwIHRlbmFudDogaHR0cHM6Ly8ke2FjdGl2ZS5uYW1lfWApO1xuXHRjb25zb2xlLmxvZyhcIiAgICBUb2tlbnMgYXJlIHN0b3JlZCBpbiB+Ly5jb25maWcvYXV0aDAgKG1vdW50ZWQgaW50byB0aGUgY3JlYXRlIGltYWdlKS5cIik7XG5cdGNvbnNvbGUubG9nKFwiICAgIE5leHQ6IG5weCBAZGVjb2hlcmUvY3JlYXRlIGF1dGgwIGNvbmZpZ3VyZVwiKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJ1bkF1dGgwQ29uZmlndXJlKGRpcmVjdG9yeSA9IFwiLlwiKTogdm9pZCB7XG5cdGNvbnN0IHRhcmdldERpciA9IHJlc29sdmUoZGlyZWN0b3J5KTtcblx0aWYgKCFpc0RlY29oZXJlV29ya3NwYWNlKHRhcmdldERpcikpIHtcblx0XHR0aHJvdyBuZXcgQ3JlYXRlQ2xpRXJyb3IoXG5cdFx0XHRgTm90IGEgRGVjb2hlcmUgd29ya3NwYWNlOiAke3RhcmdldERpcn0uIFNjYWZmb2xkIG9uZSBmaXJzdCB3aXRoIFxcYG5weCBAZGVjb2hlcmUvY3JlYXRlIHdlYmFwaVxcYC5gLFxuXHRcdCk7XG5cdH1cblxuXHRjb25zdCBhY3RpdmUgPSBlbnN1cmVMb2dnZWRJbigpO1xuXHRjb25zdCBpc3N1ZXJCYXNlVXJsID0gYGh0dHBzOi8vJHthY3RpdmUubmFtZX1gO1xuXHRjb25zdCBwcm9qZWN0TmFtZSA9IHByb2Nlc3MuZW52LkRFQ09IRVJFX1BST0pFQ1RfTkFNRT8udHJpbSgpIHx8IGJhc2VuYW1lKHRhcmdldERpcik7XG5cdGNvbnN0IGVudlBhdGggPSBqb2luKHRhcmdldERpciwgXCIuZW52XCIpO1xuXHRjb25zdCBleGlzdGluZyA9IHJlYWRFbnZGaWxlKGVudlBhdGgpO1xuXHRjb25zdCBleGlzdGluZ0F1ZGllbmNlID0gZXhpc3RpbmcuQVVUSDBfQVVESUVOQ0U/LnRyaW0oKTtcblx0Y29uc3QgZGlzY292ZXJlZCA9IGRpc2NvdmVyQXV0aG9yaXplU2NvcGVzKHRhcmdldERpcik7XG5cdGxldCBleGlzdGluZ1Njb3Blczogc3RyaW5nW10gPSBbXTtcblx0aWYgKGV4aXN0aW5nQXVkaWVuY2UpIHtcblx0XHR0cnkge1xuXHRcdFx0ZXhpc3RpbmdTY29wZXMgPSBhdXRoMENsaS5saXN0QXBpU2NvcGVzKGV4aXN0aW5nQXVkaWVuY2UpO1xuXHRcdH0gY2F0Y2ggKGVycikge1xuXHRcdFx0aWYgKGVyciBpbnN0YW5jZW9mIGF1dGgwQ2xpLkF1dGgwQXV0aEVycm9yKSB0aHJvdyBlcnI7XG5cdFx0fVxuXHR9XG5cdGNvbnN0IGFwaVNjb3BlcyA9IHJlc29sdmVBcGlTY29wZXMoZGlzY292ZXJlZCwgZXhpc3RpbmdTY29wZXMpO1xuXHRjb25zb2xlLmxvZyhcblx0XHRkaXNjb3ZlcmVkLmxlbmd0aCA+IDBcblx0XHRcdD8gYCAg4pyTIFNjYW5uZWQgQEF1dGhvcml6ZSDigJQgJHtkaXNjb3ZlcmVkLmxlbmd0aH0gc2NvcGUocykgZnJvbSBjb250cm9sbGVyc2Bcblx0XHRcdDogXCIgIOKckyBObyBAQXV0aG9yaXplIGluIHByb2plY3RzLyovc3JjIOKAlCBrZWVwaW5nIGV4aXN0aW5nIC8gSGVsbG8gc2NvcGVzXCIsXG5cdCk7XG5cblx0bGV0IGF1ZGllbmNlID0gZXhpc3RpbmdBdWRpZW5jZTtcblx0aWYgKGF1ZGllbmNlKSB7XG5cdFx0dHJ5IHtcblx0XHRcdGF1dGgwQ2xpLnVwZGF0ZUFwaVNjb3BlcyhhdWRpZW5jZSwgYXBpU2NvcGVzKTtcblx0XHRcdGNvbnNvbGUubG9nKGAgIOKckyBBUEkgc2NvcGVzIGVuc3VyZWQgKCR7YXBpU2NvcGVzLmpvaW4oXCIsIFwiKX0pYCk7XG5cdFx0fSBjYXRjaCAoZXJyKSB7XG5cdFx0XHRjb25zb2xlLmVycm9yKFxuXHRcdFx0XHRgICDinJcgRmFpbGVkIHRvIHVwZGF0ZSBBUEkgc2NvcGVzOiAke2VyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBlcnJ9YCxcblx0XHRcdCk7XG5cdFx0fVxuXHR9IGVsc2Uge1xuXHRcdGNvbnN0IGlkZW50aWZpZXIgPSBgaHR0cHM6Ly9hcGkuJHtwcm9qZWN0TmFtZX1gO1xuXHRcdGNvbnNvbGUubG9nKGBcXG4gIENyZWF0aW5nIEF1dGgwIEFQSSAke2lkZW50aWZpZXJ9Li4uYCk7XG5cdFx0YXVkaWVuY2UgPSBhdXRoMENsaS5jcmVhdGVBcGkoYCR7cHJvamVjdE5hbWV9IEFQSWAsIGlkZW50aWZpZXIsIGFwaVNjb3BlcykuaWRlbnRpZmllcjtcblx0XHRjb25zb2xlLmxvZyhgICDinJMgQVBJIGNyZWF0ZWQ6ICR7YXVkaWVuY2V9YCk7XG5cdH1cblxuXHRjb25zdCBhcHBOYW1lID0gYCR7cHJvamVjdE5hbWV9JHtTUEFfU1VGRklYfWA7XG5cdGNvbnN0IGFwcCA9IGF1dGgwQ2xpLmVuc3VyZVNwYUFwcChhcHBOYW1lLCBbLi4uUE9TVE1BTl9DQUxMQkFDS1NdKTtcblx0Y29uc29sZS5sb2coXG5cdFx0YXBwLnJldXNlZFxuXHRcdFx0PyBgICDinJMgUmV1c2luZyBBdXRoMCBTUEEgYXBwICgke2FwcC5jbGllbnRfaWR9KWBcblx0XHRcdDogYCAg4pyTIEF1dGgwIFNQQSBhcHAgY3JlYXRlZCAoJHthcHAuY2xpZW50X2lkfSlgLFxuXHQpO1xuXHR0cnkge1xuXHRcdGF1dGgwQ2xpLmVuYWJsZUNvbm5lY3Rpb25Gb3JDbGllbnQoYXV0aDBDbGkuREJfQ09OTkVDVElPTl9OQU1FLCBhcHAuY2xpZW50X2lkKTtcblx0XHRjb25zb2xlLmxvZyhgICDinJMgRW5hYmxlZCAke2F1dGgwQ2xpLkRCX0NPTk5FQ1RJT05fTkFNRX0gb24gU1BBYCk7XG5cdH0gY2F0Y2ggKGVycikge1xuXHRcdGNvbnNvbGUuZXJyb3IoXG5cdFx0XHRgICDinJcgRmFpbGVkIHRvIGVuYWJsZSBEQiBjb25uZWN0aW9uIG9uIFNQQTogJHtlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogZXJyfWAsXG5cdFx0KTtcblx0fVxuXG5cdHVwc2VydEVudihlbnZQYXRoLCB7XG5cdFx0QVVUSDBfSVNTVUVSX0JBU0VfVVJMOiBpc3N1ZXJCYXNlVXJsLFxuXHRcdEFVVEgwX0FVRElFTkNFOiBhdWRpZW5jZSxcblx0fSk7XG5cdGNvbnNvbGUubG9nKGAgIOKckyBXcm90ZSBBVVRIMF9JU1NVRVJfQkFTRV9VUkwgYW5kIEFVVEgwX0FVRElFTkNFIHRvIC5lbnZgKTtcblxuXHRjb25zdCBhZG1pblN1YiA9IGV4aXN0aW5nLkFVVEgwX0FETUlOX1VTRVJfU1VCPy50cmltKCk7XG5cdGlmIChhZG1pblN1Yikge1xuXHRcdHRyeSB7XG5cdFx0XHRhdXRoMENsaS5hc3NpZ25Vc2VyUGVybWlzc2lvbnMoYWRtaW5TdWIsIGF1ZGllbmNlLCBhcGlTY29wZXMpO1xuXHRcdFx0Y29uc29sZS5sb2coYCAg4pyTIEFzc2lnbmVkICR7YXBpU2NvcGVzLmxlbmd0aH0gQVBJIHBlcm1pc3Npb24ocykgdG8gYWRtaW4gdXNlcmApO1xuXHRcdH0gY2F0Y2ggKGVycikge1xuXHRcdFx0Y29uc29sZS5lcnJvcihcblx0XHRcdFx0YCAg4pyXIEZhaWxlZCB0byBhc3NpZ24gYWRtaW4gcGVybWlzc2lvbnM6ICR7ZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IGVycn1gLFxuXHRcdFx0KTtcblx0XHR9XG5cdH1cblxuXHRjb25zdCBkb21haW4gPSBpc3N1ZXJCYXNlVXJsLnJlcGxhY2UoL15odHRwcz86XFwvXFwvLywgXCJcIik7XG5cdHBhdGNoUG9zdG1hbkF1dGgodGFyZ2V0RGlyLCBwcm9qZWN0TmFtZSwge1xuXHRcdGRvbWFpbixcblx0XHRhdWRpZW5jZSxcblx0XHRjbGllbnRJZDogYXBwLmNsaWVudF9pZCxcblx0XHRzY29wZXM6IHBvc3RtYW5SZXF1ZXN0ZWRTY29wZXMoYXBpU2NvcGVzKSxcblx0fSk7XG59XG5cbmZ1bmN0aW9uIHJlYWRFbnZGaWxlKHBhdGg6IHN0cmluZyk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuXHRpZiAoIWV4aXN0c1N5bmMocGF0aCkpIHJldHVybiB7fTtcblx0Y29uc3Qgb3V0OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG5cdGZvciAoY29uc3QgbGluZSBvZiByZWFkRmlsZVN5bmMocGF0aCwgXCJ1dGY4XCIpLnNwbGl0KFwiXFxuXCIpKSB7XG5cdFx0Y29uc3QgdHJpbW1lZCA9IGxpbmUudHJpbSgpO1xuXHRcdGlmICh0cmltbWVkID09PSBcIlwiIHx8IHRyaW1tZWQuc3RhcnRzV2l0aChcIiNcIikpIGNvbnRpbnVlO1xuXHRcdGNvbnN0IGVxID0gbGluZS5pbmRleE9mKFwiPVwiKTtcblx0XHRpZiAoZXEgPD0gMCkgY29udGludWU7XG5cdFx0b3V0W2xpbmUuc2xpY2UoMCwgZXEpLnRyaW0oKV0gPSBsaW5lLnNsaWNlKGVxICsgMSk7XG5cdH1cblx0cmV0dXJuIG91dDtcbn1cblxuZnVuY3Rpb24gcmVzb2x2ZUFwaVNjb3Blcyhcblx0ZGlzY292ZXJlZDogcmVhZG9ubHkgc3RyaW5nW10sXG5cdGV4aXN0aW5nOiByZWFkb25seSBzdHJpbmdbXSxcbik6IHN0cmluZ1tdIHtcblx0Y29uc3QgbWVyZ2VkID0gbWVyZ2VBcGlTY29wZXMoZGlzY292ZXJlZCwgZXhpc3RpbmcpO1xuXHRyZXR1cm4gbWVyZ2VkLmxlbmd0aCA+IDAgPyBtZXJnZWQgOiBbLi4uYXV0aDBDbGkuSEVMTE9fQVBJX1NDT1BFU10uc29ydCgpO1xufVxuXG5mdW5jdGlvbiB1cHNlcnRFbnYocGF0aDogc3RyaW5nLCBlbnRyaWVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KTogdm9pZCB7XG5cdGxldCB0ZXh0ID0gZXhpc3RzU3luYyhwYXRoKSA/IHJlYWRGaWxlU3luYyhwYXRoLCBcInV0ZjhcIikgOiBcIlwiO1xuXHRmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhlbnRyaWVzKSkge1xuXHRcdGNvbnN0IHJlID0gbmV3IFJlZ0V4cChgXiR7a2V5fT0uKiRgLCBcIm1cIik7XG5cdFx0aWYgKHJlLnRlc3QodGV4dCkpIHtcblx0XHRcdHRleHQgPSB0ZXh0LnJlcGxhY2UocmUsIGAke2tleX09JHt2YWx1ZX1gKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGV4dCA9IGAke3RleHR9JHt0ZXh0ID09PSBcIlwiIHx8IHRleHQuZW5kc1dpdGgoXCJcXG5cIikgPyBcIlwiIDogXCJcXG5cIn0ke2tleX09JHt2YWx1ZX1cXG5gO1xuXHRcdH1cblx0fVxuXHRpZiAodGV4dCAhPT0gXCJcIiAmJiAhdGV4dC5lbmRzV2l0aChcIlxcblwiKSkgdGV4dCA9IGAke3RleHR9XFxuYDtcblx0d3JpdGVGaWxlU3luYyhwYXRoLCB0ZXh0KTtcbn1cblxuZnVuY3Rpb24gcGF0Y2hQb3N0bWFuQXV0aChcblx0dGFyZ2V0RGlyOiBzdHJpbmcsXG5cdHByb2plY3ROYW1lOiBzdHJpbmcsXG5cdGF1dGg6IHsgZG9tYWluOiBzdHJpbmc7IGF1ZGllbmNlOiBzdHJpbmc7IGNsaWVudElkOiBzdHJpbmc7IHNjb3Blczogc3RyaW5nIH0sXG4pOiB2b2lkIHtcblx0Y29uc3QgZW52WWFtbCA9IGpvaW4oXG5cdFx0dGFyZ2V0RGlyLFxuXHRcdFwicG9zdG1hbi9lbnZpcm9ubWVudHNcIixcblx0XHRgJHtwcm9qZWN0TmFtZX0tTG9jYWwuZW52aXJvbm1lbnQueWFtbGAsXG5cdCk7XG5cdGlmIChleGlzdHNTeW5jKGVudllhbWwpKSB7XG5cdFx0bGV0IHlhbWwgPSByZWFkRmlsZVN5bmMoZW52WWFtbCwgXCJ1dGY4XCIpO1xuXHRcdHlhbWwgPSByZXBsYWNlWWFtbEtleWVkVmFsdWUoeWFtbCwgXCJhdXRoMERvbWFpblwiLCBhdXRoLmRvbWFpbik7XG5cdFx0eWFtbCA9IHJlcGxhY2VZYW1sS2V5ZWRWYWx1ZSh5YW1sLCBcImF1dGgwQXVkaWVuY2VcIiwgYXV0aC5hdWRpZW5jZSk7XG5cdFx0eWFtbCA9IHJlcGxhY2VZYW1sS2V5ZWRWYWx1ZSh5YW1sLCBcImF1dGgwQ2xpZW50SWRcIiwgYXV0aC5jbGllbnRJZCk7XG5cdFx0eWFtbCA9IHJlcGxhY2VZYW1sS2V5ZWRWYWx1ZShcblx0XHRcdHlhbWwsXG5cdFx0XHRcImF1dGhVcmxcIixcblx0XHRcdGBodHRwczovLyR7YXV0aC5kb21haW59L2F1dGhvcml6ZT9hdWRpZW5jZT0ke2F1dGguYXVkaWVuY2V9YCxcblx0XHQpO1xuXHRcdHlhbWwgPSByZXBsYWNlWWFtbEtleWVkVmFsdWUoeWFtbCwgXCJhY2Nlc3NUb2tlblVybFwiLCBgaHR0cHM6Ly8ke2F1dGguZG9tYWlufS9vYXV0aC90b2tlbmApO1xuXHRcdHlhbWwgPSByZXBsYWNlWWFtbEtleWVkVmFsdWUoeWFtbCwgXCJzY29wZVwiLCBhdXRoLnNjb3Blcyk7XG5cdFx0d3JpdGVGaWxlU3luYyhlbnZZYW1sLCB5YW1sKTtcblx0XHRjb25zb2xlLmxvZyhgICDinJMgVXBkYXRlZCBQb3N0bWFuIGVudmlyb25tZW50IGF1dGgwQ2xpZW50SWQgKCR7YXV0aC5jbGllbnRJZH0pYCk7XG5cdFx0Y29uc29sZS5sb2coYCAg4pyTIFVwZGF0ZWQgUG9zdG1hbiB0b2tlbiBzY29wZXNgKTtcblx0fVxuXG5cdGNvbnN0IGNvbGxlY3Rpb25EZWYgPSBqb2luKFxuXHRcdHRhcmdldERpcixcblx0XHRcInBvc3RtYW4vY29sbGVjdGlvbnNcIixcblx0XHRgJHtwcm9qZWN0TmFtZX0gV2ViQVBJYCxcblx0XHRcIi5yZXNvdXJjZXMvZGVmaW5pdGlvbi55YW1sXCIsXG5cdCk7XG5cdGlmIChleGlzdHNTeW5jKGNvbGxlY3Rpb25EZWYpKSB7XG5cdFx0bGV0IHlhbWwgPSByZWFkRmlsZVN5bmMoY29sbGVjdGlvbkRlZiwgXCJ1dGY4XCIpO1xuXHRcdHlhbWwgPSB5YW1sLnJlcGxhY2UoL14oXFxzKmNsaWVudElkOlxccyopLiskL20sIGAkMSR7SlNPTi5zdHJpbmdpZnkoYXV0aC5jbGllbnRJZCl9YCk7XG5cdFx0eWFtbCA9IHlhbWwucmVwbGFjZSgvXihcXHMqc2NvcGU6XFxzKikuKyQvbSwgYCQxJHtKU09OLnN0cmluZ2lmeShhdXRoLnNjb3Blcyl9YCk7XG5cdFx0d3JpdGVGaWxlU3luYyhjb2xsZWN0aW9uRGVmLCB5YW1sKTtcblx0fVxufVxuXG4vKiogUmVwbGFjZSBga2V5OiA8bmFtZT5gIC8gYHZhbHVlOiDigKZgIHBhaXJzIGluIFBvc3RtYW4gTG9jYWwgVmlldyBlbnZpcm9ubWVudCBZQU1MLiAqL1xuZnVuY3Rpb24gcmVwbGFjZVlhbWxLZXllZFZhbHVlKHlhbWw6IHN0cmluZywga2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xuXHRjb25zdCBxdW90ZWQgPSBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XG5cdGNvbnN0IHJlID0gbmV3IFJlZ0V4cChgKGtleTpcXFxccyoke2tleX1cXFxccypcXFxcblxcXFxzKnZhbHVlOlxcXFxzKilbXlxcXFxuXStgLCBcIm1cIik7XG5cdGlmICghcmUudGVzdCh5YW1sKSkgcmV0dXJuIHlhbWw7XG5cdHJldHVybiB5YW1sLnJlcGxhY2UocmUsIGAkMSR7cXVvdGVkfWApO1xufVxuIl0sIm5hbWVzIjpbImV4aXN0c1N5bmMiLCJyZWFkRmlsZVN5bmMiLCJ3cml0ZUZpbGVTeW5jIiwiYmFzZW5hbWUiLCJqb2luIiwicmVzb2x2ZSIsIkNyZWF0ZUNsaUVycm9yIiwiaXNEZWNvaGVyZVdvcmtzcGFjZSIsImRpc2NvdmVyQXV0aG9yaXplU2NvcGVzIiwibWVyZ2VBcGlTY29wZXMiLCJwb3N0bWFuUmVxdWVzdGVkU2NvcGVzIiwiYXV0aDBDbGkiLCJQT1NUTUFOX0NBTExCQUNLUyIsIlNQQV9TVUZGSVgiLCJBVVRIMF9DTElfSU5TVEFMTF9NRVNTQUdFIiwiZmFpbCIsIm1lc3NhZ2UiLCJyZXF1aXJlSW5zdGFsbGVkIiwiaXNJbnN0YWxsZWQiLCJlbnN1cmVMb2dnZWRJbiIsInByb2Nlc3MiLCJzdGRvdXQiLCJ3cml0ZSIsInRlbmFudHMiLCJsaXN0VGVuYW50cyIsImxlbmd0aCIsImNvbnNvbGUiLCJsb2ciLCJsb2dpbiIsImxpc3RBcGlzIiwiZXJyIiwiQXV0aDBBdXRoRXJyb3IiLCJhY3RpdmUiLCJmaW5kIiwidCIsInJ1bkF1dGgwTG9naW4iLCJuYW1lIiwicnVuQXV0aDBDb25maWd1cmUiLCJkaXJlY3RvcnkiLCJ0YXJnZXREaXIiLCJpc3N1ZXJCYXNlVXJsIiwicHJvamVjdE5hbWUiLCJlbnYiLCJERUNPSEVSRV9QUk9KRUNUX05BTUUiLCJ0cmltIiwiZW52UGF0aCIsImV4aXN0aW5nIiwicmVhZEVudkZpbGUiLCJleGlzdGluZ0F1ZGllbmNlIiwiQVVUSDBfQVVESUVOQ0UiLCJkaXNjb3ZlcmVkIiwiZXhpc3RpbmdTY29wZXMiLCJsaXN0QXBpU2NvcGVzIiwiYXBpU2NvcGVzIiwicmVzb2x2ZUFwaVNjb3BlcyIsImF1ZGllbmNlIiwidXBkYXRlQXBpU2NvcGVzIiwiZXJyb3IiLCJFcnJvciIsImlkZW50aWZpZXIiLCJjcmVhdGVBcGkiLCJhcHBOYW1lIiwiYXBwIiwiZW5zdXJlU3BhQXBwIiwicmV1c2VkIiwiY2xpZW50X2lkIiwiZW5hYmxlQ29ubmVjdGlvbkZvckNsaWVudCIsIkRCX0NPTk5FQ1RJT05fTkFNRSIsInVwc2VydEVudiIsIkFVVEgwX0lTU1VFUl9CQVNFX1VSTCIsImFkbWluU3ViIiwiQVVUSDBfQURNSU5fVVNFUl9TVUIiLCJhc3NpZ25Vc2VyUGVybWlzc2lvbnMiLCJkb21haW4iLCJyZXBsYWNlIiwicGF0Y2hQb3N0bWFuQXV0aCIsImNsaWVudElkIiwic2NvcGVzIiwicGF0aCIsIm91dCIsImxpbmUiLCJzcGxpdCIsInRyaW1tZWQiLCJzdGFydHNXaXRoIiwiZXEiLCJpbmRleE9mIiwic2xpY2UiLCJtZXJnZWQiLCJIRUxMT19BUElfU0NPUEVTIiwic29ydCIsImVudHJpZXMiLCJ0ZXh0Iiwia2V5IiwidmFsdWUiLCJPYmplY3QiLCJyZSIsIlJlZ0V4cCIsInRlc3QiLCJlbmRzV2l0aCIsImF1dGgiLCJlbnZZYW1sIiwieWFtbCIsInJlcGxhY2VZYW1sS2V5ZWRWYWx1ZSIsImNvbGxlY3Rp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
@@ -0,0 +1,57 @@
1
+ import { existsSync, readdirSync, readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { listExistingApiNames } from "./api-name.js";
4
+ /** OIDC scopes requested on the Postman SPA token (not Auth0 API permissions). */ export const OIDC_SCOPES = [
5
+ "openid",
6
+ "profile",
7
+ "email"
8
+ ];
9
+ const AUTHORIZE_RE = /@Authorize\(\s*(["'])([^"']+)\1(?:\s*,\s*(["'])([^"']+)\3)?\s*\)/g;
10
+ function isAppSource(fileName) {
11
+ return fileName.endsWith(".ts") && !fileName.endsWith(".spec.ts") && !fileName.endsWith(".test.ts") && !fileName.endsWith(".d.ts");
12
+ }
13
+ /** Collect action:Subject scopes from Authorize decorators in each API src tree. */ export function discoverAuthorizeScopes(rootDir) {
14
+ const scopes = new Set();
15
+ for (const apiName of listExistingApiNames(rootDir)){
16
+ collectFromDir(join(rootDir, "projects", apiName, "src"), scopes);
17
+ }
18
+ return [
19
+ ...scopes
20
+ ].sort();
21
+ }
22
+ function collectFromDir(dir, scopes) {
23
+ if (!existsSync(dir)) return;
24
+ for (const entry of readdirSync(dir, {
25
+ withFileTypes: true
26
+ })){
27
+ const path = join(dir, entry.name);
28
+ if (entry.isDirectory()) {
29
+ collectFromDir(path, scopes);
30
+ continue;
31
+ }
32
+ if (!entry.isFile() || !isAppSource(entry.name)) continue;
33
+ const text = readFileSync(path, "utf8");
34
+ for (const match of text.matchAll(AUTHORIZE_RE)){
35
+ const action = match[2];
36
+ if (action == null || action === "") continue;
37
+ const subject = match[4] ?? "all";
38
+ scopes.add(`${action}:${subject}`);
39
+ }
40
+ }
41
+ }
42
+ /** Additive union so Auth0 CLI scope replace does not drop permissions already on the API. */ export function mergeApiScopes(discovered, existing) {
43
+ return [
44
+ ...new Set([
45
+ ...existing,
46
+ ...discovered
47
+ ])
48
+ ].sort();
49
+ }
50
+ export function postmanRequestedScopes(apiScopes) {
51
+ return [
52
+ ...OIDC_SCOPES,
53
+ ...apiScopes
54
+ ].join(" ");
55
+ }
56
+
57
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjYWZmb2xkL3NyYy93ZWJhcGkvYXV0aG9yaXplLXNjb3Blcy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBleGlzdHNTeW5jLCByZWFkZGlyU3luYywgcmVhZEZpbGVTeW5jIH0gZnJvbSBcIm5vZGU6ZnNcIjtcbmltcG9ydCB7IGpvaW4gfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgeyBsaXN0RXhpc3RpbmdBcGlOYW1lcyB9IGZyb20gXCIuL2FwaS1uYW1lLmpzXCI7XG5cbi8qKiBPSURDIHNjb3BlcyByZXF1ZXN0ZWQgb24gdGhlIFBvc3RtYW4gU1BBIHRva2VuIChub3QgQXV0aDAgQVBJIHBlcm1pc3Npb25zKS4gKi9cbmV4cG9ydCBjb25zdCBPSURDX1NDT1BFUyA9IFtcIm9wZW5pZFwiLCBcInByb2ZpbGVcIiwgXCJlbWFpbFwiXSBhcyBjb25zdDtcblxuY29uc3QgQVVUSE9SSVpFX1JFID0gL0BBdXRob3JpemVcXChcXHMqKFtcIiddKShbXlwiJ10rKVxcMSg/OlxccyosXFxzKihbXCInXSkoW15cIiddKylcXDMpP1xccypcXCkvZztcblxuZnVuY3Rpb24gaXNBcHBTb3VyY2UoZmlsZU5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuXHRyZXR1cm4gKFxuXHRcdGZpbGVOYW1lLmVuZHNXaXRoKFwiLnRzXCIpICYmXG5cdFx0IWZpbGVOYW1lLmVuZHNXaXRoKFwiLnNwZWMudHNcIikgJiZcblx0XHQhZmlsZU5hbWUuZW5kc1dpdGgoXCIudGVzdC50c1wiKSAmJlxuXHRcdCFmaWxlTmFtZS5lbmRzV2l0aChcIi5kLnRzXCIpXG5cdCk7XG59XG5cbi8qKiBDb2xsZWN0IGFjdGlvbjpTdWJqZWN0IHNjb3BlcyBmcm9tIEF1dGhvcml6ZSBkZWNvcmF0b3JzIGluIGVhY2ggQVBJIHNyYyB0cmVlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRpc2NvdmVyQXV0aG9yaXplU2NvcGVzKHJvb3REaXI6IHN0cmluZyk6IHN0cmluZ1tdIHtcblx0Y29uc3Qgc2NvcGVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cdGZvciAoY29uc3QgYXBpTmFtZSBvZiBsaXN0RXhpc3RpbmdBcGlOYW1lcyhyb290RGlyKSkge1xuXHRcdGNvbGxlY3RGcm9tRGlyKGpvaW4ocm9vdERpciwgXCJwcm9qZWN0c1wiLCBhcGlOYW1lLCBcInNyY1wiKSwgc2NvcGVzKTtcblx0fVxuXHRyZXR1cm4gWy4uLnNjb3Blc10uc29ydCgpO1xufVxuXG5mdW5jdGlvbiBjb2xsZWN0RnJvbURpcihkaXI6IHN0cmluZywgc2NvcGVzOiBTZXQ8c3RyaW5nPik6IHZvaWQge1xuXHRpZiAoIWV4aXN0c1N5bmMoZGlyKSkgcmV0dXJuO1xuXHRmb3IgKGNvbnN0IGVudHJ5IG9mIHJlYWRkaXJTeW5jKGRpciwgeyB3aXRoRmlsZVR5cGVzOiB0cnVlIH0pKSB7XG5cdFx0Y29uc3QgcGF0aCA9IGpvaW4oZGlyLCBlbnRyeS5uYW1lKTtcblx0XHRpZiAoZW50cnkuaXNEaXJlY3RvcnkoKSkge1xuXHRcdFx0Y29sbGVjdEZyb21EaXIocGF0aCwgc2NvcGVzKTtcblx0XHRcdGNvbnRpbnVlO1xuXHRcdH1cblx0XHRpZiAoIWVudHJ5LmlzRmlsZSgpIHx8ICFpc0FwcFNvdXJjZShlbnRyeS5uYW1lKSkgY29udGludWU7XG5cdFx0Y29uc3QgdGV4dCA9IHJlYWRGaWxlU3luYyhwYXRoLCBcInV0ZjhcIik7XG5cdFx0Zm9yIChjb25zdCBtYXRjaCBvZiB0ZXh0Lm1hdGNoQWxsKEFVVEhPUklaRV9SRSkpIHtcblx0XHRcdGNvbnN0IGFjdGlvbiA9IG1hdGNoWzJdO1xuXHRcdFx0aWYgKGFjdGlvbiA9PSBudWxsIHx8IGFjdGlvbiA9PT0gXCJcIikgY29udGludWU7XG5cdFx0XHRjb25zdCBzdWJqZWN0ID0gbWF0Y2hbNF0gPz8gXCJhbGxcIjtcblx0XHRcdHNjb3Blcy5hZGQoYCR7YWN0aW9ufToke3N1YmplY3R9YCk7XG5cdFx0fVxuXHR9XG59XG5cbi8qKiBBZGRpdGl2ZSB1bmlvbiBzbyBBdXRoMCBDTEkgc2NvcGUgcmVwbGFjZSBkb2VzIG5vdCBkcm9wIHBlcm1pc3Npb25zIGFscmVhZHkgb24gdGhlIEFQSS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZUFwaVNjb3Blcyhcblx0ZGlzY292ZXJlZDogcmVhZG9ubHkgc3RyaW5nW10sXG5cdGV4aXN0aW5nOiByZWFkb25seSBzdHJpbmdbXSxcbik6IHN0cmluZ1tdIHtcblx0cmV0dXJuIFsuLi5uZXcgU2V0KFsuLi5leGlzdGluZywgLi4uZGlzY292ZXJlZF0pXS5zb3J0KCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwb3N0bWFuUmVxdWVzdGVkU2NvcGVzKGFwaVNjb3BlczogcmVhZG9ubHkgc3RyaW5nW10pOiBzdHJpbmcge1xuXHRyZXR1cm4gWy4uLk9JRENfU0NPUEVTLCAuLi5hcGlTY29wZXNdLmpvaW4oXCIgXCIpO1xufVxuIl0sIm5hbWVzIjpbImV4aXN0c1N5bmMiLCJyZWFkZGlyU3luYyIsInJlYWRGaWxlU3luYyIsImpvaW4iLCJsaXN0RXhpc3RpbmdBcGlOYW1lcyIsIk9JRENfU0NPUEVTIiwiQVVUSE9SSVpFX1JFIiwiaXNBcHBTb3VyY2UiLCJmaWxlTmFtZSIsImVuZHNXaXRoIiwiZGlzY292ZXJBdXRob3JpemVTY29wZXMiLCJyb290RGlyIiwic2NvcGVzIiwiU2V0IiwiYXBpTmFtZSIsImNvbGxlY3RGcm9tRGlyIiwic29ydCIsImRpciIsImVudHJ5Iiwid2l0aEZpbGVUeXBlcyIsInBhdGgiLCJuYW1lIiwiaXNEaXJlY3RvcnkiLCJpc0ZpbGUiLCJ0ZXh0IiwibWF0Y2giLCJtYXRjaEFsbCIsImFjdGlvbiIsInN1YmplY3QiLCJhZGQiLCJtZXJnZUFwaVNjb3BlcyIsImRpc2NvdmVyZWQiLCJleGlzdGluZyIsInBvc3RtYW5SZXF1ZXN0ZWRTY29wZXMiLCJhcGlTY29wZXMiXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLFVBQVUsRUFBRUMsV0FBVyxFQUFFQyxZQUFZLFFBQVEsVUFBVTtBQUNoRSxTQUFTQyxJQUFJLFFBQVEsWUFBWTtBQUNqQyxTQUFTQyxvQkFBb0IsUUFBUSxnQkFBZ0I7QUFFckQsZ0ZBQWdGLEdBQ2hGLE9BQU8sTUFBTUMsY0FBYztJQUFDO0lBQVU7SUFBVztDQUFRLENBQVU7QUFFbkUsTUFBTUMsZUFBZTtBQUVyQixTQUFTQyxZQUFZQyxRQUFnQjtJQUNwQyxPQUNDQSxTQUFTQyxRQUFRLENBQUMsVUFDbEIsQ0FBQ0QsU0FBU0MsUUFBUSxDQUFDLGVBQ25CLENBQUNELFNBQVNDLFFBQVEsQ0FBQyxlQUNuQixDQUFDRCxTQUFTQyxRQUFRLENBQUM7QUFFckI7QUFFQSxrRkFBa0YsR0FDbEYsT0FBTyxTQUFTQyx3QkFBd0JDLE9BQWU7SUFDdEQsTUFBTUMsU0FBUyxJQUFJQztJQUNuQixLQUFLLE1BQU1DLFdBQVdWLHFCQUFxQk8sU0FBVTtRQUNwREksZUFBZVosS0FBS1EsU0FBUyxZQUFZRyxTQUFTLFFBQVFGO0lBQzNEO0lBQ0EsT0FBTztXQUFJQTtLQUFPLENBQUNJLElBQUk7QUFDeEI7QUFFQSxTQUFTRCxlQUFlRSxHQUFXLEVBQUVMLE1BQW1CO0lBQ3ZELElBQUksQ0FBQ1osV0FBV2lCLE1BQU07SUFDdEIsS0FBSyxNQUFNQyxTQUFTakIsWUFBWWdCLEtBQUs7UUFBRUUsZUFBZTtJQUFLLEdBQUk7UUFDOUQsTUFBTUMsT0FBT2pCLEtBQUtjLEtBQUtDLE1BQU1HLElBQUk7UUFDakMsSUFBSUgsTUFBTUksV0FBVyxJQUFJO1lBQ3hCUCxlQUFlSyxNQUFNUjtZQUNyQjtRQUNEO1FBQ0EsSUFBSSxDQUFDTSxNQUFNSyxNQUFNLE1BQU0sQ0FBQ2hCLFlBQVlXLE1BQU1HLElBQUksR0FBRztRQUNqRCxNQUFNRyxPQUFPdEIsYUFBYWtCLE1BQU07UUFDaEMsS0FBSyxNQUFNSyxTQUFTRCxLQUFLRSxRQUFRLENBQUNwQixjQUFlO1lBQ2hELE1BQU1xQixTQUFTRixLQUFLLENBQUMsRUFBRTtZQUN2QixJQUFJRSxVQUFVLFFBQVFBLFdBQVcsSUFBSTtZQUNyQyxNQUFNQyxVQUFVSCxLQUFLLENBQUMsRUFBRSxJQUFJO1lBQzVCYixPQUFPaUIsR0FBRyxDQUFDLEdBQUdGLE9BQU8sQ0FBQyxFQUFFQyxTQUFTO1FBQ2xDO0lBQ0Q7QUFDRDtBQUVBLDRGQUE0RixHQUM1RixPQUFPLFNBQVNFLGVBQ2ZDLFVBQTZCLEVBQzdCQyxRQUEyQjtJQUUzQixPQUFPO1dBQUksSUFBSW5CLElBQUk7ZUFBSW1CO2VBQWFEO1NBQVc7S0FBRSxDQUFDZixJQUFJO0FBQ3ZEO0FBRUEsT0FBTyxTQUFTaUIsdUJBQXVCQyxTQUE0QjtJQUNsRSxPQUFPO1dBQUk3QjtXQUFnQjZCO0tBQVUsQ0FBQy9CLElBQUksQ0FBQztBQUM1QyJ9