nucleus-core-ts 0.9.950 → 0.9.951

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.
@@ -19,6 +19,39 @@ type PgTable = ReturnType<typeof import('drizzle-orm/pg-core').pgTable>;
19
19
  * - **Schema-aware**: caller passes the schema-resolved `rolesTable` and
20
20
  * `userRolesTable`, so this helper works correctly under multi-tenancy.
21
21
  */
22
+ /**
23
+ * The role names a new account should receive, from the two config shapes.
24
+ *
25
+ * `defaultRoles` (a list) is what an operator edits in the admin panel; a
26
+ * baseline account usually needs more than one role, and the single
27
+ * `defaultRole` string could not express that. The string is still honoured so
28
+ * an installation that predates the list keeps working, and both are merged
29
+ * rather than one shadowing the other — an operator who adds a list has not
30
+ * asked for the role their config has always granted to stop being granted.
31
+ *
32
+ * Blanks and duplicates are dropped: an empty box in the panel is "nothing",
33
+ * not a role named "".
34
+ */
35
+ export declare function resolveDefaultRoleNames(authentication: {
36
+ defaultRole?: string | null;
37
+ defaultRoles?: readonly string[] | null;
38
+ } | null | undefined): string[];
39
+ /**
40
+ * Assigns every configured default role to a newly created user.
41
+ *
42
+ * Each name is handled independently: a role that no longer exists is logged
43
+ * and skipped, and the rest are still granted. The alternative — abandoning the
44
+ * whole list on the first bad name — would silently downgrade every new account
45
+ * because one role was renamed.
46
+ */
47
+ export declare function assignDefaultRoles(params: {
48
+ db: NodePgDatabase;
49
+ userId: string;
50
+ roleNames: readonly string[];
51
+ rolesTable: PgTable | null | undefined;
52
+ userRolesTable: PgTable | null | undefined;
53
+ logger: Logger;
54
+ }): Promise<void>;
22
55
  export declare function assignDefaultRole(params: {
23
56
  db: NodePgDatabase;
24
57
  userId: string;
@@ -11,6 +11,8 @@ export type CohortRouteConfig = {
11
11
  profilesTable: PgTable | null;
12
12
  basePath: string;
13
13
  defaultRole?: string;
14
+ /** List form of `defaultRole`; merged with it. See NucleusConfigOptions.authentication. */
15
+ defaultRoles?: string[];
14
16
  emailExemptDomains?: string[];
15
17
  passwordPolicy?: {
16
18
  minLength?: number;
@@ -33,6 +33,12 @@ export interface AuthRouteConfig {
33
33
  * of blocking sign-up.
34
34
  */
35
35
  defaultRole?: string;
36
+ /**
37
+ * The list form of `defaultRole` (see NucleusConfigOptions). Merged with it,
38
+ * never replacing it. Read per request so the admin panel's write applies to
39
+ * the next sign-up.
40
+ */
41
+ defaultRoles?: string[];
36
42
  cookieMaxAgeBufferSeconds?: number;
37
43
  cookieDomain?: string;
38
44
  emailExemptDomains?: string[];
@@ -328,6 +328,24 @@ export interface NucleusConfigOptions {
328
328
  * Example: "user-free"
329
329
  */
330
330
  defaultRole?: string;
331
+ /**
332
+ * Role names to assign automatically to every newly created user — the
333
+ * list form of `defaultRole`, for the common case where a baseline account
334
+ * needs several roles (e.g. chat + knowledge + a spend cap).
335
+ *
336
+ * Merged with `defaultRole` rather than replacing it, so adding a list
337
+ * never silently revokes the role an installation has always granted. Each
338
+ * name is resolved independently and a missing one is skipped with a
339
+ * warning — one renamed role must not downgrade every new account.
340
+ *
341
+ * Settable at runtime through the config write-path (`PATCH
342
+ * /nucleus/config/authentication`), which is how the portal's "roles for
343
+ * new SSO accounts" panel writes it. Read per request, so a change applies
344
+ * on the next sign-up rather than the next deployment.
345
+ *
346
+ * Example: ["vorion-chat-basic", "vorion-knowledge-manager"]
347
+ */
348
+ defaultRoles?: string[];
331
349
  /**
332
350
  * URL of the IDP service for consumer-mode services to call POST /auth/check.
333
351
  * Required when mode="consumer" and authorization.enabled=true for scope-based checks.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nucleus-core-ts",
3
- "version": "0.9.950",
3
+ "version": "0.9.951",
4
4
  "description": "Production-ready, enterprise-grade TypeScript framework for building multi-tenant APIs",
5
5
  "author": "Hidayet Can Özcan <hidayetcan@gmail.com>",
6
6
  "license": "SEE LICENSE IN LICENSE",
package/scripts/build.ts CHANGED
@@ -16,6 +16,17 @@ const BLUE = '\x1b[34m'
16
16
  const RED = '\x1b[31m'
17
17
  const NC = '\x1b[0m'
18
18
 
19
+ /**
20
+ * A path fit to be pasted into a shell command.
21
+ *
22
+ * `join()` returns `dist\client.js` on Windows, and the backslash is an ESCAPE
23
+ * character to the shell — `--outfile=dist\client.js` silently became
24
+ * `--outfile=distclient.js`, so `dist/client.js` was simply absent from a build
25
+ * that reported success. Every consumer importing `nucleus-core-ts/client`
26
+ * would then fail to resolve at install time, from a package that looked fine.
27
+ */
28
+ const shellPath = (p: string) => p.replaceAll('\\', '/')
29
+
19
30
  const log = {
20
31
  info: (msg: string) => console.log(`${BLUE}ℹ️ ${msg}${NC}`),
21
32
  success: (msg: string) => console.log(`${GREEN}✅ ${msg}${NC}`),
@@ -69,7 +80,7 @@ async function buildClientEntries() {
69
80
 
70
81
  for (const [exportPath, entry] of Object.entries(clientEntries)) {
71
82
  const outFile = entry.replace(/\.ts$/, '.js').replace('./', '')
72
- const outPath = join(config.build.outDir, outFile)
83
+ const outPath = shellPath(join(config.build.outDir, outFile))
73
84
 
74
85
  const clientMinifyVal = config.build.minify
75
86
  const clientMinifyFlags =
@@ -134,7 +145,7 @@ async function transpileClientModules() {
134
145
  } else {
135
146
  // Single file transpilation
136
147
  const outFile = entry.replace(/\.ts$/, '.js').replace('./', '')
137
- const outPath = join(config.build.outDir, outFile)
148
+ const outPath = shellPath(join(config.build.outDir, outFile))
138
149
 
139
150
  const outDir = outPath.substring(0, outPath.lastIndexOf('/'))
140
151
  if (outDir) {
File without changes