@antelopejs/dms-frontend 0.1.9 → 0.2.1

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/README.md CHANGED
@@ -44,7 +44,7 @@ making the template root (`src/materialize.ts`) and the manifest query
44
44
  `--renderer` flag and no renderer registry; the single-renderer assumption is
45
45
  deliberate until a second renderer exists. Whatever a renderer names its module
46
46
  entry is its own convention: `dms.frontend.ts` and the
47
- `#dms-inertia/frontend-module` alias belong to the Vue renderer, not to the
47
+ `#dms/frontend-module` alias belong to the Vue renderer, not to the
48
48
  loader.
49
49
 
50
50
  ## Application ownership
@@ -104,7 +104,7 @@ Manifest negotiation and module materialization are the renderer contract descri
104
104
 
105
105
  The generated Vue application uses `@inertiajs/vue3`, `@nuxt/ui/vite` with `{ router: "inertia" }`, and `@nuxt/ui/vue-plugin`. The Node server resolves each Inertia visit through `/dms/page?path=…`, including fresh shared data so account, tenant, and permission changes update navigation state. It proxies backend routes and manages authentication through server-side sessions. `DMS_BOOTSTRAP_SECRET` is used only by the CLI's server-to-server frontend manifest and module archive requests and is never sent by, or exposed to, browser traffic.
106
106
 
107
- Vue modules use `dms.frontend.ts` and the `#dms-inertia/frontend-module` SDK alias, which replaces the former `#cms-inertia` alias and is the import path every DMS frontend module now uses. Email templates register separately through `dms.email.ts`.
107
+ Vue modules register through `dms.frontend.ts` and import the SDK from the `#dms/frontend-module` alias, which the loader resolves to the generated `frontend-module.ts`: `defineDmsPlugin`, `useDmsRouter`, the page and session types, and everything else a module needs from the host. Email templates register separately through `dms.email.ts`.
108
108
 
109
109
  An email entry exports `serverEmailTemplates` and may export a plain `appConfig` object, such as shared branding defaults. Email rendering merges these configurations in manifest-priority order and provides them to `useDmsAppConfig` per render. Public runtime options come from the module manifest; `DMS_CLIENT_BASE_URL` overrides `public.dms.clientBaseUrl`. Email entries must not import the browser frontend module.
110
110
 
