akanjs 2.4.2-rc.0 → 2.4.2-rc.2

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 (49) hide show
  1. package/common/index.ts +1 -1
  2. package/common/subRoute.ts +61 -0
  3. package/constant/cascadePaths.ts +32 -0
  4. package/constant/fieldInfo.ts +11 -3
  5. package/constant/index.ts +3 -0
  6. package/constant/textFieldPathSet.ts +8 -0
  7. package/constant/textFieldPaths.ts +59 -0
  8. package/constant/types.ts +0 -4
  9. package/constant/via.ts +19 -28
  10. package/dictionary/dictInfo.ts +4 -0
  11. package/document/documentQuery.ts +17 -1
  12. package/document/documentSchema.ts +1 -15
  13. package/document/filterMeta.ts +4 -2
  14. package/local/apps/serverLifecycle/serverLifecycle-local.db +0 -0
  15. package/local/apps/serverLifecycle/serverLifecycle-local.db-shm +0 -0
  16. package/local/apps/serverLifecycle/serverLifecycle-local.db-wal +0 -0
  17. package/package.json +1 -1
  18. package/server/devtools/types.ts +2 -2
  19. package/server/di/diLifecycle.ts +7 -1
  20. package/server/proxy/hostBasePathWebProxy.ts +16 -5
  21. package/server/resolver/database.resolver.ts +5 -6
  22. package/server/resolver/service.resolver.ts +27 -5
  23. package/server/webRouter.ts +27 -11
  24. package/service/predefinedAdaptor/database.adaptor.ts +212 -88
  25. package/service/predefinedAdaptor/index.ts +1 -0
  26. package/service/predefinedAdaptor/searchIndex.ts +517 -0
  27. package/service/predefinedAdaptor/sqlDescriptor.ts +25 -0
  28. package/types/common/index.d.ts +1 -1
  29. package/types/common/subRoute.d.ts +19 -0
  30. package/types/constant/cascadePaths.d.ts +11 -0
  31. package/types/constant/fieldInfo.d.ts +8 -3
  32. package/types/constant/index.d.ts +3 -0
  33. package/types/constant/textFieldPathSet.d.ts +8 -0
  34. package/types/constant/textFieldPaths.d.ts +10 -0
  35. package/types/constant/types.d.ts +0 -3
  36. package/types/constant/via.d.ts +8 -24
  37. package/types/dictionary/base.dictionary.d.ts +1 -1
  38. package/types/dictionary/dictionary.d.ts +8 -8
  39. package/types/document/documentQuery.d.ts +13 -1
  40. package/types/document/documentSchema.d.ts +0 -3
  41. package/types/document/filterMeta.d.ts +2 -1
  42. package/types/server/devtools/types.d.ts +2 -2
  43. package/types/server/resolver/service.resolver.d.ts +3 -3
  44. package/types/service/predefinedAdaptor/database.adaptor.d.ts +46 -13
  45. package/types/service/predefinedAdaptor/index.d.ts +1 -0
  46. package/types/service/predefinedAdaptor/searchIndex.d.ts +73 -0
  47. package/types/service/predefinedAdaptor/sqlDescriptor.d.ts +5 -0
  48. package/types/ui/Constant/schemaDoc.d.ts +2 -2
  49. package/ui/Constant/schemaDoc.ts +8 -2
@@ -1,6 +1,6 @@
1
1
  import type { PromiseOrObject } from "akanjs/base";
2
2
  import { capitalize } from "akanjs/common";
