@sneat/space-services 0.16.0 → 0.18.0

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/esm2022/index.js CHANGED
@@ -5,4 +5,5 @@ export * from './lib/services/space-item.service';
5
5
  export * from './lib/services/space-context.service';
6
6
  export * from './lib/services/space-module.service';
7
7
  export * from './lib/components/with-space-input.directive';
8
+ export * from './lib/guards/space-home-redirect.guard';
8
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/space/services/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qCAAqC,CAAC;AACpD,cAAc,kCAAkC,CAAC;AACjD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,mCAAmC,CAAC;AAClD,cAAc,sCAAsC,CAAC;AACrD,cAAc,qCAAqC,CAAC;AAEpD,cAAc,6CAA6C,CAAC","sourcesContent":["export * from './lib/services/space-service.module';\nexport * from './lib/services/space-nav.service';\nexport * from './lib/services/space.service';\nexport * from './lib/services/space-item.service';\nexport * from './lib/services/space-context.service';\nexport * from './lib/services/space-module.service';\n\nexport * from './lib/components/with-space-input.directive';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/space/services/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qCAAqC,CAAC;AACpD,cAAc,kCAAkC,CAAC;AACjD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,mCAAmC,CAAC;AAClD,cAAc,sCAAsC,CAAC;AACrD,cAAc,qCAAqC,CAAC;AAEpD,cAAc,6CAA6C,CAAC;AAE5D,cAAc,wCAAwC,CAAC","sourcesContent":["export * from './lib/services/space-service.module';\nexport * from './lib/services/space-nav.service';\nexport * from './lib/services/space.service';\nexport * from './lib/services/space-item.service';\nexport * from './lib/services/space-context.service';\nexport * from './lib/services/space-module.service';\n\nexport * from './lib/components/with-space-input.directive';\n\nexport * from './lib/guards/space-home-redirect.guard';\n"]}
@@ -0,0 +1,50 @@
1
+ import { inject } from '@angular/core';
2
+ import { Router } from '@angular/router';
3
+ import { SneatUserService } from '@sneat/auth-core';
4
+ import { currentSpacePath, SpaceTypeFamily } from '@sneat/core';
5
+ import { filter, firstValueFrom } from 'rxjs';
6
+ /**
7
+ * Builds a route guard that sends a signed-in user from a space-less "home"
8
+ * route straight to a space-scoped page — so apps never have to show a
9
+ * spaces-list just to get the user into their space.
10
+ *
11
+ * 1. If a space is already active (remembered in local storage) -> that
12
+ * space's `<page>`: /space/{type}/{id}/<page>.
13
+ * 2. Otherwise wait for the signed-in user's record and redirect to their
14
+ * FAMILY space's `<page>`: /space/family/{id}/<page>.
15
+ * 3. If the user has no family space (e.g. brand-new, no spaces yet) -> allow
16
+ * the guarded route to render its fallback (typically a spaces list, where
17
+ * they can create/pick a space).
18
+ *
19
+ * Runs AFTER an auth guard, so the user is already authenticated here.
20
+ *
21
+ * Generalises the per-app "redirect home to my space" guard: each extension app
22
+ * passes the trailing segment of its own main page (e.g. assetus -> `'assets'`,
23
+ * requoter -> `'requoter'`).
24
+ *
25
+ * @param page bare space-scoped segment to land on (no leading slash), appended
26
+ * after the resolved space path.
27
+ */
28
+ export function spaceHomeRedirectGuard(page) {
29
+ return async () => {
30
+ const router = inject(Router);
31
+ const userService = inject(SneatUserService);
32
+ // 1. Fast path: an active space is remembered (currentSpacePath() already
33
+ // yields `/space/{type}/{id}`, so just append the page segment).
34
+ const activePath = currentSpacePath();
35
+ if (activePath) {
36
+ return router.parseUrl(`${activePath}/${page}`);
37
+ }
38
+ // 2. Await the user record (loads asynchronously from Firestore after auth),
39
+ // then redirect to the family space.
40
+ const state = await firstValueFrom(userService.userState.pipe(filter((s) => s.status !== 'authenticating' && s.record !== undefined)));
41
+ const spaces = state.record?.spaces ?? {};
42
+ const family = Object.entries(spaces).find(([, brief]) => brief.type === SpaceTypeFamily);
43
+ if (family) {
44
+ return router.parseUrl(`/space/${SpaceTypeFamily}/${family[0]}/${page}`);
45
+ }
46
+ // 3. No active space and no family space — render the fallback.
47
+ return true;
48
+ };
49
+ }
50
+ //# sourceMappingURL=space-home-redirect.guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"space-home-redirect.guard.js","sourceRoot":"","sources":["../../../../../../../libs/space/services/src/lib/guards/space-home-redirect.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAiB,MAAM,EAAW,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,OAAO,KAAK,IAAgC,EAAE;QAC5C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QAC9B,MAAM,WAAW,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;QAE7C,0EAA0E;QAC1E,oEAAoE;QACpE,MAAM,UAAU,GAAG,gBAAgB,EAAE,CAAC;QACtC,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,MAAM,CAAC,QAAQ,CAAC,GAAG,UAAU,IAAI,IAAI,EAAE,CAAC,CAAC;QAClD,CAAC;QAED,6EAA6E;QAC7E,wCAAwC;QACxC,MAAM,KAAK,GAAG,MAAM,cAAc,CAChC,WAAW,CAAC,SAAS,CAAC,IAAI,CACxB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,gBAAgB,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CACvE,CACF,CAAC;QACF,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE,CAAC;QAC1C,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CACxC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,eAAe,CAC9C,CAAC;QACF,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,MAAM,CAAC,QAAQ,CAAC,UAAU,eAAe,IAAI,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QAC3E,CAAC;QAED,gEAAgE;QAChE,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { inject } from '@angular/core';\nimport { CanActivateFn, Router, UrlTree } from '@angular/router';\nimport { SneatUserService } from '@sneat/auth-core';\nimport { currentSpacePath, SpaceTypeFamily } from '@sneat/core';\nimport { filter, firstValueFrom } from 'rxjs';\n\n/**\n * Builds a route guard that sends a signed-in user from a space-less \"home\"\n * route straight to a space-scoped page — so apps never have to show a\n * spaces-list just to get the user into their space.\n *\n * 1. If a space is already active (remembered in local storage) -> that\n * space's `<page>`: /space/{type}/{id}/<page>.\n * 2. Otherwise wait for the signed-in user's record and redirect to their\n * FAMILY space's `<page>`: /space/family/{id}/<page>.\n * 3. If the user has no family space (e.g. brand-new, no spaces yet) -> allow\n * the guarded route to render its fallback (typically a spaces list, where\n * they can create/pick a space).\n *\n * Runs AFTER an auth guard, so the user is already authenticated here.\n *\n * Generalises the per-app \"redirect home to my space\" guard: each extension app\n * passes the trailing segment of its own main page (e.g. assetus -> `'assets'`,\n * requoter -> `'requoter'`).\n *\n * @param page bare space-scoped segment to land on (no leading slash), appended\n * after the resolved space path.\n */\nexport function spaceHomeRedirectGuard(page: string): CanActivateFn {\n return async (): Promise<boolean | UrlTree> => {\n const router = inject(Router);\n const userService = inject(SneatUserService);\n\n // 1. Fast path: an active space is remembered (currentSpacePath() already\n // yields `/space/{type}/{id}`, so just append the page segment).\n const activePath = currentSpacePath();\n if (activePath) {\n return router.parseUrl(`${activePath}/${page}`);\n }\n\n // 2. Await the user record (loads asynchronously from Firestore after auth),\n // then redirect to the family space.\n const state = await firstValueFrom(\n userService.userState.pipe(\n filter((s) => s.status !== 'authenticating' && s.record !== undefined),\n ),\n );\n const spaces = state.record?.spaces ?? {};\n const family = Object.entries(spaces).find(\n ([, brief]) => brief.type === SpaceTypeFamily,\n );\n if (family) {\n return router.parseUrl(`/space/${SpaceTypeFamily}/${family[0]}/${page}`);\n }\n\n // 3. No active space and no family space — render the fallback.\n return true;\n };\n}\n"]}
package/index.d.ts CHANGED
@@ -5,3 +5,4 @@ export * from './lib/services/space-item.service';
5
5
  export * from './lib/services/space-context.service';
