@nextage/nx-frame-be 1.0.41 → 1.0.43

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.
@@ -18,7 +18,7 @@ exports.APP = {
18
18
  dataScr: process.env.SECRET,
19
19
  nxPubSub: new pubsub_manager_1.PubSubManager(),
20
20
  shutdownMng: new shutdown_manager_1.ShutdownManager(),
21
- config: { endpoint: {}, email: {}, jwt: {}, aws: {}, mongo: {}, logging: {}, invite: {}, msg: {} }
21
+ config: { endpoint: {}, email: {}, jwt: {}, aws: {}, mongo: {}, logging: {}, invite: {}, msg: {}, app: {} }
22
22
  };
23
23
  exports.FILE_CONTENT_TYPES = {
24
24
  none: '',
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const coded_entity_controller_1 = require("../../models/coded-entity.controller");
4
+ const loader_1 = require("../loader");
5
+ const registry_1 = require("../registry");
6
+ /**
7
+ * `SchemaRegistry` defers `generateSchema`/`loadSchema` until `apply`, so module
8
+ * LOADING is decoupled from schema MUTATION. These tests assert the deferral,
9
+ * the single-shot application and the reset semantics used for test isolation.
10
+ */
11
+ describe('SchemaRegistry', () => {
12
+ afterEach(() => registry_1.schemaRegistry.reset());
13
+ it('starts empty', () => {
14
+ expect(registry_1.schemaRegistry.count).toBe(0);
15
+ });
16
+ it('defers registerSchema until apply', () => {
17
+ const marker = 'registryProbeField: String';
18
+ registry_1.schemaRegistry.registerSchema({ typeDefs: { query: marker } });
19
+ // registration is recorded but NOT yet folded into mainSchema
20
+ expect(registry_1.schemaRegistry.count).toBe(1);
21
+ expect(loader_1.mainSchema.typeDefs.query).not.toContain('registryProbeField');
22
+ registry_1.schemaRegistry.apply();
23
+ expect(loader_1.mainSchema.typeDefs.query).toContain('registryProbeField');
24
+ });
25
+ it('defers register (controller) until apply', () => {
26
+ const params = {
27
+ fields: { type: 'id: String', query: 'code: String', input: 'code: String' }
28
+ };
29
+ registry_1.schemaRegistry.register(coded_entity_controller_1.ceCtrl, params);
30
+ // the CRUD query name is generated by generateSchema at apply time only
31
+ expect(registry_1.schemaRegistry.count).toBe(1);
32
+ expect(loader_1.mainSchema.typeDefs.query).not.toContain('codedEntityList');
33
+ registry_1.schemaRegistry.apply();
34
+ expect(loader_1.mainSchema.typeDefs.query).toContain('codedEntityList');
35
+ });
36
+ it('reset clears every registration', () => {
37
+ registry_1.schemaRegistry.registerSchema({ typeDefs: { query: 'a: String' } });
38
+ registry_1.schemaRegistry.registerSchema({ typeDefs: { query: 'b: String' } });
39
+ expect(registry_1.schemaRegistry.count).toBe(2);
40
+ registry_1.schemaRegistry.reset();
41
+ expect(registry_1.schemaRegistry.count).toBe(0);
42
+ });
43
+ it('exposes a class for isolated instances', () => {
44
+ const local = new registry_1.SchemaRegistry();
45
+ local.registerSchema({ typeDefs: { query: 'c: String' } });
46
+ expect(local.count).toBe(1);
47
+ expect(registry_1.schemaRegistry.count).toBe(0);
48
+ });
49
+ });
@@ -1,4 +1,5 @@
1
1
  export * from './directives';
2
2
  export * from './loader';
3
3
  export * from './generator';
4
+ export * from './registry';
4
5
  export * from './utils';
@@ -17,5 +17,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./directives"), exports);
18
18
  __exportStar(require("./loader"), exports);
19
19
  __exportStar(require("./generator"), exports);
20
+ __exportStar(require("./registry"), exports);
20
21
  __exportStar(require("./utils"), exports);
21
22
  //export * from './scalars';
@@ -0,0 +1,47 @@
1
+ import { BaseController } from '../base/base.controller';
2
+ import { NxGraphQLSchemaData, NxGraphQLSchemaExtension } from './interfaces';
3
+ /**
4
+ * Deferred GraphQL schema-assembly registry.
5
+ *
6
+ * Historically every nx-app GraphQL leaf mutated the global `mainSchema` at
7
+ * import time by calling `generateSchema`/`loadSchema` as a module side-effect.
8
+ * That coupled module LOADING (which files get imported, and in what order) with
9
+ * schema MUTATION, and left the registered set invisible and non-resettable.
10
+ *
11
+ * With this registry a leaf instead REGISTERS its module — a controller plus a
12
+ * schema extension, or a raw typeDefs/resolvers block — deferring the actual
13
+ * `generateSchema`/`loadSchema` call. The bootstrap `graphql` phase discovers and
14
+ * imports the leaves (which call {@link register}/{@link registerSchema}) and then
15
+ * calls {@link apply} ONCE to fold every module into `mainSchema`.
16
+ *
17
+ * Benefits: loading is order-independent (filesystem discovery), mutation is a
18
+ * single explicit logged step, and the registered set is inspectable ({@link count})
19
+ * and resettable ({@link reset}) for test isolation.
20
+ */
21
+ export declare class SchemaRegistry {
22
+ private deferred;
23
+ /**
24
+ * Register a controller-backed module. Mirrors {@link generateSchema}'s
25
+ * signature verbatim; the call is deferred until {@link apply}.
26
+ */
27
+ register<T extends BaseController<any, any, any>>(controller: T, schema?: NxGraphQLSchemaExtension, mergeCodedEntity?: boolean, readOnly?: boolean): void;
28
+ /**
29
+ * Register a raw typeDefs/resolvers block (no controller). Mirrors
30
+ * {@link loadSchema}; the call is deferred until {@link apply}.
31
+ */
32
+ registerSchema(data: NxGraphQLSchemaData): void;
33
+ /**
34
+ * Fold every registered module into the global `mainSchema`. Call ONCE from
35
+ * the bootstrap `graphql` phase, after all leaves have been imported.
36
+ */
37
+ apply(): void;
38
+ /** Clear all registrations (test isolation). */
39
+ reset(): void;
40
+ /** Number of modules registered so far. */
41
+ get count(): number;
42
+ }
43
+ /**
44
+ * Process-wide GraphQL schema registry singleton. nx-app leaves import this and
45
+ * call `register`/`registerSchema`; the bootstrap `graphql` phase calls `apply`.
46
+ */
47
+ export declare const schemaRegistry: SchemaRegistry;
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.schemaRegistry = exports.SchemaRegistry = void 0;
4
+ const constants_1 = require("../constants");
5
+ const generator_1 = require("./generator");
6
+ const loader_1 = require("./loader");
7
+ /**
8
+ * Deferred GraphQL schema-assembly registry.
9
+ *
10
+ * Historically every nx-app GraphQL leaf mutated the global `mainSchema` at
11
+ * import time by calling `generateSchema`/`loadSchema` as a module side-effect.
12
+ * That coupled module LOADING (which files get imported, and in what order) with
13
+ * schema MUTATION, and left the registered set invisible and non-resettable.
14
+ *
15
+ * With this registry a leaf instead REGISTERS its module — a controller plus a
16
+ * schema extension, or a raw typeDefs/resolvers block — deferring the actual
17
+ * `generateSchema`/`loadSchema` call. The bootstrap `graphql` phase discovers and
18
+ * imports the leaves (which call {@link register}/{@link registerSchema}) and then
19
+ * calls {@link apply} ONCE to fold every module into `mainSchema`.
20
+ *
21
+ * Benefits: loading is order-independent (filesystem discovery), mutation is a
22
+ * single explicit logged step, and the registered set is inspectable ({@link count})
23
+ * and resettable ({@link reset}) for test isolation.
24
+ */
25
+ class SchemaRegistry {
26
+ constructor() {
27
+ this.deferred = [];
28
+ }
29
+ /**
30
+ * Register a controller-backed module. Mirrors {@link generateSchema}'s
31
+ * signature verbatim; the call is deferred until {@link apply}.
32
+ */
33
+ register(controller, schema = {}, mergeCodedEntity = false, readOnly = false) {
34
+ this.deferred.push(() => (0, generator_1.generateSchema)(controller, schema, mergeCodedEntity, readOnly));
35
+ }
36
+ /**
37
+ * Register a raw typeDefs/resolvers block (no controller). Mirrors
38
+ * {@link loadSchema}; the call is deferred until {@link apply}.
39
+ */
40
+ registerSchema(data) {
41
+ this.deferred.push(() => (0, loader_1.loadSchema)(data));
42
+ }
43
+ /**
44
+ * Fold every registered module into the global `mainSchema`. Call ONCE from
45
+ * the bootstrap `graphql` phase, after all leaves have been imported.
46
+ */
47
+ apply() {
48
+ this.deferred.forEach(run => run());
49
+ constants_1.APP.logger.info(`🧩 GraphQL registry: applied ${this.deferred.length} schema module(s)`);
50
+ }
51
+ /** Clear all registrations (test isolation). */
52
+ reset() {
53
+ this.deferred = [];
54
+ }
55
+ /** Number of modules registered so far. */
56
+ get count() {
57
+ return this.deferred.length;
58
+ }
59
+ }
60
+ exports.SchemaRegistry = SchemaRegistry;
61
+ /**
62
+ * Process-wide GraphQL schema registry singleton. nx-app leaves import this and
63
+ * call `register`/`registerSchema`; the bootstrap `graphql` phase calls `apply`.
64
+ */
65
+ exports.schemaRegistry = new SchemaRegistry();
@@ -42,7 +42,20 @@ export type AppConfig = {
42
42
  mongo: AppMongoDB;
43
43
  invite: AppInvitation;
44
44
  logging: AppLogging;
45
+ app: AppCustomConfig;
45
46
  };
47
+ /**
48
+ * Application-specific configuration slot.
49
+ *
50
+ * Intentionally EMPTY in the framework: each consuming application augments this
51
+ * interface (declaration merging: `declare module '@nextage/nx-frame-be'`) to
52
+ * add its own strongly-typed settings, and populates `APP.config.app` at bootstrap
53
+ * (after env is read). This keeps CORE config (`endpoint`, `jwt`, `mongo`, …) in
54
+ * the framework while APP-ONLY settings live here — typed by the app, not by env
55
+ * reads scattered across the codebase.
56
+ */
57
+ export interface AppCustomConfig {
58
+ }
46
59
  export type AppMongoDB = {
47
60
  auth?: {
48
61
  us: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextage/nx-frame-be",
3
- "version": "1.0.41",
3
+ "version": "1.0.43",
4
4
  "description": "",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",