3
- import type { ConstantModel, QueryOf } from "akanjs/constant";
3
+ import { type ConstantModel, ConstantRegistry, type QueryOf } from "akanjs/constant";
4
4
  import {
5
5
  type CRUDEventType,
6
6
  type DatabaseModel,
@@ -17,7 +17,11 @@ import {
17
17
  import type { DatabaseService, ServiceCls } from "akanjs/service";
18
18
 
19
19
  export class ServiceResolver {
20
- static #getDefaultDbServiceMethods(className: string) {
20
+ static #getDefaultDbServiceMethods(
21
+ className: string,
22
+ cascades: [string, string][],
23
+ getService: (refName: string) => DatabaseService,
24
+ ) {
21
25
  const dbServiceMethods = {
22
26
  async __get(this: DatabaseService, id: string) {
23
27
  return await this.__databaseModel.__get(id);
@@ -95,9 +99,18 @@ export class ServiceResolver {
95
99
  return this.__update(id, data);
96
100
  },
97
101
  async __remove(this: DatabaseService, id: string): Promise<Doc> {
102
+
103
+ const targets = cascades.map(([key, refName]) => [key, getService(refName)] as const);
98
104
  await this.__libsPreRemove(id);
99
105
  const doc = await this.__databaseModel.__remove(id);
100
- return await this.__libsPostRemove(doc);
106
+ const removed = await this.__libsPostRemove(doc);
107
+ for (const [key, target] of targets) {
108
+ const value = (removed as Record<string, unknown>)[key];
109
+ const ids = (Array.isArray(value) ? value : [value]).filter((v): v is string => typeof v === "string");
110
+
111
+ for (const targetId of ids) await target.__remove(targetId);
112
+ }
113
+ return removed;
101
114
  },
102
115
  async [`remove${className}`](this: DatabaseService, id: string): Promise<Doc> {
103
116
  return this.__remove(id);
@@ -105,9 +118,18 @@ export class ServiceResolver {
105
118
  };
106
119
  return dbServiceMethods;
107
120
  }
108
- static resolveDatabaseService(constant: ConstantModel, database: DatabaseModel, srvRef: ServiceCls): ServiceCls {
121
+ static resolveDatabaseService(
122
+ constant: ConstantModel,
123
+ database: DatabaseModel,
124
+ srvRef: ServiceCls,
125
+ getService: (refName: string) => DatabaseService,
126
+ ): ServiceCls {
109
127
  const className = capitalize(database.refName);
110
- Object.assign(srvRef.prototype, ServiceResolver.#getDefaultDbServiceMethods(className));
128
+
129
+ const cascades = [...constant.full.cascade.remove].map(
130
+ ([key, modelRef]) => [key, ConstantRegistry.getRefName(modelRef)] as [string, string],
131
+ );
132
+ Object.assign(srvRef.prototype, ServiceResolver.#getDefaultDbServiceMethods(className, cascades, getService));
111
133
  const getQueryDataFromKey = (queryKey: string, args: any): { query: any; queryOption: any } => {
112
134
  const lastArg = args.at(-1);
113
135
  const hasQueryOption =
@@ -7,6 +7,7 @@ import {
7
7
  getBasePathFromPathname,
8
8
  Logger,
9
9
  parseAkanI18nEnv,
10
+ resolveSubRouteHosts,
10
11
  } from "akanjs/common";
11
12
  import { type AkanRequestStore, createRequestStore, parseCookieHeader } from "akanjs/fetch";
12
13
  import type { AkanMetricsReport } from "akanjs/service";
@@ -267,6 +268,7 @@ export class WebRouter {
267
268
  #logger = new Logger("WebRouter");
268
269
  #artifactDir = WebRouter.#resolveArtifactDir();
269
270
  #artifact: BaseBuildArtifact;
271
+ #subRoutes: Record<string, string[]>;
270
272
  #rsc: RscWorker;
271
273
  #hub: HmrWsHub | null = null;
272
274
  #prodMode = process.env.NODE_ENV === "production";
@@ -293,6 +295,16 @@ export class WebRouter {
293
295
  constructor({ artifact, cssBytesByUrl, rsc, seedIndex, upgradeHmrWs }: WebRouterOptions) {
294
296
  this.#logger.verbose(`[SSR] loaded ${Object.keys(cssBytesByUrl).length} CSS assets`);
295
297
  this.#artifact = artifact;
298
+ const { subRoutes, ignoredBasePaths } = resolveSubRouteHosts({
299
+ subRoutes: artifact.subRoutes,
300
+ basePaths: artifact.basePaths,
301
+ env: process.env.AKAN_SUB_ROUTE_HOSTS,
302
+ });
303
+ this.#subRoutes = subRoutes;
304
+ if (ignoredBasePaths.length)
305
+ this.#logger.warn(
306
+ `AKAN_SUB_ROUTE_HOSTS names basePaths this build does not serve, ignoring: ${ignoredBasePaths.join(", ")}`,
307
+ );
296
308
  this.#rsc = rsc;
297
309
  this.renderState = {
298
310
  buildId: 0,
@@ -424,8 +436,7 @@ export class WebRouter {
424
436
  const clientOrigin = WebRouter.#clientFacingOrigin(req);
425
437
  const target = reqUrl.searchParams.get("url");
426
438
  const rawTargetUrl = target ? new URL(target, clientOrigin) : reqUrl;
427
- const requestBasePath =
428
- req.headers.get("x-base-path") ?? WebRouter.#basePathForRequestHost(req, this.#artifact.subRoutes);
439
+ const requestBasePath = this.#requestBasePath(req);
429
440
  const normalizedTarget = normalizeRscTargetUrlForHostBasePath(rawTargetUrl, {
430
441
  basePath: requestBasePath,
431
442
  basePaths: this.#artifact.basePaths,
@@ -517,11 +528,7 @@ export class WebRouter {
517
528
  });
518
529
  }
519
530
 
520
- const sitemapBasePath = getSitemapBasePath(
521
- url.pathname,
522
- this.#artifact.basePaths,
523
- req.headers.get("x-base-path") ?? WebRouter.#basePathForRequestHost(req, this.#artifact.subRoutes),
524
- );
531
+ const sitemapBasePath = getSitemapBasePath(url.pathname, this.#artifact.basePaths, this.#requestBasePath(req));
525
532
  if (sitemapBasePath !== undefined) {
526
533
  return new Response(
527
534
  createDefaultSitemapXml({
@@ -713,6 +720,17 @@ export class WebRouter {
713
720
  return getClientFacingOrigin(req);
714
721
  }
715
722
 
723
+ /**
724
+ * `x-base-path` is set by `HostBasePathWebProxy`, but it reaches here from the wire too, so it is checked against
725
+ * the basePaths this build serves — the same check `getBasePathFromPathname` already applies to it. An unknown
726
+ * value falls through to host matching instead of routing the request into a basePath that resolves to nothing.
727
+ */
728
+ #requestBasePath(req: Request): string | null {
729
+ const headerBasePath = req.headers.get("x-base-path");
730
+ if (headerBasePath && this.#artifact.basePaths.includes(headerBasePath)) return headerBasePath;
731
+ return WebRouter.#basePathForRequestHost(req, this.#subRoutes);
732
+ }
733
+
716
734
  static #basePathForRequestHost(req: Request, subRoutes: Record<string, string[]>): string | null {
717
735
  const host = (req.headers.get("x-forwarded-host") ?? req.headers.get("host") ?? "")
718
736
  .toLowerCase()
@@ -857,8 +875,7 @@ export class WebRouter {
857
875
  pathname,
858
876
  i18n: this.#artifact.i18n,
859
877
  basePaths: this.#artifact.basePaths,
860
- headerBasePath:
861
- req.headers.get("x-base-path") ?? WebRouter.#basePathForRequestHost(req, this.#artifact.subRoutes),
878
+ headerBasePath: this.#requestBasePath(req),
862
879
  });
863
880
  }
864
881
 
@@ -866,8 +883,7 @@ export class WebRouter {
866
883
  const basePath = getBasePathFromPathname(pathname, {
867
884
  basePaths: Object.keys(this.renderState.cssAssets),
868
885
  i18n: this.#artifact.i18n,
869
- headerBasePath:
870
- req.headers.get("x-base-path") ?? WebRouter.#basePathForRequestHost(req, this.#artifact.subRoutes),
886
+ headerBasePath: this.#requestBasePath(req),
871
887
  });
872
888
  return this.renderState.cssAssets[basePath ?? ""]?.cssUrl ?? null;
873
889
  }