6
6
  export * from './lib/services/space-module.service';
7
7
  export * from './lib/components/with-space-input.directive';
8
+ export * from './lib/guards/space-home-redirect.guard';
@@ -0,0 +1,24 @@
1
+ import { CanActivateFn } from '@angular/router';
2
+ /**
3
+ * Builds a route guard that sends a signed-in user from a space-less "home"
4
+ * route straight to a space-scoped page — so apps never have to show a
5
+ * spaces-list just to get the user into their space.
6
+ *
7
+ * 1. If a space is already active (remembered in local storage) -> that
8
+ * space's `<page>`: /space/{type}/{id}/<page>.
9
+ * 2. Otherwise wait for the signed-in user's record and redirect to their
10
+ * FAMILY space's `<page>`: /space/family/{id}/<page>.
11
+ * 3. If the user has no family space (e.g. brand-new, no spaces yet) -> allow
12
+ * the guarded route to render its fallback (typically a spaces list, where
13
+ * they can create/pick a space).
14
+ *
15
+ * Runs AFTER an auth guard, so the user is already authenticated here.
16
+ *
17
+ * Generalises the per-app "redirect home to my space" guard: each extension app
18
+ * passes the trailing segment of its own main page (e.g. assetus -> `'assets'`,
19
+ * requoter -> `'requoter'`).
20
+ *
21
+ * @param page bare space-scoped segment to land on (no leading slash), appended
22
+ * after the resolved space path.
23
+ */
24
+ export declare function spaceHomeRedirectGuard(page: string): CanActivateFn;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sneat/space-services",
3
- "version": "0.16.0",
3
+ "version": "0.18.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },