@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.
- package/commonjs/src/add-api.action.js +3 -1
- package/commonjs/src/add-api.command.js +3 -1
- package/commonjs/src/add.command.js +3 -1
- package/commonjs/src/add.module.js +3 -1
- package/commonjs/src/cli.js +3 -2
- package/commonjs/src/create.command.js +3 -1
- package/commonjs/src/create.module.js +3 -1
- package/commonjs/src/domain/prompt.js +2 -0
- package/commonjs/src/index.js +2 -12
- package/commonjs/src/models/compose.model.js +3 -111
- package/commonjs/src/models/config-yaml.model.js +2 -0
- package/commonjs/src/models/const.js +2 -0
- package/commonjs/src/models/dev-container.model.js +10 -66
- package/commonjs/src/models/docker-image.model.js +6 -24
- package/commonjs/src/models/env-file.model.js +2 -0
- package/commonjs/src/models/gitignore.model.js +2 -7
- package/commonjs/src/models/launch-json.model.js +4 -0
- package/commonjs/src/models/package-json.model.js +7 -14
- package/commonjs/src/models/project.model.js +2 -0
- package/commonjs/src/models/source-file.js +2 -0
- package/commonjs/src/models/tsconfig.model.js +2 -0
- package/commonjs/src/models/vitest-config.model.js +2 -0
- package/commonjs/src/models/vscode-settings.model.js +2 -0
- package/commonjs/src/program.js +6 -13
- package/commonjs/src/resolve-target-dir.js +2 -0
- package/commonjs/src/services/scaffold.service.js +2 -0
- package/commonjs/src/version.js +2 -0
- package/commonjs/src/webapi/api-name.js +2 -0
- package/commonjs/src/webapi/cli-options.js +2 -0
- package/commonjs/src/webapi/const.js +3 -7
- package/commonjs/src/webapi/create-api.js +18 -46
- package/commonjs/src/webapi/devcontainer/codebase-rag-mcp.js +2 -0
- package/commonjs/src/webapi/devcontainer/host-scripts.js +2 -0
- package/commonjs/src/webapi/features/auth.feature.js +44 -11
- package/commonjs/src/webapi/features/auth0-cli.js +3 -40
- package/commonjs/src/webapi/features/biome-format.js +2 -0
- package/commonjs/src/webapi/features/database.feature.js +10 -10
- package/commonjs/src/webapi/features/finalize.feature.js +4 -2
- package/commonjs/src/webapi/features/postman.feature.js +2 -0
- package/commonjs/src/webapi/models/api-package-json.model.js +3 -1
- package/commonjs/src/webapi/models/auth-config.model.js +2 -0
- package/commonjs/src/webapi/models/controller-source-file.model.js +8 -5
- package/commonjs/src/webapi/models/github-ci.model.js +6 -6
- package/commonjs/src/webapi/models/main-source-file.model.js +5 -3
- package/commonjs/src/webapi/models/production-dockerfile.model.js +109 -27
- package/commonjs/src/webapi/models/sample-files.model.js +4 -2
- package/commonjs/src/webapi/models/webapi-image.model.js +2 -0
- package/commonjs/src/webapi/postman/hello-openapi.js +2 -0
- package/commonjs/src/webapi/postman/local-view.js +2 -0
- package/commonjs/src/webapi/postman/openapi-to-postman.js +8 -44
- package/commonjs/src/webapi/workspace-readme.js +5 -4
- package/commonjs/src/webapi.action.js +3 -1
- package/commonjs/src/webapi.command.js +4 -2
- package/es6/src/add-api.action.js +3 -1
- package/es6/src/add-api.command.js +3 -1
- package/es6/src/add.command.js +3 -1
- package/es6/src/add.module.js +3 -1
- package/es6/src/cli.js +3 -2
- package/es6/src/create.command.js +3 -1
- package/es6/src/create.module.js +3 -1
- package/es6/src/domain/prompt.js +2 -0
- package/es6/src/index.js +2 -3
- package/es6/src/models/compose.model.js +3 -113
- package/es6/src/models/config-yaml.model.js +2 -0
- package/es6/src/models/const.js +2 -0
- package/es6/src/models/dev-container.model.js +10 -66
- package/es6/src/models/docker-image.model.js +6 -24
- package/es6/src/models/env-file.model.js +2 -0
- package/es6/src/models/gitignore.model.js +2 -7
- package/es6/src/models/launch-json.model.js +4 -0
- package/es6/src/models/package-json.model.js +7 -11
- package/es6/src/models/project.model.js +2 -0
- package/es6/src/models/source-file.js +2 -0
- package/es6/src/models/tsconfig.model.js +2 -0
- package/es6/src/models/vitest-config.model.js +2 -0
- package/es6/src/models/vscode-settings.model.js +2 -0
- package/es6/src/program.js +7 -18
- package/es6/src/resolve-target-dir.js +2 -0
- package/es6/src/services/scaffold.service.js +2 -0
- package/es6/src/version.js +2 -0
- package/es6/src/webapi/api-name.js +2 -0
- package/es6/src/webapi/cli-options.js +2 -0
- package/es6/src/webapi/const.js +3 -4
- package/es6/src/webapi/create-api.js +20 -48
- package/es6/src/webapi/devcontainer/codebase-rag-mcp.js +2 -0
- package/es6/src/webapi/devcontainer/host-scripts.js +2 -0
- package/es6/src/webapi/features/auth.feature.js +44 -11
- package/es6/src/webapi/features/auth0-cli.js +4 -35
- package/es6/src/webapi/features/biome-format.js +2 -0
- package/es6/src/webapi/features/database.feature.js +10 -10
- package/es6/src/webapi/features/finalize.feature.js +4 -2
- package/es6/src/webapi/features/postman.feature.js +2 -0
- package/es6/src/webapi/models/api-package-json.model.js +4 -2
- package/es6/src/webapi/models/auth-config.model.js +2 -0
- package/es6/src/webapi/models/controller-source-file.model.js +8 -5
- package/es6/src/webapi/models/github-ci.model.js +6 -6
- package/es6/src/webapi/models/main-source-file.model.js +5 -3
- package/es6/src/webapi/models/production-dockerfile.model.js +117 -35
- package/es6/src/webapi/models/sample-files.model.js +4 -2
- package/es6/src/webapi/models/webapi-image.model.js +2 -0
- package/es6/src/webapi/postman/hello-openapi.js +2 -0
- package/es6/src/webapi/postman/local-view.js +2 -0
- package/es6/src/webapi/postman/openapi-to-postman.js +4 -4
- package/es6/src/webapi/workspace-readme.js +5 -4
- package/es6/src/webapi.action.js +3 -1
- package/es6/src/webapi.command.js +4 -2
- package/package.json +4 -14
- package/types/src/add-api.action.d.ts +1 -1
- package/types/src/add-api.command.d.ts +1 -1
- package/types/src/add.command.d.ts +2 -2
- package/types/src/add.module.d.ts +1 -1
- package/types/src/create.command.d.ts +2 -2
- package/types/src/create.module.d.ts +1 -1
- package/types/src/index.d.ts +0 -4
- package/types/src/models/compose.model.d.ts +0 -9
- package/types/src/models/dev-container.model.d.ts +1 -13
- package/types/src/models/docker-image.model.d.ts +0 -6
- package/types/src/models/gitignore.model.d.ts +0 -2
- package/types/src/models/package-json.model.d.ts +0 -1
- package/types/src/program.d.ts +1 -6
- package/types/src/webapi/const.d.ts +0 -2
- package/types/src/webapi/create-api.d.ts +1 -1
- package/types/src/webapi/features/auth0-cli.d.ts +0 -4
- package/types/src/webapi/models/api-package-json.model.d.ts +1 -1
- package/types/src/webapi/models/controller-source-file.model.d.ts +2 -2
- package/types/src/webapi/models/main-source-file.model.d.ts +1 -1
- package/types/src/webapi/models/production-dockerfile.model.d.ts +14 -9
- package/types/src/webapi.action.d.ts +1 -1
- package/types/src/webapi.command.d.ts +1 -1
- package/LICENSE +0 -15
- package/commonjs/src/auth0-configure.action.js +0 -28
- package/commonjs/src/auth0-configure.command.js +0 -24
- package/commonjs/src/auth0-login.action.js +0 -28
- package/commonjs/src/auth0-login.command.js +0 -23
- package/commonjs/src/auth0.command.js +0 -22
- package/commonjs/src/auth0.module.js +0 -28
- package/commonjs/src/webapi/auth0-commands.js +0 -250
- package/commonjs/src/webapi/authorize-scopes.js +0 -79
- package/es6/src/auth0-configure.action.js +0 -18
- package/es6/src/auth0-configure.command.js +0 -14
- package/es6/src/auth0-login.action.js +0 -18
- package/es6/src/auth0-login.command.js +0 -13
- package/es6/src/auth0.command.js +0 -12
- package/es6/src/auth0.module.js +0 -18
- package/es6/src/webapi/auth0-commands.js +0 -185
- package/es6/src/webapi/authorize-scopes.js +0 -55
- package/types/src/auth0-configure.action.d.ts +0 -7
- package/types/src/auth0-configure.command.d.ts +0 -6
- package/types/src/auth0-login.action.d.ts +0 -4
- package/types/src/auth0-login.command.d.ts +0 -6
- package/types/src/auth0.command.d.ts +0 -6
- package/types/src/auth0.module.d.ts +0 -18
- package/types/src/webapi/auth0-commands.d.ts +0 -11
- 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;
|
package/types/src/program.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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/
|
|
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/
|
|
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
|
|
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
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
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;
|
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
|
-
}
|