@decohere/scaffold 0.0.1-dev.126 → 0.0.1-dev.80

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 (154) hide show
  1. package/commonjs/src/add-api.action.js +3 -1
  2. package/commonjs/src/add-api.command.js +3 -1
  3. package/commonjs/src/add.command.js +3 -1
  4. package/commonjs/src/add.module.js +3 -1
  5. package/commonjs/src/cli.js +3 -2
  6. package/commonjs/src/create.command.js +3 -1
  7. package/commonjs/src/create.module.js +3 -1
  8. package/commonjs/src/domain/prompt.js +2 -0
  9. package/commonjs/src/index.js +2 -12
  10. package/commonjs/src/models/compose.model.js +3 -111
  11. package/commonjs/src/models/config-yaml.model.js +2 -0
  12. package/commonjs/src/models/const.js +2 -0
  13. package/commonjs/src/models/dev-container.model.js +10 -66
  14. package/commonjs/src/models/docker-image.model.js +6 -24
  15. package/commonjs/src/models/env-file.model.js +2 -0
  16. package/commonjs/src/models/gitignore.model.js +2 -7
  17. package/commonjs/src/models/launch-json.model.js +4 -0
  18. package/commonjs/src/models/package-json.model.js +7 -14
  19. package/commonjs/src/models/project.model.js +2 -0
  20. package/commonjs/src/models/source-file.js +2 -0
  21. package/commonjs/src/models/tsconfig.model.js +2 -0
  22. package/commonjs/src/models/vitest-config.model.js +2 -0
  23. package/commonjs/src/models/vscode-settings.model.js +2 -0
  24. package/commonjs/src/program.js +6 -13
  25. package/commonjs/src/resolve-target-dir.js +2 -0
  26. package/commonjs/src/services/scaffold.service.js +2 -0
  27. package/commonjs/src/version.js +2 -0
  28. package/commonjs/src/webapi/api-name.js +2 -0
  29. package/commonjs/src/webapi/cli-options.js +2 -0
  30. package/commonjs/src/webapi/const.js +3 -7
  31. package/commonjs/src/webapi/create-api.js +18 -46
  32. package/commonjs/src/webapi/devcontainer/codebase-rag-mcp.js +2 -0
  33. package/commonjs/src/webapi/devcontainer/host-scripts.js +2 -0
  34. package/commonjs/src/webapi/features/auth.feature.js +44 -11
  35. package/commonjs/src/webapi/features/auth0-cli.js +3 -40
  36. package/commonjs/src/webapi/features/biome-format.js +2 -0
  37. package/commonjs/src/webapi/features/database.feature.js +10 -10
  38. package/commonjs/src/webapi/features/finalize.feature.js +4 -2
  39. package/commonjs/src/webapi/features/postman.feature.js +2 -0
  40. package/commonjs/src/webapi/models/api-package-json.model.js +3 -1
  41. package/commonjs/src/webapi/models/auth-config.model.js +2 -0
  42. package/commonjs/src/webapi/models/controller-source-file.model.js +8 -5
  43. package/commonjs/src/webapi/models/github-ci.model.js +6 -6
  44. package/commonjs/src/webapi/models/main-source-file.model.js +5 -3
  45. package/commonjs/src/webapi/models/production-dockerfile.model.js +109 -27
  46. package/commonjs/src/webapi/models/sample-files.model.js +4 -2
  47. package/commonjs/src/webapi/models/webapi-image.model.js +2 -0
  48. package/commonjs/src/webapi/postman/hello-openapi.js +2 -0
  49. package/commonjs/src/webapi/postman/local-view.js +2 -0
  50. package/commonjs/src/webapi/postman/openapi-to-postman.js +8 -44
  51. package/commonjs/src/webapi/workspace-readme.js +5 -4
  52. package/commonjs/src/webapi.action.js +3 -1
  53. package/commonjs/src/webapi.command.js +4 -2
  54. package/es6/src/add-api.action.js +3 -1
  55. package/es6/src/add-api.command.js +3 -1
  56. package/es6/src/add.command.js +3 -1
  57. package/es6/src/add.module.js +3 -1
  58. package/es6/src/cli.js +3 -2
  59. package/es6/src/create.command.js +3 -1
  60. package/es6/src/create.module.js +3 -1
  61. package/es6/src/domain/prompt.js +2 -0
  62. package/es6/src/index.js +2 -3
  63. package/es6/src/models/compose.model.js +3 -113
  64. package/es6/src/models/config-yaml.model.js +2 -0
  65. package/es6/src/models/const.js +2 -0
  66. package/es6/src/models/dev-container.model.js +10 -66
  67. package/es6/src/models/docker-image.model.js +6 -24
  68. package/es6/src/models/env-file.model.js +2 -0
  69. package/es6/src/models/gitignore.model.js +2 -7
  70. package/es6/src/models/launch-json.model.js +4 -0
  71. package/es6/src/models/package-json.model.js +7 -11
  72. package/es6/src/models/project.model.js +2 -0
  73. package/es6/src/models/source-file.js +2 -0
  74. package/es6/src/models/tsconfig.model.js +2 -0
  75. package/es6/src/models/vitest-config.model.js +2 -0
  76. package/es6/src/models/vscode-settings.model.js +2 -0
  77. package/es6/src/program.js +7 -18
  78. package/es6/src/resolve-target-dir.js +2 -0
  79. package/es6/src/services/scaffold.service.js +2 -0
  80. package/es6/src/version.js +2 -0
  81. package/es6/src/webapi/api-name.js +2 -0
  82. package/es6/src/webapi/cli-options.js +2 -0
  83. package/es6/src/webapi/const.js +3 -4
  84. package/es6/src/webapi/create-api.js +20 -48
  85. package/es6/src/webapi/devcontainer/codebase-rag-mcp.js +2 -0
  86. package/es6/src/webapi/devcontainer/host-scripts.js +2 -0
  87. package/es6/src/webapi/features/auth.feature.js +44 -11
  88. package/es6/src/webapi/features/auth0-cli.js +4 -35
  89. package/es6/src/webapi/features/biome-format.js +2 -0
  90. package/es6/src/webapi/features/database.feature.js +10 -10
  91. package/es6/src/webapi/features/finalize.feature.js +4 -2
  92. package/es6/src/webapi/features/postman.feature.js +2 -0
  93. package/es6/src/webapi/models/api-package-json.model.js +4 -2
  94. package/es6/src/webapi/models/auth-config.model.js +2 -0
  95. package/es6/src/webapi/models/controller-source-file.model.js +8 -5
  96. package/es6/src/webapi/models/github-ci.model.js +6 -6
  97. package/es6/src/webapi/models/main-source-file.model.js +5 -3
  98. package/es6/src/webapi/models/production-dockerfile.model.js +117 -35
  99. package/es6/src/webapi/models/sample-files.model.js +4 -2
  100. package/es6/src/webapi/models/webapi-image.model.js +2 -0
  101. package/es6/src/webapi/postman/hello-openapi.js +2 -0
  102. package/es6/src/webapi/postman/local-view.js +2 -0
  103. package/es6/src/webapi/postman/openapi-to-postman.js +4 -4
  104. package/es6/src/webapi/workspace-readme.js +5 -4
  105. package/es6/src/webapi.action.js +3 -1
  106. package/es6/src/webapi.command.js +4 -2
  107. package/package.json +4 -14
  108. package/types/src/add-api.action.d.ts +1 -1
  109. package/types/src/add-api.command.d.ts +1 -1
  110. package/types/src/add.command.d.ts +2 -2
  111. package/types/src/add.module.d.ts +1 -1
  112. package/types/src/create.command.d.ts +2 -2
  113. package/types/src/create.module.d.ts +1 -1
  114. package/types/src/index.d.ts +0 -4
  115. package/types/src/models/compose.model.d.ts +0 -9
  116. package/types/src/models/dev-container.model.d.ts +1 -13
  117. package/types/src/models/docker-image.model.d.ts +0 -6
  118. package/types/src/models/gitignore.model.d.ts +0 -2
  119. package/types/src/models/package-json.model.d.ts +0 -1
  120. package/types/src/program.d.ts +1 -6
  121. package/types/src/webapi/const.d.ts +0 -2
  122. package/types/src/webapi/create-api.d.ts +1 -1
  123. package/types/src/webapi/features/auth0-cli.d.ts +0 -4
  124. package/types/src/webapi/models/api-package-json.model.d.ts +1 -1
  125. package/types/src/webapi/models/controller-source-file.model.d.ts +2 -2
  126. package/types/src/webapi/models/main-source-file.model.d.ts +1 -1
  127. package/types/src/webapi/models/production-dockerfile.model.d.ts +14 -9
  128. package/types/src/webapi.action.d.ts +1 -1
  129. package/types/src/webapi.command.d.ts +1 -1
  130. package/LICENSE +0 -15
  131. package/commonjs/src/auth0-configure.action.js +0 -28
  132. package/commonjs/src/auth0-configure.command.js +0 -24
  133. package/commonjs/src/auth0-login.action.js +0 -28
  134. package/commonjs/src/auth0-login.command.js +0 -23
  135. package/commonjs/src/auth0.command.js +0 -22
  136. package/commonjs/src/auth0.module.js +0 -28
  137. package/commonjs/src/webapi/auth0-commands.js +0 -250
  138. package/commonjs/src/webapi/authorize-scopes.js +0 -79
  139. package/es6/src/auth0-configure.action.js +0 -18
  140. package/es6/src/auth0-configure.command.js +0 -14
  141. package/es6/src/auth0-login.action.js +0 -18
  142. package/es6/src/auth0-login.command.js +0 -13
  143. package/es6/src/auth0.command.js +0 -12
  144. package/es6/src/auth0.module.js +0 -18
  145. package/es6/src/webapi/auth0-commands.js +0 -185
  146. package/es6/src/webapi/authorize-scopes.js +0 -55
  147. package/types/src/auth0-configure.action.d.ts +0 -7
  148. package/types/src/auth0-configure.command.d.ts +0 -6
  149. package/types/src/auth0-login.action.d.ts +0 -4
  150. package/types/src/auth0-login.command.d.ts +0 -6
  151. package/types/src/auth0.command.d.ts +0 -6
  152. package/types/src/auth0.module.d.ts +0 -18
  153. package/types/src/webapi/auth0-commands.d.ts +0 -11
  154. package/types/src/webapi/authorize-scopes.d.ts +0 -7
