@jwilleke/ngdpbase-types 5.24.0 → 5.25.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/README.md +1 -1
- package/lib/packages/ngdpbase-types/index.d.ts +2 -2
- package/lib/packages/ngdpbase-types/testing.d.ts +7 -2
- package/lib/packages/ngdpbase-types/testing.js +7 -2
- package/lib/src/managers/AddonsManager.d.ts +82 -1
- package/lib/src/security/PolicyInformationPoint.d.ts +8 -0
- package/lib/src/utils/addonHost.d.ts +29 -3
- package/lib/src/utils/addonHost.js +16 -2
- package/lib/src/utils/addonPageSync.d.ts +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,6 +12,6 @@ import { buildAddonHost, openAddonTestDatabase, toCsv, formatters } from '@jwill
|
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
- The main entry is types only. Importing it at run time fails, on purpose.
|
|
15
|
-
- `/testing` is for tests. `buildAddonHost(slug, defaults)` is the real host. `openAddonTestDatabase(owner, { migrations, ledgerTable })` is the handle `openAddonDatabase` returns, in memory. `toCsv` is `ExportManager.toCsv`. `formatters` is a plugin's `context.formatters`.
|
|
15
|
+
- `/testing` is for tests. `buildAddonHost(slug, defaults, setEnabledForPerson?, engine?)` is the real host; `host.setEnabledForPerson` calls the setter you pass (it refuses without one), and `engine` names the system principal `host.systemContext(reason)` uses (core's fallback without one). `openAddonTestDatabase(owner, { migrations, ledgerTable })` is the handle `openAddonDatabase` returns, in memory. `toCsv` is `ExportManager.toCsv`. `formatters` is a plugin's `context.formatters`.
|
|
16
16
|
|
|
17
17
|
The add-on guide is [docs/guides/addons-developer-guide.md](https://github.com/jwilleke/ngdpbase/blob/master/docs/guides/addons-developer-guide.md).
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
* `@jwilleke/ngdpbase-types/testing`. A test holds this file to `export type`
|
|
15
15
|
* only, so the published entry carries no JavaScript.
|
|
16
16
|
*/
|
|
17
|
-
export type { AddonModule } from '../../src/managers/AddonsManager.js';
|
|
18
|
-
export type { AddonHost } from '../../src/utils/addonHost.js';
|
|
17
|
+
export type { AddonModule, AddonManifest, AddonListing } from '../../src/managers/AddonsManager.js';
|
|
18
|
+
export type { AddonHost, PersonSwitchSetter } from '../../src/utils/addonHost.js';
|
|
19
19
|
export type { WikiEngine } from '../../src/types/WikiEngine.js';
|
|
20
20
|
export type { ApiContext } from '../../src/context/ApiContext.js';
|
|
21
21
|
export type { ActorContext } from '../../src/context/ActorContext.js';
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import ExportManager from '../../src/managers/ExportManager.js';
|
|
5
5
|
import { type AddonDatabaseOptions } from '../../src/managers/DatabaseManager.js';
|
|
6
6
|
import { type SqliteHandle } from '../../src/providers/SqliteDatabaseProvider.js';
|
|
7
|
-
import { type AddonHost } from '../../src/utils/addonHost.js';
|
|
7
|
+
import { buildAddonHost as buildHost, type AddonHost, type PersonSwitchSetter } from '../../src/utils/addonHost.js';
|
|
8
8
|
export { formatters } from '../../src/managers/PluginManager.js';
|
|
9
9
|
/**
|
|
10
10
|
* Core's `buildAddonHost`, with the audit registry bound to this add-on's
|
|
@@ -15,8 +15,13 @@ export { formatters } from '../../src/managers/PluginManager.js';
|
|
|
15
15
|
*
|
|
16
16
|
* @param slug - The add-on's canonical slug
|
|
17
17
|
* @param addonDefaults - The add-on's own `config/default-config.json`
|
|
18
|
+
* @param setEnabledForPerson - What `host.setEnabledForPerson` does in the
|
|
19
|
+
* test (#1963); a site binds core's setter. Without one it refuses.
|
|
20
|
+
* @param engine - Optional: an engine (or stand-in) whose PolicyInformationPoint
|
|
21
|
+
* names the system principal for `host.systemContext`; without one it is
|
|
22
|
+
* core's fallback principal
|
|
18
23
|
*/
|
|
19
|
-
export declare function buildAddonHost(slug: string, addonDefaults: Record<string, unknown>): AddonHost;
|
|
24
|
+
export declare function buildAddonHost(slug: string, addonDefaults: Record<string, unknown>, setEnabledForPerson?: PersonSwitchSetter, engine?: Parameters<typeof buildHost>[3]): AddonHost;
|
|
20
25
|
/** The add-on whose declaration a test database is checked against: its slug and its own `config/default-config.json`. */
|
|
21
26
|
export interface AddonTestDatabaseDeclarer {
|
|
22
27
|
slug: string;
|
|
@@ -14,10 +14,15 @@ export { formatters } from '../../src/managers/PluginManager.js';
|
|
|
14
14
|
*
|
|
15
15
|
* @param slug - The add-on's canonical slug
|
|
16
16
|
* @param addonDefaults - The add-on's own `config/default-config.json`
|
|
17
|
+
* @param setEnabledForPerson - What `host.setEnabledForPerson` does in the
|
|
18
|
+
* test (#1963); a site binds core's setter. Without one it refuses.
|
|
19
|
+
* @param engine - Optional: an engine (or stand-in) whose PolicyInformationPoint
|
|
20
|
+
* names the system principal for `host.systemContext`; without one it is
|
|
21
|
+
* core's fallback principal
|
|
17
22
|
*/
|
|
18
|
-
export function buildAddonHost(slug, addonDefaults) {
|
|
23
|
+
export function buildAddonHost(slug, addonDefaults, setEnabledForPerson, engine) {
|
|
19
24
|
bindAuditEvents((key, fallback) => addonDefaults[key] ?? fallback);
|
|
20
|
-
return buildHost(slug, addonDefaults);
|
|
25
|
+
return buildHost(slug, addonDefaults, setEnabledForPerson, engine);
|
|
21
26
|
}
|
|
22
27
|
/**
|
|
23
28
|
* An add-on's database as `DatabaseManager.openAddonDatabase` returns it, in
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*
|
|
11
11
|
* @see {@link https://github.com/jwilleke/ngdpbase/issues/158}
|
|
12
12
|
*/
|
|
13
|
-
import type
|
|
13
|
+
import { type ActorContext } from '../context/ActorContext.js';
|
|
14
14
|
import BaseManager from './BaseManager.js';
|
|
15
15
|
import type { BackupData } from './BaseManager.js';
|
|
16
16
|
import type { WikiEngine } from '../types/WikiEngine.js';
|
|
@@ -208,7 +208,49 @@ export interface AddonManifest {
|
|
|
208
208
|
* docs/guides/addons-developer-guide.md "Declare a Private Store".
|
|
209
209
|
*/
|
|
210
210
|
stores?: unknown;
|
|
211
|
+
/**
|
|
212
|
+
* #1963: each person turns this add-on on or off for themselves. Their
|
|
213
|
+
* switch is the preference `<slug>.enabled` (`personSwitchKey`), read only
|
|
214
|
+
* by `AddonsManager.enabledAddonsFor` and written only through
|
|
215
|
+
* `host.setEnabledForPerson`. Absent or anything but `true`: not per-person.
|
|
216
|
+
*/
|
|
217
|
+
perPerson?: boolean;
|
|
218
|
+
/**
|
|
219
|
+
* #1965: the add-on's About page, a page it ships in `pages/`, by uuid or
|
|
220
|
+
* slug. `[{ConfigAccessor type='addons'}]` links to it ("More about it").
|
|
221
|
+
* The site overrides it with `ngdpbase.addons.<slug>.about-page`.
|
|
222
|
+
*/
|
|
223
|
+
aboutPage?: string;
|
|
224
|
+
/**
|
|
225
|
+
* #1965: the heading the add-on is listed under, shared by related add-ons
|
|
226
|
+
* (e.g. "Accounting" for accounting, accounting-donations and accounting-dues).
|
|
227
|
+
*/
|
|
228
|
+
family?: string;
|
|
229
|
+
/** #1965: `false` keeps plumbing (e.g. elasticsearch) out of the add-on listings. */
|
|
230
|
+
listed?: boolean;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* One add-on as the listings show it (#1965), from `AddonsManager.listedAddons()`.
|
|
234
|
+
* `version`, `loaded` and `error` are for administrators; the plugin that
|
|
235
|
+
* renders a listing decides who sees them.
|
|
236
|
+
*/
|
|
237
|
+
export interface AddonListing {
|
|
238
|
+
slug: string;
|
|
239
|
+
description: string;
|
|
240
|
+
/** The heading it is grouped under, or null */
|
|
241
|
+
family: string | null;
|
|
242
|
+
/** The About page (uuid or slug), the site's override first; null when none */
|
|
243
|
+
aboutPage: string | null;
|
|
244
|
+
perPerson: boolean;
|
|
245
|
+
version: string;
|
|
246
|
+
loaded: boolean;
|
|
247
|
+
error: string | null;
|
|
211
248
|
}
|
|
249
|
+
/**
|
|
250
|
+
* The preference that holds a person's switch for a per-person add-on (#1963):
|
|
251
|
+
* `<slug>.enabled`. The one place the key is spelled.
|
|
252
|
+
*/
|
|
253
|
+
export declare function personSwitchKey(slug: string): string;
|
|
212
254
|
/**
|
|
213
255
|
* Details returned by add-on's status() method
|
|
214
256
|
*/
|
|
@@ -262,6 +304,7 @@ export interface AddonStatus {
|
|
|
262
304
|
* AddonsManager - Manages optional add-on modules
|
|
263
305
|
*/
|
|
264
306
|
declare class AddonsManager extends BaseManager {
|
|
307
|
+
#private;
|
|
265
308
|
/** Map of discovered add-ons by name */
|
|
266
309
|
private addons;
|
|
267
310
|
/** Configured paths to addons directories (one or more) */
|
|
@@ -282,6 +325,8 @@ declare class AddonsManager extends BaseManager {
|
|
|
282
325
|
private domainAddonName;
|
|
283
326
|
/** #1883: the enabled add-ons that did not load this start, with why — each reported once. */
|
|
284
327
|
private readonly loadFailures;
|
|
328
|
+
/** #1973: every enabled add-on has had its turn to load this boot (see {@link addonsLoaded}). */
|
|
329
|
+
private loadPassDone;
|
|
285
330
|
constructor(engine: WikiEngine);
|
|
286
331
|
/**
|
|
287
332
|
* Initialize the AddonsManager
|
|
@@ -405,6 +450,20 @@ declare class AddonsManager extends BaseManager {
|
|
|
405
450
|
ok: false;
|
|
406
451
|
blockedBy: string[];
|
|
407
452
|
};
|
|
453
|
+
/**
|
|
454
|
+
* The installed version of an add-on (#1973): the `version` in its
|
|
455
|
+
* package.json, or its module's `version` when the package.json has none.
|
|
456
|
+
* Undefined for an add-on that was not discovered.
|
|
457
|
+
*
|
|
458
|
+
* @param slug - The add-on's slug
|
|
459
|
+
*/
|
|
460
|
+
getAddonVersion(slug: string): string | undefined;
|
|
461
|
+
/**
|
|
462
|
+
* Whether this boot's load pass is over (#1973): every enabled add-on has
|
|
463
|
+
* had its `register()` called, loaded or not. Until then, what an add-on has
|
|
464
|
+
* not registered yet says nothing about whether it still provides it.
|
|
465
|
+
*/
|
|
466
|
+
addonsLoaded(): boolean;
|
|
408
467
|
/**
|
|
409
468
|
* Get add-on specific configuration
|
|
410
469
|
*/
|
|
@@ -614,6 +673,28 @@ declare class AddonsManager extends BaseManager {
|
|
|
614
673
|
* other addons' saves or the core-preferences save.
|
|
615
674
|
*/
|
|
616
675
|
saveProfileSections(ctx: ActorContext, body: Record<string, unknown>): Promise<void>;
|
|
676
|
+
/**
|
|
677
|
+
* The add-ons the site's listings show (#1965): enabled, and not
|
|
678
|
+
* `listed: false` in their manifest, in load order. Cheap: it calls no
|
|
679
|
+
* add-on's status(), so a page can render it.
|
|
680
|
+
*/
|
|
681
|
+
listedAddons(): AddonListing[];
|
|
682
|
+
/** #1963: the loaded add-ons whose manifest says `perPerson: true`, in load order. */
|
|
683
|
+
private perPersonAddons;
|
|
684
|
+
/**
|
|
685
|
+
* The per-person add-ons this subject has turned on (#1963): each loaded
|
|
686
|
+
* add-on whose manifest says `perPerson: true` and whose switch, the
|
|
687
|
+
* person's preference `<slug>.enabled`, is `true`.
|
|
688
|
+
*
|
|
689
|
+
* It reads exactly those keys and no other preference, so no access check
|
|
690
|
+
* or listing built on it can come to depend on an arbitrary setting. An
|
|
691
|
+
* anonymous subject, an unknown or inactive account, and the system
|
|
692
|
+
* principal (which has no account) have none.
|
|
693
|
+
*
|
|
694
|
+
* @param ctx - Whose add-ons: the request's subject, or a job's context
|
|
695
|
+
* @returns The slugs, in load order
|
|
696
|
+
*/
|
|
697
|
+
enabledAddonsFor(ctx: ActorContext): Promise<string[]>;
|
|
617
698
|
/**
|
|
618
699
|
* Get count of loaded add-ons
|
|
619
700
|
*/
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import BaseManager from '../managers/BaseManager.js';
|
|
2
|
+
import type { ActorContext } from '../context/ActorContext.js';
|
|
2
3
|
import { WikiEngine } from '../types/WikiEngine.js';
|
|
3
4
|
import type { AgentTokenGrant, ProxyClaim } from '../managers/UserManager.js';
|
|
4
5
|
import type { Request } from 'express';
|
|
@@ -201,6 +202,13 @@ declare class PolicyInformationPoint extends BaseManager {
|
|
|
201
202
|
* session at all, so the session path alone would still have said Anonymous.
|
|
202
203
|
*/
|
|
203
204
|
currentSubject(req: Request): Promise<UserContext>;
|
|
205
|
+
/**
|
|
206
|
+
* The subject's per-person add-ons that are turned on (#1963): an attribute
|
|
207
|
+
* the PIP supplies to a decision (the page audience `addon:<slug>`, #1964)
|
|
208
|
+
* the way it supplies roles from RoleManager. AddonsManager owns the answer;
|
|
209
|
+
* none when it is not running.
|
|
210
|
+
*/
|
|
211
|
+
subjectEnabledAddons(ctx: ActorContext): Promise<string[]>;
|
|
204
212
|
private userManager;
|
|
205
213
|
private roleManager;
|
|
206
214
|
/**
|
|
@@ -10,6 +10,11 @@
|
|
|
10
10
|
* - `recordAuditEvent` and `addonAuditEventName` accept only the audit events
|
|
11
11
|
* this add-on declares in its own `config/default-config.json`, so one
|
|
12
12
|
* add-on cannot write records that look like another's or like core's;
|
|
13
|
+
* - `systemContext(reason)` is bound to the running engine, so the system
|
|
14
|
+
* principal's name comes from core (`NGDPBASE_SYSTEM_USER`), never from
|
|
15
|
+
* the add-on (#1973);
|
|
16
|
+
* - `setEnabledForPerson` sets this add-on's own per-person switch (#1963),
|
|
17
|
+
* bound to its slug, so it can never set another add-on's;
|
|
13
18
|
* - the object is `Object.freeze`d, so no add-on can replace a value.
|
|
14
19
|
*
|
|
15
20
|
* Additive only: nothing here is removed or renamed without a major release.
|
|
@@ -17,8 +22,9 @@
|
|
|
17
22
|
*/
|
|
18
23
|
import type { Logger } from 'winston';
|
|
19
24
|
import { ApiContext, ApiError, sendApiError } from '../context/ApiContext.js';
|
|
20
|
-
import { actorOf } from '../context/ActorContext.js';
|
|
21
|
-
import { jobContextFromRequest, jobContextFromSystem } from '../context/JobContext.js';
|
|
25
|
+
import { actorOf, type ActorContext } from '../context/ActorContext.js';
|
|
26
|
+
import { jobContextFromRequest, jobContextFromSystem, type JobContext } from '../context/JobContext.js';
|
|
27
|
+
import { systemContext } from '../context/bootActions.js';
|
|
22
28
|
import { guardedFetch } from '../http/guardedFetch.js';
|
|
23
29
|
import { recordAuditEvent } from './auditEvents.js';
|
|
24
30
|
import { addonAuditEventName } from './auditEventNames.js';
|
|
@@ -32,9 +38,25 @@ export interface AddonHost {
|
|
|
32
38
|
readonly actorOf: typeof actorOf;
|
|
33
39
|
readonly jobContextFromRequest: typeof jobContextFromRequest;
|
|
34
40
|
readonly jobContextFromSystem: typeof jobContextFromSystem;
|
|
41
|
+
/**
|
|
42
|
+
* The context the add-on's own boot work runs under (#1973): core's system
|
|
43
|
+
* principal, with `reason` saying what and why, for the record. Pass it
|
|
44
|
+
* where a manager door asks for a context at start, such as
|
|
45
|
+
* `FormsDataManager.registerShippedForm`.
|
|
46
|
+
*/
|
|
47
|
+
readonly systemContext: (reason: string) => JobContext;
|
|
35
48
|
readonly logger: Logger;
|
|
36
49
|
readonly guardedFetch: typeof guardedFetch;
|
|
50
|
+
/**
|
|
51
|
+
* #1963: turn this per-person add-on on (`true`) or off (`false`) for the
|
|
52
|
+
* person `ctx` acts as: their preference `<slug>.enabled`. Pass the context
|
|
53
|
+
* you were given (a profile hook's `ctx`). Refused when the add-on's manifest
|
|
54
|
+
* does not say `perPerson: true`, or the person may not manage their profile.
|
|
55
|
+
*/
|
|
56
|
+
readonly setEnabledForPerson: PersonSwitchSetter;
|
|
37
57
|
}
|
|
58
|
+
/** Sets one add-on's per-person switch; core binds the slug when it builds the host (#1963). */
|
|
59
|
+
export type PersonSwitchSetter = (ctx: ActorContext, on: boolean) => Promise<void>;
|
|
38
60
|
/**
|
|
39
61
|
* The audit event names one add-on declares: the permission entries carrying
|
|
40
62
|
* an `audit` block, and the `ngdpbase.audit.events` entries, in that add-on's
|
|
@@ -47,5 +69,9 @@ export declare function addonDeclaredAuditEvents(addonDefaults: Record<string, u
|
|
|
47
69
|
* @param slug - The add-on's canonical slug
|
|
48
70
|
* @param addonDefaults - That add-on's own default-config.json, as folded into
|
|
49
71
|
* the configuration merge (`ConfigurationManager.getAddonDeclaredDefaults`)
|
|
72
|
+
* @param setEnabledForPerson - This add-on's switch setter, slug already bound
|
|
73
|
+
* (`AddonsManager` supplies it); without one, the host's setter refuses
|
|
74
|
+
* @param engine - The running engine, which names the system principal for
|
|
75
|
+
* `systemContext`; without one (a test) it is core's fallback principal
|
|
50
76
|
*/
|
|
51
|
-
export declare function buildAddonHost(slug: string, addonDefaults: Record<string, unknown>): AddonHost;
|
|
77
|
+
export declare function buildAddonHost(slug: string, addonDefaults: Record<string, unknown>, setEnabledForPerson?: PersonSwitchSetter, engine?: Parameters<typeof systemContext>[0]): AddonHost;
|
|
@@ -10,6 +10,11 @@
|
|
|
10
10
|
* - `recordAuditEvent` and `addonAuditEventName` accept only the audit events
|
|
11
11
|
* this add-on declares in its own `config/default-config.json`, so one
|
|
12
12
|
* add-on cannot write records that look like another's or like core's;
|
|
13
|
+
* - `systemContext(reason)` is bound to the running engine, so the system
|
|
14
|
+
* principal's name comes from core (`NGDPBASE_SYSTEM_USER`), never from
|
|
15
|
+
* the add-on (#1973);
|
|
16
|
+
* - `setEnabledForPerson` sets this add-on's own per-person switch (#1963),
|
|
17
|
+
* bound to its slug, so it can never set another add-on's;
|
|
13
18
|
* - the object is `Object.freeze`d, so no add-on can replace a value.
|
|
14
19
|
*
|
|
15
20
|
* Additive only: nothing here is removed or renamed without a major release.
|
|
@@ -18,11 +23,14 @@
|
|
|
18
23
|
import { ApiContext, ApiError, sendApiError } from '../context/ApiContext.js';
|
|
19
24
|
import { actorOf } from '../context/ActorContext.js';
|
|
20
25
|
import { jobContextFromRequest, jobContextFromSystem } from '../context/JobContext.js';
|
|
26
|
+
import { systemContext } from '../context/bootActions.js';
|
|
21
27
|
import { guardedFetch } from '../http/guardedFetch.js';
|
|
22
28
|
import { recordAuditEvent } from './auditEvents.js';
|
|
23
29
|
import { addonAuditEventName } from './auditEventNames.js';
|
|
24
30
|
import { auditDeclarationsFrom } from './auditRegistry.js';
|
|
25
31
|
import logger from './logger.js';
|
|
32
|
+
/** A host built outside a site (the test kit, with no setter given) has no account store. */
|
|
33
|
+
const noPersonSwitch = () => Promise.reject(new Error('setEnabledForPerson is not available: this host was built without a site'));
|
|
26
34
|
/**
|
|
27
35
|
* The audit event names one add-on declares: the permission entries carrying
|
|
28
36
|
* an `audit` block, and the `ngdpbase.audit.events` entries, in that add-on's
|
|
@@ -45,8 +53,12 @@ function refuseUndeclared(slug, name, declared) {
|
|
|
45
53
|
* @param slug - The add-on's canonical slug
|
|
46
54
|
* @param addonDefaults - That add-on's own default-config.json, as folded into
|
|
47
55
|
* the configuration merge (`ConfigurationManager.getAddonDeclaredDefaults`)
|
|
56
|
+
* @param setEnabledForPerson - This add-on's switch setter, slug already bound
|
|
57
|
+
* (`AddonsManager` supplies it); without one, the host's setter refuses
|
|
58
|
+
* @param engine - The running engine, which names the system principal for
|
|
59
|
+
* `systemContext`; without one (a test) it is core's fallback principal
|
|
48
60
|
*/
|
|
49
|
-
export function buildAddonHost(slug, addonDefaults) {
|
|
61
|
+
export function buildAddonHost(slug, addonDefaults, setEnabledForPerson = noPersonSwitch, engine) {
|
|
50
62
|
const declared = addonDeclaredAuditEvents(addonDefaults);
|
|
51
63
|
const hostAddonAuditEventName = (name) => {
|
|
52
64
|
const checked = addonAuditEventName(name);
|
|
@@ -66,7 +78,9 @@ export function buildAddonHost(slug, addonDefaults) {
|
|
|
66
78
|
actorOf,
|
|
67
79
|
jobContextFromRequest,
|
|
68
80
|
jobContextFromSystem,
|
|
81
|
+
systemContext: (reason) => systemContext(engine, reason),
|
|
69
82
|
logger: logger.child({ addon: slug }),
|
|
70
|
-
guardedFetch
|
|
83
|
+
guardedFetch,
|
|
84
|
+
setEnabledForPerson
|
|
71
85
|
});
|
|
72
86
|
}
|
|
@@ -34,8 +34,8 @@ export declare function evaluateSeededAddonPage(args: {
|
|
|
34
34
|
/**
|
|
35
35
|
* How a shipped item's sync status reads on an admin screen: the status words
|
|
36
36
|
* and the edit protection of Admin → Required Pages, which every screen that
|
|
37
|
-
* syncs shipped content shares (`views/_sync-status.ejs`, `views/_sync-button.ejs
|
|
38
|
-
*
|
|
37
|
+
* syncs shipped content shares (`views/_sync-status.ejs`, `views/_sync-button.ejs`,
|
|
38
|
+
* #1918).
|
|
39
39
|
*
|
|
40
40
|
* - `status` — `modified` when the live copy differs from what ships,
|
|
41
41
|
* `current` when it is the same.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jwilleke/ngdpbase-types",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.25.0",
|
|
4
4
|
"description": "TypeScript types for ngdpbase add-ons, and a test kit of core's own values. A dev dependency, versioned with ngdpbase.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Jim Willeke",
|