@memberjunction/server-extensions-core 6.1.0-edge.4 → 6.1.0-edge.6
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 +36 -4
- package/dist/BaseServerExtension.d.ts +1 -1
- package/dist/BaseServerExtension.js +1 -1
- package/dist/ServerExtensionLoader.d.ts +5 -4
- package/dist/ServerExtensionLoader.d.ts.map +1 -1
- package/dist/ServerExtensionLoader.js +5 -4
- package/dist/ServerExtensionLoader.js.map +1 -1
- package/dist/collect.d.ts +93 -0
- package/dist/collect.d.ts.map +1 -0
- package/dist/collect.js +274 -0
- package/dist/collect.js.map +1 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +7 -3
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -9,7 +9,18 @@ This package provides two main exports:
|
|
|
9
9
|
- **`BaseServerExtension`** — Abstract base class that all extensions implement. Defines the `Initialize`, `Shutdown`, and `HealthCheck` lifecycle methods.
|
|
10
10
|
- **`ServerExtensionLoader`** — Discovers registered extension classes via MJ's `ClassFactory`, matches them to config entries, and manages their lifecycle.
|
|
11
11
|
|
|
12
|
-
Extensions are discovered automatically using MemberJunction's standard `@RegisterClass` + `ClassFactory` pattern.
|
|
12
|
+
Extensions are discovered automatically using MemberJunction's standard `@RegisterClass` + `ClassFactory` pattern.
|
|
13
|
+
|
|
14
|
+
**Open App packages** listed in the host `mj.config.cjs` `dynamicPackages.server[]` declare the extensions they need:
|
|
15
|
+
|
|
16
|
+
1. Named export `MJ_SERVER_EXTENSIONS` on the server package (preferred; read after the package is imported).
|
|
17
|
+
2. Fallback: `package.json` → `memberjunction.serverExtensions`.
|
|
18
|
+
|
|
19
|
+
`@memberjunction/server-bootstrap` collects those declarations and `serve()` merges them with the host `serverExtensions[]`. Host `DriverClass` wins (`Enabled`, `RootPath`, per-key `Settings`). A host entry with `Enabled: false` disables a discovered extension. Host-only extensions (Slack, Teams) stay in the host config.
|
|
20
|
+
|
|
21
|
+
**Pre-auth.** Extension routes mount *before* MJServer's auth middleware. Boot logs every collected and merged extension as `PRE-AUTH` with its `DriverClass` and `RootPath` so an operator who installed an Open App for its entities can see the HTTP surface. To suppress one, add the same `DriverClass` to host `serverExtensions[]` with `Enabled: false`. Invalid `RootPath` values (`/`, `/graphql`, `/auth`, `/oauth`, `/health`, `/magic-link`, wildcards) are dropped fail-closed rather than mounted. Matching is **case-insensitive** (Express routing is) and `serve()` also passes the process's real mounts (`graphqlRootPath`, `/healthcheck`, `/esignature`, `/media`, widget, telephony, …) so a custom GraphQL root or a core path not in the static baseline cannot be claimed. Overlapping enabled roots (including case variants) are logged.
|
|
22
|
+
|
|
23
|
+
Open Apps therefore do **not** require the operator to copy extension blocks into the host `mj.config.cjs`. The host file is the override layer plus host-only extensions.
|
|
13
24
|
|
|
14
25
|
## Installation
|
|
15
26
|
|
|
@@ -56,7 +67,29 @@ export class MyCustomExtension extends BaseServerExtension {
|
|
|
56
67
|
}
|
|
57
68
|
```
|
|
58
69
|
|
|
59
|
-
### 2.
|
|
70
|
+
### 2. Declare the extension (Open App **or** host)
|
|
71
|
+
|
|
72
|
+
An Open App server package publishes the default config (so installing the app is enough):
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
// packages/Server/src/index.ts
|
|
76
|
+
export const MJ_SERVER_EXTENSIONS = [
|
|
77
|
+
{ Enabled: true, DriverClass: 'MyCustomExtension', RootPath: '/api/my-extension', Settings: {} },
|
|
78
|
+
];
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
// packages/Server/package.json
|
|
83
|
+
{
|
|
84
|
+
"memberjunction": {
|
|
85
|
+
"serverExtensions": [
|
|
86
|
+
{ "Enabled": true, "DriverClass": "MyCustomExtension", "RootPath": "/api/my-extension", "Settings": {} }
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
A **host** `mj.config.cjs` is only needed to override that default, to disable it, or to load a host-only extension (not shipped by an Open App):
|
|
60
93
|
|
|
61
94
|
```javascript
|
|
62
95
|
module.exports = {
|
|
@@ -68,7 +101,6 @@ module.exports = {
|
|
|
68
101
|
RootPath: '/api/my-extension',
|
|
69
102
|
Settings: {
|
|
70
103
|
apiKey: process.env.MY_EXTENSION_API_KEY,
|
|
71
|
-
// Any extension-specific settings
|
|
72
104
|
}
|
|
73
105
|
}
|
|
74
106
|
]
|
|
@@ -139,7 +171,7 @@ interface ExtensionHealthResult {
|
|
|
139
171
|
|
|
140
172
|
## Lifecycle
|
|
141
173
|
|
|
142
|
-
1. MJServer
|
|
174
|
+
1. MJServer merges Open App–discovered `serverExtensions[]` with the host `mj.config.cjs` list (host `DriverClass` wins)
|
|
143
175
|
2. For each enabled entry, `ServerExtensionLoader` uses `ClassFactory.CreateInstance(BaseServerExtension, driverClass)` to find the registered class
|
|
144
176
|
3. Creates an instance and calls `Initialize(app, config)`
|
|
145
177
|
4. Extension registers its Express routes under `config.RootPath`
|
|
@@ -15,7 +15,7 @@ import { ServerExtensionConfig, ExtensionInitResult, ExtensionHealthResult } fro
|
|
|
15
15
|
*
|
|
16
16
|
* ## Lifecycle
|
|
17
17
|
*
|
|
18
|
-
* 1. MJServer
|
|
18
|
+
* 1. MJServer loads the merged `serverExtensions[]` (Open App packages + host overlay)
|
|
19
19
|
* 2. For each enabled entry, looks up `@RegisterClass(BaseServerExtension, driverClass)`
|
|
20
20
|
* 3. Creates instance via `ClassFactory.CreateInstance()`
|
|
21
21
|
* 4. Calls `Initialize(app, config)` — extension registers routes
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*
|
|
14
14
|
* ## Lifecycle
|
|
15
15
|
*
|
|
16
|
-
* 1. MJServer
|
|
16
|
+
* 1. MJServer loads the merged `serverExtensions[]` (Open App packages + host overlay)
|
|
17
17
|
* 2. For each enabled entry, looks up `@RegisterClass(BaseServerExtension, driverClass)`
|
|
18
18
|
* 3. Creates instance via `ClassFactory.CreateInstance()`
|
|
19
19
|
* 4. Calls `Initialize(app, config)` — extension registers routes
|
|
@@ -8,13 +8,14 @@ import { ServerExtensionConfig, ExtensionHealthResult } from './types.js';
|
|
|
8
8
|
/**
|
|
9
9
|
* Discovers, initializes, and manages the lifecycle of server extensions.
|
|
10
10
|
*
|
|
11
|
-
* Called by MJServer's `serve()` function during startup. The loader
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* Called by MJServer's `serve()` function during startup. The loader receives
|
|
12
|
+
* the merged extension list (Open App–discovered configs overlaid by host
|
|
13
|
+
* `mj.config.cjs` `serverExtensions[]`), uses MJ's `ClassFactory` to find
|
|
14
|
+
* registered extension classes, and calls `Initialize()` on each.
|
|
14
15
|
*
|
|
15
16
|
* ## Discovery Flow
|
|
16
17
|
*
|
|
17
|
-
* 1.
|
|
18
|
+
* 1. Receives the merged `serverExtensions[]` (discovered Open App packages + host overlay)
|
|
18
19
|
* 2. For each enabled entry, uses `ClassFactory.CreateInstance(BaseServerExtension, driverClass)`
|
|
19
20
|
* 3. Creates an instance and calls `Initialize(app, config)`
|
|
20
21
|
* 4. Tracks all loaded extensions for health checks and shutdown
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServerExtensionLoader.d.ts","sourceRoot":"","sources":["../src/ServerExtensionLoader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAGtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EACH,qBAAqB,EACrB,qBAAqB,EACxB,MAAM,YAAY,CAAC;AAgBpB
|
|
1
|
+
{"version":3,"file":"ServerExtensionLoader.d.ts","sourceRoot":"","sources":["../src/ServerExtensionLoader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAGtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EACH,qBAAqB,EACrB,qBAAqB,EACxB,MAAM,YAAY,CAAC;AAgBpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBAAa,qBAAqB;IAC9B,OAAO,CAAC,iBAAiB,CAAyB;IAElD;;;;;;;;;OASG;IACU,cAAc,CACvB,GAAG,EAAE,WAAW,EAChB,gBAAgB,EAAE,qBAAqB,EAAE,GAC1C,OAAO,CAAC,IAAI,CAAC;IAsBhB;;;;;;;OAOG;IACU,cAAc,IAAI,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAmB/D;;;;;;OAMG;IACU,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAczC;;;;OAIG;IACH,IAAW,UAAU,IAAI,aAAa,CAAC;QAAE,QAAQ,EAAE,mBAAmB,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAE7F;IAED;;OAEG;IACH,IAAW,cAAc,IAAI,MAAM,CAElC;IAED;;;;;;OAMG;YACW,mBAAmB;CA+CpC"}
|
|
@@ -8,13 +8,14 @@ import { BaseServerExtension } from './BaseServerExtension.js';
|
|
|
8
8
|
/**
|
|
9
9
|
* Discovers, initializes, and manages the lifecycle of server extensions.
|
|
10
10
|
*
|
|
11
|
-
* Called by MJServer's `serve()` function during startup. The loader
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* Called by MJServer's `serve()` function during startup. The loader receives
|
|
12
|
+
* the merged extension list (Open App–discovered configs overlaid by host
|
|
13
|
+
* `mj.config.cjs` `serverExtensions[]`), uses MJ's `ClassFactory` to find
|
|
14
|
+
* registered extension classes, and calls `Initialize()` on each.
|
|
14
15
|
*
|
|
15
16
|
* ## Discovery Flow
|
|
16
17
|
*
|
|
17
|
-
* 1.
|
|
18
|
+
* 1. Receives the merged `serverExtensions[]` (discovered Open App packages + host overlay)
|
|
18
19
|
* 2. For each enabled entry, uses `ClassFactory.CreateInstance(BaseServerExtension, driverClass)`
|
|
19
20
|
* 3. Creates an instance and calls `Initialize(app, config)`
|
|
20
21
|
* 4. Tracks all loaded extensions for health checks and shutdown
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServerExtensionLoader.js","sourceRoot":"","sources":["../src/ServerExtensionLoader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAoB/D
|
|
1
|
+
{"version":3,"file":"ServerExtensionLoader.js","sourceRoot":"","sources":["../src/ServerExtensionLoader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @memberjunction/server-extensions-core
|
|
3
|
+
* @description Pure collect / normalize / merge for Open App server-extension metadata.
|
|
4
|
+
*
|
|
5
|
+
* Open App server packages declare the extensions they need mounted. The host
|
|
6
|
+
* `mj.config.cjs` `serverExtensions[]` remains the override layer (and the place
|
|
7
|
+
* host-only extensions such as Slack/Teams live). Discovery of the Open App
|
|
8
|
+
* declarations happens in `@memberjunction/server-bootstrap` because
|
|
9
|
+
* `dynamicPackages` is stripped from MJServer's Zod-parsed `configInfo`.
|
|
10
|
+
*/
|
|
11
|
+
import { ServerExtensionConfig } from './types.js';
|
|
12
|
+
/** Named export Open App server packages use to publish their extension configs. */
|
|
13
|
+
export declare const MJ_SERVER_EXTENSIONS_EXPORT = "MJ_SERVER_EXTENSIONS";
|
|
14
|
+
/** `package.json` path Open App server packages use for static introspection. */
|
|
15
|
+
export declare const MJ_SERVER_EXTENSIONS_PACKAGE_JSON_PATH = "memberjunction.serverExtensions";
|
|
16
|
+
export interface NormalizeServerExtensionOptions {
|
|
17
|
+
/** Label used in skip messages (package name, file path, etc.). */
|
|
18
|
+
source?: string;
|
|
19
|
+
/** Called once per skipped/invalid entry. Tests pass a spy; production logs. */
|
|
20
|
+
onInvalid?: (message: string) => void;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Coerce unknown JSON / module-export data into `ServerExtensionConfig[]`.
|
|
24
|
+
* Invalid entries are skipped (not thrown) so one bad Open App declaration
|
|
25
|
+
* cannot take down server boot.
|
|
26
|
+
*/
|
|
27
|
+
export declare function normalizeServerExtensionConfigs(raw: unknown, options?: NormalizeServerExtensionOptions): ServerExtensionConfig[];
|
|
28
|
+
/**
|
|
29
|
+
* Read `MJ_SERVER_EXTENSIONS` from an already-imported Open App server module.
|
|
30
|
+
*/
|
|
31
|
+
export declare function extractServerExtensionsFromModule(mod: Record<string, unknown> | null | undefined, options?: NormalizeServerExtensionOptions): ServerExtensionConfig[];
|
|
32
|
+
/**
|
|
33
|
+
* Read `memberjunction.serverExtensions` from a parsed `package.json`.
|
|
34
|
+
*/
|
|
35
|
+
export declare function extractServerExtensionsFromPackageJson(pkgJson: unknown, options?: NormalizeServerExtensionOptions): ServerExtensionConfig[];
|
|
36
|
+
/**
|
|
37
|
+
* Merge Open App–discovered extension configs with the host `mj.config.cjs` list.
|
|
38
|
+
*
|
|
39
|
+
* - Identity is `DriverClass`.
|
|
40
|
+
* - Later discovered entries replace earlier ones (ClassFactory last-wins).
|
|
41
|
+
* - Host overlay wins `Enabled` and `RootPath` when the host provides them;
|
|
42
|
+
* `Settings` is `{ ...discovered, ...host }`.
|
|
43
|
+
* - Host-only DriverClasses append after discovered ones.
|
|
44
|
+
* - A host `Enabled: false` entry is kept so the loader skips that DriverClass
|
|
45
|
+
* rather than falling back to the discovered one.
|
|
46
|
+
*/
|
|
47
|
+
export declare function mergeServerExtensionConfigs(discovered: readonly ServerExtensionConfig[] | null | undefined, host: readonly ServerExtensionConfig[] | null | undefined): ServerExtensionConfig[];
|
|
48
|
+
/** Exact RootPaths that must never be claimed by an extension (they are the whole tree or a core endpoint). */
|
|
49
|
+
export declare const RESERVED_SERVER_EXTENSION_ROOTS: readonly string[];
|
|
50
|
+
/**
|
|
51
|
+
* Baseline prefixes of core MJServer routes (always applied, including at discovery).
|
|
52
|
+
* Matching is case-insensitive and bidirectional — see `validateServerExtensionRootPath`.
|
|
53
|
+
* Prefix-with-slash so `/health` rejects `/health/extensions` but not `/healthcare`
|
|
54
|
+
* (sibling `/healthcheck` is supplied via `extraReservedRoots` from `serve()`).
|
|
55
|
+
*/
|
|
56
|
+
export declare const RESERVED_SERVER_EXTENSION_ROOT_PREFIXES: readonly string[];
|
|
57
|
+
export declare const MAX_SERVER_EXTENSION_ROOT_PATH_LENGTH = 128;
|
|
58
|
+
/**
|
|
59
|
+
* Returns an error message when `rootPath` is unsafe to mount pre-auth, or `null` when it is usable.
|
|
60
|
+
* Fail closed: invalid paths must not be mounted.
|
|
61
|
+
*
|
|
62
|
+
* Reserved matching is case-insensitive (Express does not set `case sensitive routing`)
|
|
63
|
+
* and bidirectional: claiming a parent of a reserved prefix (`/telephony` vs `/telephony/twilio`)
|
|
64
|
+
* is also a collision because Express prefix-matches the parent.
|
|
65
|
+
*
|
|
66
|
+
* `extraReservedRoots` is the running server's actual mounts (graphqlRootPath, widget, …)
|
|
67
|
+
* so this check cannot drift from `serve()`. Discovery-time normalize uses only the
|
|
68
|
+
* static baseline; `prepareServerExtensionConfigs` passes the extras.
|
|
69
|
+
*/
|
|
70
|
+
export declare function validateServerExtensionRootPath(rootPath: string, extraReservedRoots?: readonly string[]): string | null;
|
|
71
|
+
/** True when two roots are equal or one is a nested path of the other (case-insensitive). */
|
|
72
|
+
export declare function serverExtensionRootsOverlap(a: string, b: string): boolean;
|
|
73
|
+
export interface PrepareServerExtensionOptions extends NormalizeServerExtensionOptions {
|
|
74
|
+
onOverlap?: (message: string) => void;
|
|
75
|
+
/**
|
|
76
|
+
* Additional reserved roots from the running server (graphqlRootPath, WIDGET_MOUNT_PATH, …).
|
|
77
|
+
* Compared case-insensitively and bidirectionally (an extension at `/telephony` collides
|
|
78
|
+
* with a core mount at `/telephony/twilio`).
|
|
79
|
+
*/
|
|
80
|
+
extraReservedRoots?: readonly string[];
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Post-merge filter used by `serve()`: drop invalid roots (fail closed) and warn when
|
|
84
|
+
* two *enabled* extensions claim overlapping paths. Disabled entries are kept so the
|
|
85
|
+
* loader can skip them by DriverClass (host `Enabled: false` stays visible).
|
|
86
|
+
*/
|
|
87
|
+
export declare function prepareServerExtensionConfigs(configs: readonly ServerExtensionConfig[] | null | undefined, options?: PrepareServerExtensionOptions): ServerExtensionConfig[];
|
|
88
|
+
/**
|
|
89
|
+
* One-line inventory of a server-extension mount. All extension routes are installed
|
|
90
|
+
* BEFORE MJServer's auth middleware — the operator must be able to see that at boot.
|
|
91
|
+
*/
|
|
92
|
+
export declare function describeServerExtensionMount(config: ServerExtensionConfig): string;
|
|
93
|
+
//# sourceMappingURL=collect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collect.d.ts","sourceRoot":"","sources":["../src/collect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEnD,oFAAoF;AACpF,eAAO,MAAM,2BAA2B,yBAAyB,CAAC;AAElE,iFAAiF;AACjF,eAAO,MAAM,sCAAsC,oCAAoC,CAAC;AAExF,MAAM,WAAW,+BAA+B;IAC5C,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gFAAgF;IAChF,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAeD;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC3C,GAAG,EAAE,OAAO,EACZ,OAAO,CAAC,EAAE,+BAA+B,GAC1C,qBAAqB,EAAE,CAwDzB;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAC7C,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EAC/C,OAAO,CAAC,EAAE,+BAA+B,GAC1C,qBAAqB,EAAE,CAQzB;AAED;;GAEG;AACH,wBAAgB,sCAAsC,CAClD,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,+BAA+B,GAC1C,qBAAqB,EAAE,CAYzB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CACvC,UAAU,EAAE,SAAS,qBAAqB,EAAE,GAAG,IAAI,GAAG,SAAS,EAC/D,IAAI,EAAE,SAAS,qBAAqB,EAAE,GAAG,IAAI,GAAG,SAAS,GAC1D,qBAAqB,EAAE,CAuCzB;AAED,+GAA+G;AAC/G,eAAO,MAAM,+BAA+B,EAAE,SAAS,MAAM,EAAU,CAAC;AAExE;;;;;GAKG;AACH,eAAO,MAAM,uCAAuC,EAAE,SAAS,MAAM,EAMpE,CAAC;AAEF,eAAO,MAAM,qCAAqC,MAAM,CAAC;AAezD;;;;;;;;;;;GAWG;AACH,wBAAgB,+BAA+B,CAC3C,QAAQ,EAAE,MAAM,EAChB,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,GACvC,MAAM,GAAG,IAAI,CAkCf;AAED,6FAA6F;AAC7F,wBAAgB,2BAA2B,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAOzE;AAED,MAAM,WAAW,6BAA8B,SAAQ,+BAA+B;IAClF,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CACzC,OAAO,EAAE,SAAS,qBAAqB,EAAE,GAAG,IAAI,GAAG,SAAS,EAC5D,OAAO,CAAC,EAAE,6BAA6B,GACxC,qBAAqB,EAAE,CAsBzB;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,CAGlF"}
|
package/dist/collect.js
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @memberjunction/server-extensions-core
|
|
3
|
+
* @description Pure collect / normalize / merge for Open App server-extension metadata.
|
|
4
|
+
*
|
|
5
|
+
* Open App server packages declare the extensions they need mounted. The host
|
|
6
|
+
* `mj.config.cjs` `serverExtensions[]` remains the override layer (and the place
|
|
7
|
+
* host-only extensions such as Slack/Teams live). Discovery of the Open App
|
|
8
|
+
* declarations happens in `@memberjunction/server-bootstrap` because
|
|
9
|
+
* `dynamicPackages` is stripped from MJServer's Zod-parsed `configInfo`.
|
|
10
|
+
*/
|
|
11
|
+
/** Named export Open App server packages use to publish their extension configs. */
|
|
12
|
+
export const MJ_SERVER_EXTENSIONS_EXPORT = 'MJ_SERVER_EXTENSIONS';
|
|
13
|
+
/** `package.json` path Open App server packages use for static introspection. */
|
|
14
|
+
export const MJ_SERVER_EXTENSIONS_PACKAGE_JSON_PATH = 'memberjunction.serverExtensions';
|
|
15
|
+
function cloneConfig(config) {
|
|
16
|
+
return {
|
|
17
|
+
Enabled: config.Enabled,
|
|
18
|
+
DriverClass: config.DriverClass,
|
|
19
|
+
RootPath: config.RootPath,
|
|
20
|
+
Settings: { ...(config.Settings ?? {}) },
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function invalid(options, message) {
|
|
24
|
+
options?.onInvalid?.(message);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Coerce unknown JSON / module-export data into `ServerExtensionConfig[]`.
|
|
28
|
+
* Invalid entries are skipped (not thrown) so one bad Open App declaration
|
|
29
|
+
* cannot take down server boot.
|
|
30
|
+
*/
|
|
31
|
+
export function normalizeServerExtensionConfigs(raw, options) {
|
|
32
|
+
const source = options?.source ? ` (${options.source})` : '';
|
|
33
|
+
if (raw == null) {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
if (!Array.isArray(raw)) {
|
|
37
|
+
invalid(options, `serverExtensions must be an array${source}`);
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
const result = [];
|
|
41
|
+
for (let i = 0; i < raw.length; i++) {
|
|
42
|
+
const entry = raw[i];
|
|
43
|
+
if (entry == null || typeof entry !== 'object' || Array.isArray(entry)) {
|
|
44
|
+
invalid(options, `serverExtensions[${i}] is not an object${source}`);
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const rec = entry;
|
|
48
|
+
const driverClass = typeof rec.DriverClass === 'string' ? rec.DriverClass.trim() : '';
|
|
49
|
+
if (!driverClass) {
|
|
50
|
+
invalid(options, `serverExtensions[${i}] missing DriverClass${source}`);
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const rootPath = typeof rec.RootPath === 'string' ? rec.RootPath.trim() : '';
|
|
54
|
+
if (!rootPath) {
|
|
55
|
+
invalid(options, `serverExtensions[${i}] ('${driverClass}') missing RootPath${source}`);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const rootError = validateServerExtensionRootPath(rootPath);
|
|
59
|
+
if (rootError) {
|
|
60
|
+
invalid(options, `serverExtensions[${i}] ('${driverClass}') ${rootError}${source}`);
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
let enabled = true;
|
|
64
|
+
if (rec.Enabled !== undefined) {
|
|
65
|
+
if (typeof rec.Enabled !== 'boolean') {
|
|
66
|
+
invalid(options, `serverExtensions[${i}] ('${driverClass}') Enabled must be a boolean${source}`);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
enabled = rec.Enabled;
|
|
70
|
+
}
|
|
71
|
+
const settings = rec.Settings != null && typeof rec.Settings === 'object' && !Array.isArray(rec.Settings)
|
|
72
|
+
? { ...rec.Settings }
|
|
73
|
+
: {};
|
|
74
|
+
if (rec.Settings != null && (typeof rec.Settings !== 'object' || Array.isArray(rec.Settings))) {
|
|
75
|
+
invalid(options, `serverExtensions[${i}] ('${driverClass}') Settings is not an object; using {}${source}`);
|
|
76
|
+
}
|
|
77
|
+
result.push({
|
|
78
|
+
Enabled: enabled,
|
|
79
|
+
DriverClass: driverClass,
|
|
80
|
+
RootPath: rootPath,
|
|
81
|
+
Settings: settings,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Read `MJ_SERVER_EXTENSIONS` from an already-imported Open App server module.
|
|
88
|
+
*/
|
|
89
|
+
export function extractServerExtensionsFromModule(mod, options) {
|
|
90
|
+
if (!mod || typeof mod !== 'object') {
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
93
|
+
if (!(MJ_SERVER_EXTENSIONS_EXPORT in mod)) {
|
|
94
|
+
return [];
|
|
95
|
+
}
|
|
96
|
+
return normalizeServerExtensionConfigs(mod[MJ_SERVER_EXTENSIONS_EXPORT], options);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Read `memberjunction.serverExtensions` from a parsed `package.json`.
|
|
100
|
+
*/
|
|
101
|
+
export function extractServerExtensionsFromPackageJson(pkgJson, options) {
|
|
102
|
+
if (pkgJson == null || typeof pkgJson !== 'object' || Array.isArray(pkgJson)) {
|
|
103
|
+
return [];
|
|
104
|
+
}
|
|
105
|
+
const memberjunction = pkgJson.memberjunction;
|
|
106
|
+
if (memberjunction == null || typeof memberjunction !== 'object' || Array.isArray(memberjunction)) {
|
|
107
|
+
return [];
|
|
108
|
+
}
|
|
109
|
+
return normalizeServerExtensionConfigs(memberjunction.serverExtensions, options);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Merge Open App–discovered extension configs with the host `mj.config.cjs` list.
|
|
113
|
+
*
|
|
114
|
+
* - Identity is `DriverClass`.
|
|
115
|
+
* - Later discovered entries replace earlier ones (ClassFactory last-wins).
|
|
116
|
+
* - Host overlay wins `Enabled` and `RootPath` when the host provides them;
|
|
117
|
+
* `Settings` is `{ ...discovered, ...host }`.
|
|
118
|
+
* - Host-only DriverClasses append after discovered ones.
|
|
119
|
+
* - A host `Enabled: false` entry is kept so the loader skips that DriverClass
|
|
120
|
+
* rather than falling back to the discovered one.
|
|
121
|
+
*/
|
|
122
|
+
export function mergeServerExtensionConfigs(discovered, host) {
|
|
123
|
+
const byClass = new Map();
|
|
124
|
+
const order = [];
|
|
125
|
+
const remember = (driverClass, config) => {
|
|
126
|
+
if (!byClass.has(driverClass)) {
|
|
127
|
+
order.push(driverClass);
|
|
128
|
+
}
|
|
129
|
+
byClass.set(driverClass, config);
|
|
130
|
+
};
|
|
131
|
+
for (const entry of discovered ?? []) {
|
|
132
|
+
const key = entry?.DriverClass?.trim();
|
|
133
|
+
if (!key) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
remember(key, cloneConfig({ ...entry, DriverClass: key }));
|
|
137
|
+
}
|
|
138
|
+
for (const entry of host ?? []) {
|
|
139
|
+
const key = entry?.DriverClass?.trim();
|
|
140
|
+
if (!key) {
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
const existing = byClass.get(key);
|
|
144
|
+
if (!existing) {
|
|
145
|
+
remember(key, cloneConfig({ ...entry, DriverClass: key }));
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
const hostRoot = typeof entry.RootPath === 'string' ? entry.RootPath.trim() : '';
|
|
149
|
+
remember(key, {
|
|
150
|
+
Enabled: entry.Enabled ?? existing.Enabled,
|
|
151
|
+
DriverClass: key,
|
|
152
|
+
RootPath: hostRoot || existing.RootPath,
|
|
153
|
+
Settings: { ...(existing.Settings ?? {}), ...(entry.Settings ?? {}) },
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
return order.map((key) => byClass.get(key));
|
|
157
|
+
}
|
|
158
|
+
/** Exact RootPaths that must never be claimed by an extension (they are the whole tree or a core endpoint). */
|
|
159
|
+
export const RESERVED_SERVER_EXTENSION_ROOTS = ['/'];
|
|
160
|
+
/**
|
|
161
|
+
* Baseline prefixes of core MJServer routes (always applied, including at discovery).
|
|
162
|
+
* Matching is case-insensitive and bidirectional — see `validateServerExtensionRootPath`.
|
|
163
|
+
* Prefix-with-slash so `/health` rejects `/health/extensions` but not `/healthcare`
|
|
164
|
+
* (sibling `/healthcheck` is supplied via `extraReservedRoots` from `serve()`).
|
|
165
|
+
*/
|
|
166
|
+
export const RESERVED_SERVER_EXTENSION_ROOT_PREFIXES = [
|
|
167
|
+
'/graphql',
|
|
168
|
+
'/auth',
|
|
169
|
+
'/oauth',
|
|
170
|
+
'/health',
|
|
171
|
+
'/magic-link',
|
|
172
|
+
];
|
|
173
|
+
export const MAX_SERVER_EXTENSION_ROOT_PATH_LENGTH = 128;
|
|
174
|
+
function normalizeRoot(rootPath) {
|
|
175
|
+
const trimmed = rootPath.trim();
|
|
176
|
+
if (trimmed === '/') {
|
|
177
|
+
return '/';
|
|
178
|
+
}
|
|
179
|
+
return trimmed.replace(/\/+$/, '') || '/';
|
|
180
|
+
}
|
|
181
|
+
/** Case-folded root for comparison. Express routing is case-insensitive by default. */
|
|
182
|
+
function foldRoot(rootPath) {
|
|
183
|
+
return normalizeRoot(rootPath).toLowerCase();
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Returns an error message when `rootPath` is unsafe to mount pre-auth, or `null` when it is usable.
|
|
187
|
+
* Fail closed: invalid paths must not be mounted.
|
|
188
|
+
*
|
|
189
|
+
* Reserved matching is case-insensitive (Express does not set `case sensitive routing`)
|
|
190
|
+
* and bidirectional: claiming a parent of a reserved prefix (`/telephony` vs `/telephony/twilio`)
|
|
191
|
+
* is also a collision because Express prefix-matches the parent.
|
|
192
|
+
*
|
|
193
|
+
* `extraReservedRoots` is the running server's actual mounts (graphqlRootPath, widget, …)
|
|
194
|
+
* so this check cannot drift from `serve()`. Discovery-time normalize uses only the
|
|
195
|
+
* static baseline; `prepareServerExtensionConfigs` passes the extras.
|
|
196
|
+
*/
|
|
197
|
+
export function validateServerExtensionRootPath(rootPath, extraReservedRoots) {
|
|
198
|
+
const raw = rootPath.trim();
|
|
199
|
+
if (!raw) {
|
|
200
|
+
return 'RootPath is empty';
|
|
201
|
+
}
|
|
202
|
+
if (!raw.startsWith('/')) {
|
|
203
|
+
return `RootPath '${raw}' must start with '/'`;
|
|
204
|
+
}
|
|
205
|
+
if (raw.length > MAX_SERVER_EXTENSION_ROOT_PATH_LENGTH) {
|
|
206
|
+
return `RootPath exceeds ${MAX_SERVER_EXTENSION_ROOT_PATH_LENGTH} characters`;
|
|
207
|
+
}
|
|
208
|
+
if (/[*?[\](){}]/.test(raw)) {
|
|
209
|
+
return `RootPath '${raw}' must not contain wildcards or glob characters`;
|
|
210
|
+
}
|
|
211
|
+
const folded = foldRoot(raw);
|
|
212
|
+
if (RESERVED_SERVER_EXTENSION_ROOTS.some((r) => foldRoot(r) === folded)) {
|
|
213
|
+
return `RootPath '${raw}' is reserved`;
|
|
214
|
+
}
|
|
215
|
+
const reservedPrefixes = [
|
|
216
|
+
...RESERVED_SERVER_EXTENSION_ROOT_PREFIXES,
|
|
217
|
+
...(extraReservedRoots ?? []).map((s) => (typeof s === 'string' ? s.trim() : '')).filter((s) => s.startsWith('/')),
|
|
218
|
+
];
|
|
219
|
+
const seen = new Set();
|
|
220
|
+
for (const prefix of reservedPrefixes) {
|
|
221
|
+
const foldedPrefix = foldRoot(prefix);
|
|
222
|
+
if (seen.has(foldedPrefix)) {
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
seen.add(foldedPrefix);
|
|
226
|
+
if (serverExtensionRootsOverlap(raw, prefix)) {
|
|
227
|
+
return `RootPath '${raw}' collides with the reserved prefix '${normalizeRoot(prefix)}'`;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
/** True when two roots are equal or one is a nested path of the other (case-insensitive). */
|
|
233
|
+
export function serverExtensionRootsOverlap(a, b) {
|
|
234
|
+
const na = foldRoot(a);
|
|
235
|
+
const nb = foldRoot(b);
|
|
236
|
+
if (na === nb) {
|
|
237
|
+
return true;
|
|
238
|
+
}
|
|
239
|
+
return na.startsWith(`${nb}/`) || nb.startsWith(`${na}/`);
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Post-merge filter used by `serve()`: drop invalid roots (fail closed) and warn when
|
|
243
|
+
* two *enabled* extensions claim overlapping paths. Disabled entries are kept so the
|
|
244
|
+
* loader can skip them by DriverClass (host `Enabled: false` stays visible).
|
|
245
|
+
*/
|
|
246
|
+
export function prepareServerExtensionConfigs(configs, options) {
|
|
247
|
+
const kept = [];
|
|
248
|
+
for (const entry of configs ?? []) {
|
|
249
|
+
const rootError = validateServerExtensionRootPath(entry.RootPath ?? '', options?.extraReservedRoots);
|
|
250
|
+
if (rootError) {
|
|
251
|
+
invalid(options, `Dropping server extension '${entry.DriverClass}': ${rootError}`);
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
kept.push(cloneConfig({ ...entry, RootPath: normalizeRoot(entry.RootPath) }));
|
|
255
|
+
}
|
|
256
|
+
const enabled = kept.filter((c) => c.Enabled);
|
|
257
|
+
for (let i = 0; i < enabled.length; i++) {
|
|
258
|
+
for (let j = i + 1; j < enabled.length; j++) {
|
|
259
|
+
if (serverExtensionRootsOverlap(enabled[i].RootPath, enabled[j].RootPath)) {
|
|
260
|
+
options?.onOverlap?.(`Enabled server extensions '${enabled[i].DriverClass}' (${enabled[i].RootPath}) and '${enabled[j].DriverClass}' (${enabled[j].RootPath}) have overlapping RootPaths`);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return kept;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* One-line inventory of a server-extension mount. All extension routes are installed
|
|
268
|
+
* BEFORE MJServer's auth middleware — the operator must be able to see that at boot.
|
|
269
|
+
*/
|
|
270
|
+
export function describeServerExtensionMount(config) {
|
|
271
|
+
const state = config.Enabled ? 'enabled' : 'disabled';
|
|
272
|
+
return `${config.DriverClass} at ${config.RootPath} (${state}, PRE-AUTH; host mj.config.cjs serverExtensions[] can set Enabled: false to suppress)`;
|
|
273
|
+
}
|
|
274
|
+
//# sourceMappingURL=collect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collect.js","sourceRoot":"","sources":["../src/collect.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,8 +8,11 @@
|
|
|
8
8
|
*
|
|
9
9
|
* This package defines the plugin architecture that allows any package to register
|
|
10
10
|
* Express routes and lifecycle hooks on a running MJServer instance. Extensions
|
|
11
|
-
* are discovered via MJ's standard `@RegisterClass` + `ClassFactory` pattern
|
|
12
|
-
*
|
|
11
|
+
* are discovered via MJ's standard `@RegisterClass` + `ClassFactory` pattern.
|
|
12
|
+
* Open App packages listed in host `dynamicPackages.server[]` declare their
|
|
13
|
+
* extensions via the `MJ_SERVER_EXTENSIONS` export (or `package.json`
|
|
14
|
+
* `memberjunction.serverExtensions`); the host `mj.config.cjs` `serverExtensions[]`
|
|
15
|
+
* overlays those by `DriverClass` and remains the place host-only extensions live.
|
|
13
16
|
*
|
|
14
17
|
* ## Quick Start
|
|
15
18
|
*
|
|
@@ -29,4 +32,6 @@
|
|
|
29
32
|
export { BaseServerExtension } from './BaseServerExtension.js';
|
|
30
33
|
export { ServerExtensionLoader } from './ServerExtensionLoader.js';
|
|
31
34
|
export { ServerExtensionConfig, ExtensionInitResult, ExtensionHealthResult, } from './types.js';
|
|
35
|
+
export { MJ_SERVER_EXTENSIONS_EXPORT, MJ_SERVER_EXTENSIONS_PACKAGE_JSON_PATH, MAX_SERVER_EXTENSION_ROOT_PATH_LENGTH, RESERVED_SERVER_EXTENSION_ROOTS, RESERVED_SERVER_EXTENSION_ROOT_PREFIXES, describeServerExtensionMount, extractServerExtensionsFromModule, extractServerExtensionsFromPackageJson, mergeServerExtensionConfigs, normalizeServerExtensionConfigs, prepareServerExtensionConfigs, serverExtensionRootsOverlap, validateServerExtensionRootPath, } from './collect.js';
|
|
36
|
+
export type { NormalizeServerExtensionOptions, PrepareServerExtensionOptions } from './collect.js';
|
|
32
37
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EACH,qBAAqB,EACrB,mBAAmB,EACnB,qBAAqB,GACxB,MAAM,YAAY,CAAC;AACpB,OAAO,EACH,2BAA2B,EAC3B,sCAAsC,EACtC,qCAAqC,EACrC,+BAA+B,EAC/B,uCAAuC,EACvC,4BAA4B,EAC5B,iCAAiC,EACjC,sCAAsC,EACtC,2BAA2B,EAC3B,+BAA+B,EAC/B,6BAA6B,EAC7B,2BAA2B,EAC3B,+BAA+B,GAClC,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,+BAA+B,EAAE,6BAA6B,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -8,8 +8,11 @@
|
|
|
8
8
|
*
|
|
9
9
|
* This package defines the plugin architecture that allows any package to register
|
|
10
10
|
* Express routes and lifecycle hooks on a running MJServer instance. Extensions
|
|
11
|
-
* are discovered via MJ's standard `@RegisterClass` + `ClassFactory` pattern
|
|
12
|
-
*
|
|
11
|
+
* are discovered via MJ's standard `@RegisterClass` + `ClassFactory` pattern.
|
|
12
|
+
* Open App packages listed in host `dynamicPackages.server[]` declare their
|
|
13
|
+
* extensions via the `MJ_SERVER_EXTENSIONS` export (or `package.json`
|
|
14
|
+
* `memberjunction.serverExtensions`); the host `mj.config.cjs` `serverExtensions[]`
|
|
15
|
+
* overlays those by `DriverClass` and remains the place host-only extensions live.
|
|
13
16
|
*
|
|
14
17
|
* ## Quick Start
|
|
15
18
|
*
|
|
@@ -28,4 +31,5 @@
|
|
|
28
31
|
*/
|
|
29
32
|
export { BaseServerExtension } from './BaseServerExtension.js';
|
|
30
33
|
export { ServerExtensionLoader } from './ServerExtensionLoader.js';
|
|
34
|
+
export { MJ_SERVER_EXTENSIONS_EXPORT, MJ_SERVER_EXTENSIONS_PACKAGE_JSON_PATH, MAX_SERVER_EXTENSION_ROOT_PATH_LENGTH, RESERVED_SERVER_EXTENSION_ROOTS, RESERVED_SERVER_EXTENSION_ROOT_PREFIXES, describeServerExtensionMount, extractServerExtensionsFromModule, extractServerExtensionsFromPackageJson, mergeServerExtensionConfigs, normalizeServerExtensionConfigs, prepareServerExtensionConfigs, serverExtensionRootsOverlap, validateServerExtensionRootPath, } from './collect.js';
|
|
31
35
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAMnE,OAAO,EACH,2BAA2B,EAC3B,sCAAsC,EACtC,qCAAqC,EACrC,+BAA+B,EAC/B,uCAAuC,EACvC,4BAA4B,EAC5B,iCAAiC,EACjC,sCAAsC,EACtC,2BAA2B,EAC3B,+BAA+B,EAC/B,6BAA6B,EAC7B,2BAA2B,EAC3B,+BAA+B,GAClC,MAAM,cAAc,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -3,10 +3,14 @@
|
|
|
3
3
|
* @description Core types for the MJServer extension framework.
|
|
4
4
|
*/
|
|
5
5
|
/**
|
|
6
|
-
* Configuration for a server extension instance
|
|
7
|
-
* array in `mj.config.cjs`.
|
|
6
|
+
* Configuration for a server extension instance.
|
|
8
7
|
*
|
|
9
|
-
*
|
|
8
|
+
* Loaded from the host `serverExtensions[]` in `mj.config.cjs`, and/or discovered
|
|
9
|
+
* from installed Open App server packages (`MJ_SERVER_EXTENSIONS` export or
|
|
10
|
+
* `package.json` `memberjunction.serverExtensions`). Host entries overlay
|
|
11
|
+
* discovered ones by `DriverClass`.
|
|
12
|
+
*
|
|
13
|
+
* Each entry corresponds to one extension instance. The `DriverClass`
|
|
10
14
|
* field is used to look up the registered class via `ClassFactory.CreateInstance()`.
|
|
11
15
|
*
|
|
12
16
|
* @example
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,WAAW,qBAAqB;IAClC,yFAAyF;IACzF,OAAO,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAChC,iFAAiF;IACjF,OAAO,EAAE,OAAO,CAAC;IAEjB,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE5B;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IAClC,qEAAqE;IACrE,OAAO,EAAE,OAAO,CAAC;IAEjB,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IAEb,wFAAwF;IACxF,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/server-extensions-core",
|
|
3
|
-
"version": "6.1.0-edge.
|
|
3
|
+
"version": "6.1.0-edge.6",
|
|
4
4
|
"description": "MemberJunction: Server Extension framework - plugin architecture for MJServer that enables auto-discovery and lifecycle management of extension modules",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"author": "MemberJunction.com",
|
|
12
12
|
"license": "BUSL-1.1",
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@memberjunction/global": "6.1.0-edge.
|
|
15
|
-
"@memberjunction/core": "6.1.0-edge.
|
|
14
|
+
"@memberjunction/global": "6.1.0-edge.6",
|
|
15
|
+
"@memberjunction/core": "6.1.0-edge.6",
|
|
16
16
|
"express": "^5.2.1"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|