@@ -59,13 +59,7 @@ export declare class DockerfileModel implements KeyedModel {
59
59
  private readonly _layerWriters;
60
60
  private _fromImage;
61
61
  private _layerCounter;
62
- private _existing;
63
62
  constructor(baseImage: string);
64
- /**
65
- * Load an existing Dockerfile so `decohere add api` can append feature layers.
66
- * The new steps are appended as one block, unless the file already contains it.
67
- */
68
- static fromFile(absolutePath: string, filePath: string): DockerfileModel;
69
63
  from(baseImage: string): this;
70
64
  addLayer(layer: LayerWriter | string, order?: 5000): this;
71
65
  addStep(step: DockerStep): this;
@@ -2,8 +2,6 @@ import type { KeyedModel, SourceFile } from "./source-file.js";
2
2
  export declare class Gitignore implements KeyedModel {
3
3
  readonly key: string;
4
4
  private ignoreList;
5
- /** Load an existing .gitignore so `decohere add api` appends instead of replacing. */
6
- static fromFile(absolutePath: string): Gitignore;
7
5
  add(...patterns: string[]): this;
8
6
  files(): SourceFile[];
9
7
  }
@@ -33,4 +33,3 @@ export declare class PackageJson implements KeyedModel {
33
33
  }
34
34
  /** Stable A→Z key order for package.json dependency maps. */
35
35
  export declare function sortStringMap(map: Record<string, string>): Record<string, string>;
36
- export declare function packageScript(workspaceName: string, apiName: string): string;
@@ -1,8 +1,3 @@
1
1
  import { Command } from "commander";
2
2
  export declare function createProgram(): Command;
3
- /**
4
- * Runs the CLI and returns its exit code; the bin (`cli.ts`) exits with it. Returning instead
5
- * of calling `process.exit` here lets tests run it in process: a run that finished after its
6
- * test had timed out used to call `process.exit` in whichever test came next.
7
- */
8
- export declare function runCli(argv?: string[]): Promise<number>;
3
+ export declare function runCli(argv?: string[]): Promise<void>;
@@ -7,8 +7,6 @@ export declare function webapiProjectDir(name: string): string;
7
7
  * Keep in sync with root `package.json` `"start"` / `"start:<name>"` and Dockerfiles.
8
8
  */
9
9
  export declare function webapiReleaseEntry(name: string): string;
10
- /** The same entry inside `.package/` (`forge package`), which is what the Dockerfile runs. */
11
- export declare function webapiPackagedEntry(): string;
12
10
  /** npm package name for a scaffolded API (`flux serve --project`). */
13
11
  export declare function webapiPackageName(workspaceName: string, apiName: string): string;
14
12
  /** Local listen port for the nth API (0-based). Production uses `PORT`. */
@@ -1,7 +1,7 @@
1
1
  export { WEBAPI_PROJECT_DIR, WEBAPI_RELEASE_ENTRY } from "./const.js";
2
2
  export type ApiOptions = {
3
3
  d?: string;
4
- /** Host project name (directory basename). Required when scaffolding into the create-builder `/workspace` mount. */
4
+ /** Host project name (directory basename). Required when scaffolding into `/workspace`. */
5
5
  projectName?: string;
6
6
  /** API slugs under `projects/`. Default `["api"]`. Repeatable `--name`. */
7
7
  names?: string[];
@@ -12,7 +12,6 @@ export interface Auth0Tenant {
12
12
  }
13
13
  export declare function isInstalled(): boolean;
14
14
  export declare function listTenants(): Auth0Tenant[];
15
- /** Device/URL login (`--no-input`) so Docker can print a host-browser URL. */
16
15
  export declare function login(): boolean;
17
16
  export declare function listApis(): Array<{
18
17
  identifier: string;
@@ -21,9 +20,6 @@ export declare function listApis(): Array<{
21
20
  export declare function createApi(name: string, identifier: string, scopes?: readonly string[]): {
22
21
  identifier: string;
23
22
  };
24
- export declare function listApiScopes(identifier: string): string[];
25
- /** Assign API permissions to a user (Authorization Core). Idempotent when already granted. */
26
- export declare function assignUserPermissions(userId: string, audience: string, permissions: readonly string[]): void;
27
23
  /**
28
24
  * Replace an API's scopes and enable RBAC policy enforcement.
29
25
  * Auth0 CLI `--scopes` replaces the full set.
@@ -2,7 +2,7 @@ import type { KeyedModel, SourceFile } from "../../models/source-file.js";
2
2
  /**
3
3
  * Builder for `projects/<api>/package.json`.
4
4
  *
5
- * Starts with the core `@decohere/http` + `@decohere/crucible` deps. Features can call
5
+ * Starts with the core cortex + crucible deps. Features can call
6
6
  * `addDependency` / `addDevDependency` to extend.
7
7
  */
8
8
  export declare class ApiPackageJson implements KeyedModel {
@@ -29,14 +29,14 @@ export declare class ControllerSourceFile implements KeyedModel {
29
29
  private readonly _cortexImports;
30
30
  private readonly _extraImportGroups;
31
31
  private readonly _classDecorators;
32
- /** Explicit @inject(SampleService): using the class as a value keeps its import, which SWC can drop when the class is only a type (design:paramtypes then collapses to Object). */
32
+ /** Explicit @inject — design:paramtypes can collapse to Object under SWC when the class is still undefined at decorate time. */
33
33
  private readonly _ctorParams;
34
34
  private readonly _methods;
35
35
  /** Retrieve a method by name to mutate its decorators. */
36
36
  getMethod(name: string): ControllerMethod;
37
37
  /** Add a class-level decorator (e.g. `@Authorize`). */
38
38
  addDecorator(decorator: string): this;
39
- /** Add a named import from `@decohere/http`. */
39
+ /** Add a named import from `@decohere/cortex`. */
40
40
  addCortexImport(name: string, typeOnly?: boolean): this;
41
41
  /** Add a named import from any other module. */
42
42
  addImport(name: string, from: string, typeOnly?: boolean): this;
@@ -25,7 +25,7 @@ export declare class MainSourceFile implements KeyedModel {
25
25
  private _dataSourceName;
26
26
  private _typeOrmSeed;
27
27
  constructor(appName: string);
28
- /** Adds a bare side-effect import, e.g. `@decohere/http/auth`. */
28
+ /** Adds a bare side-effect import, e.g. `@decohere/cortex/auth`. */
29
29
  addSideEffectImport(path: string): this;
30
30
  /** Adds a named import, e.g. `import { Foo } from "bar"`. */
31
31
  addImport(name: string, from: string, typeOnly?: boolean): this;
@@ -1,18 +1,23 @@
1
1
  import type { KeyedModel, SourceFile } from "../../models/source-file.js";
2
+ export type ProductionDockerfileOptions = {
3
+ /** When true, only write `Dockerfile.<name>` (existing workspace — do not replace root Dockerfile). */
4
+ namedOnly?: boolean;
5
+ };
2
6
  /**
3
- * Production Dockerfile for each API, in the API's own folder: `projects/<name>/Dockerfile`.
4
- * That is where `forge docker` and `forge package` look for a deployable, and the folder is
5
- * the Docker build context.
7
+ * Production Dockerfiles for PaaS (Railway/Fly) and local `docker build`.
6
8
  *
7
- * The image copies `.package/`, which `forge package` writes before Docker runs: the API's
8
- * compiled code, the workspace libraries it imports, and a real (symlink-free) `node_modules`
9
- * of the third-party packages it reaches. So the image build installs nothing, runs no
10
- * workspace tooling, and needs no npm token.
9
+ * Context is always the **repo root** (`docker build -f Dockerfile.billing .`).
10
+ * Root `Dockerfile` is the first API (`pnpm start`). Extra or custom-named APIs
11
+ * also get `Dockerfile.<name>` so each service can be deployed on its own.
12
+ *
13
+ * Runtime `node_modules` come from a **prod-deps** stage (`pnpm install --prod`),
14
+ * not the full build install (Forge, TypeScript, Biome, Vitest).
11
15
  */
12
16
  export declare class WebapiProductionDockerfile implements KeyedModel {
13
17
  private readonly apiNames;
18
+ private readonly options;
14
19
  readonly key: string;
15
- constructor(apiNames?: readonly string[]);
20
+ constructor(apiNames?: readonly string[], options?: ProductionDockerfileOptions);
16
21
  files(): SourceFile[];
17
22
  }
18
- export declare function renderProductionDockerfile(apiName: string): string;
23
+ export declare function renderProductionDockerfile(apiName: string, startScript: string): string;
@@ -1,4 +1,4 @@
1
- import { type Action, ActionResponse } from "@decohere/devkit/cli";
1
+ import { type Action, ActionResponse } from "@decohere/nexus/cli";
2
2
  export type WebapiOptions = {
3
3
  directory?: string;
4
4
  d?: string;
@@ -1,4 +1,4 @@
1
- import { DecohereCommand } from "@decohere/devkit/cli";
1
+ import { DecohereCommand } from "@decohere/nexus/cli";
2
2
  import { WebapiAction } from "./webapi.action.js";
3
3
  export declare class WebapiCommand extends DecohereCommand {
4
4
  get actions(): (typeof WebapiAction)[];
package/LICENSE DELETED
@@ -1,15 +0,0 @@
1
- ISC License
2
-
3
- Copyright (c) 2025-2026 Typesmiths
4
-
5
- Permission to use, copy, modify, and/or distribute this software for any
6
- purpose with or without fee is hereby granted, provided that the above
7
- copyright notice and this permission notice appear in all copies.
8
-
9
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
@@ -1,28 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- Object.defineProperty(exports, "Auth0ConfigureAction", {
6
- enumerable: true,
7
- get: function() {
8
- return Auth0ConfigureAction;
9
- }
10
- });
11
- const _decorators = require("@decohere/crucible/decorators");
12
- const _cli = require("@decohere/devkit/cli");
13
- const _auth0commands = require("./webapi/auth0-commands.js");
14
- function _ts_decorate(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
- class Auth0ConfigureAction {
21
- async run(options) {
22
- (0, _auth0commands.runAuth0Configure)(typeof options.d === "string" ? options.d : ".");
23
- return _cli.ActionResponse.Success("configure");
24
- }
25
- }
26
- Auth0ConfigureAction = _ts_decorate([
27
- (0, _decorators.injectable)()
28
- ], Auth0ConfigureAction);
@@ -1,24 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- Object.defineProperty(exports, "Auth0ConfigureCommand", {
6
- enumerable: true,
7
- get: function() {
8
- return Auth0ConfigureCommand;
9
- }
10
- });
11
- const _cli = require("@decohere/devkit/cli");
12
- const _auth0configureaction = require("./auth0-configure.action.js");
13
- class Auth0ConfigureCommand extends _cli.DecohereCommand {
14
- get actions() {
15
- return [
16
- _auth0configureaction.Auth0ConfigureAction
17
- ];
18
- }
19
- constructor(name){
20
- super(name);
21
- this.description("Update Auth0 API permissions and Postman SPA from @Authorize in this workspace");
22
- this.option("-d <directory>", "Workspace directory (default: current directory)", ".");
23
- }
24
- }
@@ -1,28 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- Object.defineProperty(exports, "Auth0LoginAction", {
6
- enumerable: true,
7
- get: function() {
8
- return Auth0LoginAction;
9
- }
10
- });
11
- const _decorators = require("@decohere/crucible/decorators");
12
- const _cli = require("@decohere/devkit/cli");
13
- const _auth0commands = require("./webapi/auth0-commands.js");
14
- function _ts_decorate(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
- class Auth0LoginAction {
21
- async run() {
22
- (0, _auth0commands.runAuth0Login)();
23
- return _cli.ActionResponse.Success("login");
24
- }
25
- }
26
- Auth0LoginAction = _ts_decorate([
27
- (0, _decorators.injectable)()
28
- ], Auth0LoginAction);
@@ -1,23 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- Object.defineProperty(exports, "Auth0LoginCommand", {
6
- enumerable: true,
7
- get: function() {
8
- return Auth0LoginCommand;
9
- }
10
- });
11
- const _cli = require("@decohere/devkit/cli");
12
- const _auth0loginaction = require("./auth0-login.action.js");
13
- class Auth0LoginCommand extends _cli.DecohereCommand {
14
- get actions() {
15
- return [
16
- _auth0loginaction.Auth0LoginAction
17
- ];
18
- }
19
- constructor(name){
20
- super(name);
21
- this.description("Authenticate the Auth0 CLI (device URL; tokens persist on the host)");
22
- }
23
- }
@@ -1,22 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- Object.defineProperty(exports, "Auth0Command", {
6
- enumerable: true,
7
- get: function() {
8
- return Auth0Command;
9
- }
10
- });
11
- const _cli = require("@decohere/devkit/cli");
12
- class Auth0Command extends _cli.DecohereCommand {
13
- constructor(commands, handler){
14
- super(Auth0Command);
15
- this.description("Log in to Auth0 and update a scaffolded client");
16
- this.exitOverride();
17
- this.registerSubcommand(commands, handler);
18
- }
19
- run(_actions, _options) {
20
- return this.help();
21
- }
22
- }
@@ -1,28 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- Object.defineProperty(exports, "Auth0Module", {
6
- enumerable: true,
7
- get: function() {
8
- return Auth0Module;
9
- }
10
- });
11
- const _cli = require("@decohere/devkit/cli");
12
- const _auth0command = require("./auth0.command.js");
13
- const _auth0configureaction = require("./auth0-configure.action.js");
14
- const _auth0configurecommand = require("./auth0-configure.command.js");
15
- const _auth0loginaction = require("./auth0-login.action.js");
16
- const _auth0logincommand = require("./auth0-login.command.js");
17
- class Auth0Module extends _cli.ModuleManifest {
18
- id = "auth0";
19
- command = _auth0command.Auth0Command;
20
- commands = {
21
- login: _auth0logincommand.Auth0LoginCommand,
22
- configure: _auth0configurecommand.Auth0ConfigureCommand
23
- };
24
- actions = {
25
- login: _auth0loginaction.Auth0LoginAction,
26
- configure: _auth0configureaction.Auth0ConfigureAction
27
- };
28
- }
@@ -1,250 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- function _export(target, all) {
6
- for(var name in all)Object.defineProperty(target, name, {
7
- enumerable: true,
8
- get: Object.getOwnPropertyDescriptor(all, name).get
9
- });
10
- }
11
- _export(exports, {
12
- get AUTH0_CLI_INSTALL_MESSAGE () {
13
- return AUTH0_CLI_INSTALL_MESSAGE;
14
- },
15
- get ensureLoggedIn () {
16
- return ensureLoggedIn;
17
- },
18
- get requireInstalled () {
19
- return requireInstalled;
20
- },
21
- get runAuth0Configure () {
22
- return runAuth0Configure;
23
- },
24
- get runAuth0Login () {
25
- return runAuth0Login;
26
- }
27
- });
28
- const _nodefs = require("node:fs");
29
- const _nodepath = require("node:path");
30
- const _apiname = require("./api-name.js");
31
- const _authorizescopes = require("./authorize-scopes.js");
32
- const _auth0cli = /*#__PURE__*/ _interop_require_wildcard(require("./features/auth0-cli.js"));
33
- function _getRequireWildcardCache(nodeInterop) {
34
- if (typeof WeakMap !== "function") return null;
35
- var cacheBabelInterop = new WeakMap();
36
- var cacheNodeInterop = new WeakMap();
37
- return (_getRequireWildcardCache = function(nodeInterop) {
38
- return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
39
- })(nodeInterop);
40
- }
41
- function _interop_require_wildcard(obj, nodeInterop) {
42
- if (!nodeInterop && obj && obj.__esModule) {
43
- return obj;
44
- }
45
- if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
46
- return {
47
- default: obj
48
- };
49
- }
50
- var cache = _getRequireWildcardCache(nodeInterop);
51
- if (cache && cache.has(obj)) {
52
- return cache.get(obj);
53
- }
54
- var newObj = {
55
- __proto__: null
56
- };
57
- var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
58
- for(var key in obj){
59
- if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
60
- var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
61
- if (desc && (desc.get || desc.set)) {
62
- Object.defineProperty(newObj, key, desc);
63
- } else {
64
- newObj[key] = obj[key];
65
- }
66
- }
67
- }
68
- newObj.default = obj;
69
- if (cache) {
70
- cache.set(obj, newObj);
71
- }
72
- return newObj;
73
- }
74
- /** Same Postman OAuth callbacks as `PostmanFeature`. */ const POSTMAN_CALLBACKS = [
75
- "https://oauth.pstmn.io/v1/callback",
76
- "https://oauth.pstmn.io/v1/browser-callback"
77
- ];
78
- const SPA_SUFFIX = " Postman";
79
- 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";
80
- function fail(message) {
81
- throw new _apiname.CreateCliError(message);
82
- }
83
- function requireInstalled() {
84
- if (_auth0cli.isInstalled()) return;
85
- fail(AUTH0_CLI_INSTALL_MESSAGE);
86
- }
87
- function ensureLoggedIn() {
88
- requireInstalled();
89
- process.stdout.write("\n Checking Auth0 credentials...");
90
- let tenants = _auth0cli.listTenants();
91
- if (tenants.length === 0) {
92
- process.stdout.write(" not logged in.\n");
93
- console.log(" Logging in to Auth0 (open the URL in your browser)...");
94
- if (!_auth0cli.login()) fail("Auth0 login failed.");
95
- tenants = _auth0cli.listTenants();
96
- }
97
- try {
98
- _auth0cli.listApis();
99
- process.stdout.write(" ok.\n");
100
- } catch (err) {
101
- if (err instanceof _auth0cli.Auth0AuthError) {
102
- process.stdout.write(" token expired.\n");
103
- console.log(" Re-authenticating (open the URL in your browser)...");
104
- if (!_auth0cli.login()) fail("Auth0 login failed.");
105
- tenants = _auth0cli.listTenants();
106
- }
107
- }
108
- const active = tenants.find((t)=>t.active) ?? tenants[0];
109
- if (active == null) fail("No Auth0 tenant after login.");
110
- return active;
111
- }
112
- function runAuth0Login() {
113
- requireInstalled();
114
- console.log(" Logging in to Auth0 (open the URL in your browser)...");
115
- if (!_auth0cli.login()) fail("Auth0 login failed.");
116
- const tenants = _auth0cli.listTenants();
117
- const active = tenants.find((t)=>t.active) ?? tenants[0];
118
- if (active == null) fail("No Auth0 tenant after login.");
119
- console.log(`\n ✓ Auth0 tenant: https://${active.name}`);
120
- console.log(" Tokens are stored in ~/.config/auth0 (mounted into the create image).");
121
- console.log(" Next: npx @decohere/create auth0 configure");
122
- }
123
- function runAuth0Configure(directory = ".") {
124
- const targetDir = (0, _nodepath.resolve)(directory);
125
- if (!(0, _apiname.isDecohereWorkspace)(targetDir)) {
126
- throw new _apiname.CreateCliError(`Not a Decohere workspace: ${targetDir}. Scaffold one first with \`npx @decohere/create webapi\`.`);
127
- }
128
- const active = ensureLoggedIn();
129
- const issuerBaseUrl = `https://${active.name}`;
130
- const projectName = process.env.DECOHERE_PROJECT_NAME?.trim() || (0, _nodepath.basename)(targetDir);
131
- const envPath = (0, _nodepath.join)(targetDir, ".env");
132
- const existing = readEnvFile(envPath);
133
- const existingAudience = existing.AUTH0_AUDIENCE?.trim();
134
- const discovered = (0, _authorizescopes.discoverAuthorizeScopes)(targetDir);
135
- let existingScopes = [];
136
- if (existingAudience) {
137
- try {
138
- existingScopes = _auth0cli.listApiScopes(existingAudience);
139
- } catch (err) {
140
- if (err instanceof _auth0cli.Auth0AuthError) throw err;
141
- }
142
- }
143
- const apiScopes = resolveApiScopes(discovered, existingScopes);
144
- console.log(discovered.length > 0 ? ` ✓ Scanned @Authorize — ${discovered.length} scope(s) from controllers` : " ✓ No @Authorize in projects/*/src — keeping existing / Hello scopes");
145
- let audience = existingAudience;
146
- if (audience) {
147
- try {
148
- _auth0cli.updateApiScopes(audience, apiScopes);
149
- console.log(` ✓ API scopes ensured (${apiScopes.join(", ")})`);
150
- } catch (err) {
151
- console.error(` ✗ Failed to update API scopes: ${err instanceof Error ? err.message : err}`);
152
- }
153
- } else {
154
- const identifier = `https://api.${projectName}`;
155
- console.log(`\n Creating Auth0 API ${identifier}...`);
156
- audience = _auth0cli.createApi(`${projectName} API`, identifier, apiScopes).identifier;
157
- console.log(` ✓ API created: ${audience}`);
158
- }
159
- const appName = `${projectName}${SPA_SUFFIX}`;
160
- const app = _auth0cli.ensureSpaApp(appName, [
161
- ...POSTMAN_CALLBACKS
162
- ]);
163
- console.log(app.reused ? ` ✓ Reusing Auth0 SPA app (${app.client_id})` : ` ✓ Auth0 SPA app created (${app.client_id})`);
164
- try {
165
- _auth0cli.enableConnectionForClient(_auth0cli.DB_CONNECTION_NAME, app.client_id);
166
- console.log(` ✓ Enabled ${_auth0cli.DB_CONNECTION_NAME} on SPA`);
167
- } catch (err) {
168
- console.error(` ✗ Failed to enable DB connection on SPA: ${err instanceof Error ? err.message : err}`);
169
- }
170
- upsertEnv(envPath, {
171
- AUTH0_ISSUER_BASE_URL: issuerBaseUrl,
172
- AUTH0_AUDIENCE: audience
173
- });
174
- console.log(` ✓ Wrote AUTH0_ISSUER_BASE_URL and AUTH0_AUDIENCE to .env`);
175
- const adminSub = existing.AUTH0_ADMIN_USER_SUB?.trim();
176
- if (adminSub) {
177
- try {
178
- _auth0cli.assignUserPermissions(adminSub, audience, apiScopes);
179
- console.log(` ✓ Assigned ${apiScopes.length} API permission(s) to admin user`);
180
- } catch (err) {
181
- console.error(` ✗ Failed to assign admin permissions: ${err instanceof Error ? err.message : err}`);
182
- }
183
- }
184
- const domain = issuerBaseUrl.replace(/^https?:\/\//, "");
185
- patchPostmanAuth(targetDir, projectName, {
186
- domain,
187
- audience,
188
- clientId: app.client_id,
189
- scopes: (0, _authorizescopes.postmanRequestedScopes)(apiScopes)
190
- });
191
- }
192
- function readEnvFile(path) {
193
- if (!(0, _nodefs.existsSync)(path)) return {};
194
- const out = {};
195
- for (const line of (0, _nodefs.readFileSync)(path, "utf8").split("\n")){
196
- const trimmed = line.trim();
197
- if (trimmed === "" || trimmed.startsWith("#")) continue;
198
- const eq = line.indexOf("=");
199
- if (eq <= 0) continue;
200
- out[line.slice(0, eq).trim()] = line.slice(eq + 1);
201
- }
202
- return out;
203
- }
204
- function resolveApiScopes(discovered, existing) {
205
- const merged = (0, _authorizescopes.mergeApiScopes)(discovered, existing);
206
- return merged.length > 0 ? merged : [
207
- ..._auth0cli.HELLO_API_SCOPES
208
- ].sort();
209
- }
210
- function upsertEnv(path, entries) {
211
- let text = (0, _nodefs.existsSync)(path) ? (0, _nodefs.readFileSync)(path, "utf8") : "";
212
- for (const [key, value] of Object.entries(entries)){
213
- const re = new RegExp(`^${key}=.*$`, "m");
214
- if (re.test(text)) {
215
- text = text.replace(re, `${key}=${value}`);
216
- } else {
217
- text = `${text}${text === "" || text.endsWith("\n") ? "" : "\n"}${key}=${value}\n`;
218
- }
219
- }
220
- if (text !== "" && !text.endsWith("\n")) text = `${text}\n`;
221
- (0, _nodefs.writeFileSync)(path, text);
222
- }
223
- function patchPostmanAuth(targetDir, projectName, auth) {
224
- const envYaml = (0, _nodepath.join)(targetDir, "postman/environments", `${projectName}-Local.environment.yaml`);
225
- if ((0, _nodefs.existsSync)(envYaml)) {
226
- let yaml = (0, _nodefs.readFileSync)(envYaml, "utf8");
227
- yaml = replaceYamlKeyedValue(yaml, "auth0Domain", auth.domain);
228
- yaml = replaceYamlKeyedValue(yaml, "auth0Audience", auth.audience);
229
- yaml = replaceYamlKeyedValue(yaml, "auth0ClientId", auth.clientId);
230
- yaml = replaceYamlKeyedValue(yaml, "authUrl", `https://${auth.domain}/authorize?audience=${auth.audience}`);
231
- yaml = replaceYamlKeyedValue(yaml, "accessTokenUrl", `https://${auth.domain}/oauth/token`);
232
- yaml = replaceYamlKeyedValue(yaml, "scope", auth.scopes);
233
- (0, _nodefs.writeFileSync)(envYaml, yaml);
234
- console.log(` ✓ Updated Postman environment auth0ClientId (${auth.clientId})`);
235
- console.log(` ✓ Updated Postman token scopes`);
236
- }
237
- const collectionDef = (0, _nodepath.join)(targetDir, "postman/collections", `${projectName} WebAPI`, ".resources/definition.yaml");
238
- if ((0, _nodefs.existsSync)(collectionDef)) {
239
- let yaml = (0, _nodefs.readFileSync)(collectionDef, "utf8");
240
- yaml = yaml.replace(/^(\s*clientId:\s*).+$/m, `$1${JSON.stringify(auth.clientId)}`);
241
- yaml = yaml.replace(/^(\s*scope:\s*).+$/m, `$1${JSON.stringify(auth.scopes)}`);
242
- (0, _nodefs.writeFileSync)(collectionDef, yaml);
243
- }
244
- }
245
- /** Replace `key: <name>` / `value: …` pairs in Postman Local View environment YAML. */ function replaceYamlKeyedValue(yaml, key, value) {
246
- const quoted = JSON.stringify(value);
247
- const re = new RegExp(`(key:\\s*${key}\\s*\\n\\s*value:\\s*)[^\\n]+`, "m");
248
- if (!re.test(yaml)) return yaml;
249
- return yaml.replace(re, `$1${quoted}`);
250
- }