@@ -117,7 +117,7 @@ A materialized module opts into the Vue adapter with a root `dms.frontend.ts`:
117
117
  ```ts
118
118
  import MyBlock from "./components/MyBlock.vue";
119
119
  import MyPage from "./pages/MyPage.vue";
120
- import type { DmsFrontendModule } from "../../frontend-module";
120
+ import type { DmsFrontendModule } from "#dms/frontend-module";
121
121
 
122
122
  const frontendModule: DmsFrontendModule = {
123
123
  setup(sdk) {
@@ -163,11 +163,13 @@ started by `dev`, and the production server started by `start`, because those
163
163
  child processes inherit the environment. A missing file is not an error; an
164
164
  unreadable one is reported and skipped.
165
165
 
166
- `DMS_SESSION_SECRET` is mandatory for anything that touches a session. The
167
- generated server encrypts its session cookie with it, and with no value — or
168
- one shorter than 32 characters the login page at `/auth` fails the first
169
- sign-in attempt rather than starting degraded. Generate one with
170
- `openssl rand -hex 32`.
166
+ `ajs dms dev` generates a fresh ephemeral 32-byte secret when
167
+ `DMS_SESSION_SECRET` is absent; all sessions are invalidated when that dev
168
+ server restarts. An explicit value is preserved, but empty or shorter than 32
169
+ characters is rejected. `build` and `start` require a configured secret and
170
+ never generate one, which is required for production so sessions survive
171
+ restarts. The generated server also validates the value as a safety net.
172
+ Generate one with `openssl rand -hex 32`.
171
173
 
172
174
  ### Opening a session from a module flow
173
175
 
@@ -21,6 +21,7 @@ function cmdBuild() {
21
21
  (0, cli_ui_1.error)("Backend URL is required. Use -b <url> or set DMS_API_BASE_URL.");
22
22
  process.exit(1);
23
23
  }
24
+ const sessionSecret = (0, common_1.resolveSessionSecret)("build");
24
25
  const spinner = new cli_ui_1.Spinner("Setting up workspace...");
25
26
  await spinner.start();
26
27
  try {
@@ -44,6 +45,7 @@ function cmdBuild() {
44
45
  cwd: workspaceDir,
45
46
  env: {
46
47
  ...process.env,
48
+ DMS_SESSION_SECRET: sessionSecret,
47
49
  NODE_OPTIONS: "--max-old-space-size=4096",
48
50
  NODE_PATH: nodeModulesDir,
49
51
  },
@@ -44,6 +44,7 @@ function cmdDev() {
44
44
  .action(async (options) => {
45
45
  const { backendUrl, workspaceKey } = resolveBackend(options);
46
46
  const bootstrapSecret = (0, common_1.resolveBootstrapSecret)(options.bootstrapSecret, backendUrl);
47
+ const sessionSecret = (0, common_1.resolveSessionSecret)("dev");
47
48
  const requestedPort = Number.parseInt(options.port, 10);
48
49
  if (Number.isNaN(requestedPort)) {
49
50
  (0, cli_ui_1.error)(`Invalid port: ${options.port}`);
@@ -101,6 +102,7 @@ function cmdDev() {
101
102
  DMS_COOKIE_SECURE: process.env.DMS_COOKIE_SECURE ?? "false",
102
103
  DMS_API_BASE_URL: backendUrl,
103
104
  DMS_BOOTSTRAP_SECRET: bootstrapSecret,
105
+ DMS_SESSION_SECRET: sessionSecret,
104
106
  NODE_OPTIONS: "--max-old-space-size=4096",
105
107
  NODE_PATH: nodeModulesDir,
106
108
  },
@@ -20,6 +20,7 @@ function cmdStart() {
20
20
  (0, cli_ui_1.error)("Backend URL is required. Use -b <url> or set DMS_API_BASE_URL.");
21
21
  process.exit(1);
22
22
  }
23
+ const sessionSecret = (0, common_1.resolveSessionSecret)("start");
23
24
  const workspaceDir = (0, common_1.getWorkspaceDir)(options.backendUrl);
24
25
  const serverPath = (0, node_path_1.join)(workspaceDir, "server.mjs");
25
26
  const clientPath = (0, node_path_1.join)(workspaceDir, "dist", "client", "index.html");
@@ -41,6 +42,7 @@ function cmdStart() {
41
42
  ...process.env,
42
43
  PORT: options.port,
43
44
  DMS_API_BASE_URL: options.backendUrl,
45
+ DMS_SESSION_SECRET: sessionSecret,
44
46
  DMS_COOKIE_SECURE: process.env.DMS_COOKIE_SECURE ?? "true",
45
47
  },
46
48
  });
package/dist/config.js CHANGED
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.Options = exports.TAILWIND_SOURCE_GLOB = exports.PNPM_LIFECYCLE_SCRIPTS = exports.layerCopyIgnore = exports.LAYER_COPY_BLOCKLIST = exports.AUTH_ESTABLISH_FILE = exports.FRONTEND_MODULE_ENTRY = exports.LAYERS_SUBDIR = exports.TEMPLATE_FILES = exports.WORKSPACE_DIR_MODE = exports.DEPS_HASH_FILE = exports.DMS_FRONTEND_HOME = void 0;
7
7
  exports.writeSecretBearingFile = writeSecretBearingFile;
8
8
  exports.normalizeBootstrapSecret = normalizeBootstrapSecret;
9
+ exports.resolveSessionSecret = resolveSessionSecret;
9
10
  exports.resolveBootstrapSecret = resolveBootstrapSecret;
10
11
  exports.sha256Hex = sha256Hex;
11
12
  exports.canonicalizeBackendUrl = canonicalizeBackendUrl;
@@ -109,6 +110,18 @@ function normalizeBootstrapSecret(value, source = DEFAULT_CREDENTIAL_SOURCE) {
109
110
  }
110
111
  return trimmed;
111
112
  }
113
+ function resolveSessionSecret(mode, value = process.env.DMS_SESSION_SECRET) {
114
+ if (value === undefined && mode === "dev") {
115
+ return (0, node_crypto_1.randomBytes)(32).toString("hex");
116
+ }
117
+ if (value === undefined || value.length < 32) {
118
+ throw new Error("DMS_SESSION_SECRET must contain at least 32 characters; " +
119
+ (mode === "dev"
120
+ ? "set it explicitly or omit it to generate an ephemeral dev secret"
121
+ : "set it explicitly for build and start"));
122
+ }
123
+ return value;
124
+ }
112
125
  function resolveBootstrapSecret(explicit, backendUrl, options = {}) {
113
126
  const normalized = normalizeBootstrapSecret(explicit);
114
127
  if (normalized)
package/dist/index.js CHANGED
@@ -38,6 +38,9 @@ Environment:
38
38
  the other variables below can live in the project's .env. A variable already
39
39
  set in the environment always wins over a file, and .env.local wins over .env.
40
40
  The generated workspace never loads a .env of its own.
41
+ 'dev' generates an ephemeral 32-byte DMS_SESSION_SECRET when it is absent;
42
+ restarting dev invalidates its sessions. 'build' and 'start' require a
43
+ configured secret of at least 32 characters.
41
44
 
42
45
  Workspaces:
43
46
  Each canonical backend URL gets its own workspace under
@@ -140,7 +140,7 @@ function writeFrontendModuleRegistry(workspaceDir, layers) {
140
140
  }
141
141
  function writeFrontendTypePaths(workspaceDir, registry) {
142
142
  const paths = {
143
- "#dms-inertia/frontend-module": ["./frontend-module.ts"],
143
+ "#dms/frontend-module": ["./frontend-module.ts"],
144
144
  "@frontend/*": ["./frontend-modules/*"],
145
145
  };
146
146
  [...registry.modules].reverse().forEach((module) => {
@@ -53,7 +53,7 @@ function removeDevelopmentDependencies(root) {
53
53
  if (!process.env.DMS_LAYER_SOURCE)
54
54
  throw new Error("DMS_LAYER_SOURCE must identify a frontend package");
55
55
  const sourceRoot = (0, node_path_1.resolve)(process.env.DMS_LAYER_SOURCE);
56
- const workspace = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "dms-inertia-real-source-"));
56
+ const workspace = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "dms-frontend-real-source-"));
57
57
  const templateRoot = (0, node_path_1.join)((0, common_1.getPackageRoot)(), "templates", "vue");
58
58
  const commandEnvironment = { ...process.env };
59
59
  const EMAIL_BUILD_SIZE_CEILING_BYTES = 256 * 1024;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antelopejs/dms-frontend",
3
- "version": "0.1.9",
3
+ "version": "0.2.1",
4
4
  "description": "Frontend-agnostic loader for AntelopeJS DMS, shipping the Vue 3 renderer (Vite, Inertia, SSR)",
5
5
  "keywords": [
6
6
  "antelope",
@@ -135,7 +135,7 @@ export default defineConfig({
135
135
  resolve: {
136
136
  dedupe: ["vue", "reka-ui", "@nuxt/ui"],
137
137
  alias: {
138
- "#dms-inertia/frontend-module": resolve(__dirname, "frontend-module.ts"),
138
+ "#dms/frontend-module": resolve(__dirname, "frontend-module.ts"),
139
139
  "#build/nuxt-icon-client-bundle": "virtual:nuxt-ui-icons",
140
140
  "#shortcuts-aggregated": resolve(
141
141
  __dirname,