codify-plugin-lib 1.0.166 → 1.0.168
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/dist/messages/handlers.js +1 -1
- package/dist/plugin/plugin.d.ts +2 -2
- package/dist/plugin/plugin.js +7 -3
- package/dist/pty/background-pty.js +5 -1
- package/dist/resource/resource-controller.d.ts +1 -1
- package/dist/resource/resource-controller.js +11 -1
- package/dist/resource/resource-settings.d.ts +6 -0
- package/dist/utils/utils.d.ts +5 -0
- package/dist/utils/utils.js +9 -0
- package/package.json +2 -2
- package/src/messages/handlers.ts +1 -1
- package/src/plugin/plugin.ts +9 -3
- package/src/pty/background-pty.ts +5 -1
- package/src/resource/resource-controller.ts +16 -1
- package/src/resource/resource-settings.ts +9 -2
- package/src/utils/utils.ts +12 -0
|
@@ -4,7 +4,7 @@ import { ApplyRequestDataSchema, ApplyResponseDataSchema, GetResourceInfoRequest
|
|
|
4
4
|
import { SudoError } from '../errors.js';
|
|
5
5
|
const SupportedRequests = {
|
|
6
6
|
'initialize': {
|
|
7
|
-
handler: async (plugin) => plugin.initialize(),
|
|
7
|
+
handler: async (plugin, data) => plugin.initialize(data),
|
|
8
8
|
requestValidator: InitializeRequestDataSchema,
|
|
9
9
|
responseValidator: InitializeResponseDataSchema
|
|
10
10
|
},
|
package/dist/plugin/plugin.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ApplyRequestData, GetResourceInfoRequestData, GetResourceInfoResponseData, ImportRequestData, ImportResponseData, InitializeResponseData, MatchRequestData, MatchResponseData, PlanRequestData, PlanResponseData, ResourceConfig, ResourceJson, ValidateRequestData, ValidateResponseData } from 'codify-schemas';
|
|
1
|
+
import { ApplyRequestData, GetResourceInfoRequestData, GetResourceInfoResponseData, ImportRequestData, ImportResponseData, InitializeRequestData, InitializeResponseData, MatchRequestData, MatchResponseData, PlanRequestData, PlanResponseData, ResourceConfig, ResourceJson, ValidateRequestData, ValidateResponseData } from 'codify-schemas';
|
|
2
2
|
import { Plan } from '../plan/plan.js';
|
|
3
3
|
import { BackgroundPty } from '../pty/background-pty.js';
|
|
4
4
|
import { Resource } from '../resource/resource.js';
|
|
@@ -10,7 +10,7 @@ export declare class Plugin {
|
|
|
10
10
|
planPty: BackgroundPty;
|
|
11
11
|
constructor(name: string, resourceControllers: Map<string, ResourceController<ResourceConfig>>);
|
|
12
12
|
static create(name: string, resources: Resource<any>[]): Plugin;
|
|
13
|
-
initialize(): Promise<InitializeResponseData>;
|
|
13
|
+
initialize(data: InitializeRequestData): Promise<InitializeResponseData>;
|
|
14
14
|
getResourceInfo(data: GetResourceInfoRequestData): Promise<GetResourceInfoResponseData>;
|
|
15
15
|
match(data: MatchRequestData): Promise<MatchResponseData>;
|
|
16
16
|
import(data: ImportRequestData): Promise<ImportResponseData>;
|
package/dist/plugin/plugin.js
CHANGED
|
@@ -4,6 +4,7 @@ import { BackgroundPty } from '../pty/background-pty.js';
|
|
|
4
4
|
import { getPty } from '../pty/index.js';
|
|
5
5
|
import { ResourceController } from '../resource/resource-controller.js';
|
|
6
6
|
import { ptyLocalStorage } from '../utils/pty-local-storage.js';
|
|
7
|
+
import { VerbosityLevel } from '../utils/utils.js';
|
|
7
8
|
export class Plugin {
|
|
8
9
|
name;
|
|
9
10
|
resourceControllers;
|
|
@@ -20,7 +21,10 @@ export class Plugin {
|
|
|
20
21
|
const controllersMap = new Map(controllers.map((r) => [r.typeId, r]));
|
|
21
22
|
return new Plugin(name, controllersMap);
|
|
22
23
|
}
|
|
23
|
-
async initialize() {
|
|
24
|
+
async initialize(data) {
|
|
25
|
+
if (data.verbosityLevel) {
|
|
26
|
+
VerbosityLevel.set(data.verbosityLevel);
|
|
27
|
+
}
|
|
24
28
|
for (const controller of this.resourceControllers.values()) {
|
|
25
29
|
await controller.initialize();
|
|
26
30
|
}
|
|
@@ -69,13 +73,13 @@ export class Plugin {
|
|
|
69
73
|
return { match };
|
|
70
74
|
}
|
|
71
75
|
async import(data) {
|
|
72
|
-
const { core, parameters } = data;
|
|
76
|
+
const { core, parameters, autoSearchAll } = data;
|
|
73
77
|
if (!this.resourceControllers.has(core.type)) {
|
|
74
78
|
throw new Error(`Cannot get info for resource ${core.type}, resource doesn't exist`);
|
|
75
79
|
}
|
|
76
80
|
const result = await ptyLocalStorage.run(this.planPty, () => this.resourceControllers
|
|
77
81
|
.get(core.type)
|
|
78
|
-
?.import(core, parameters));
|
|
82
|
+
?.import(core, parameters, autoSearchAll));
|
|
79
83
|
return {
|
|
80
84
|
request: data,
|
|
81
85
|
result: result ?? [],
|
|
@@ -5,6 +5,7 @@ import { EventEmitter } from 'node:events';
|
|
|
5
5
|
import * as fs from 'node:fs/promises';
|
|
6
6
|
import stripAnsi from 'strip-ansi';
|
|
7
7
|
import { debugLog } from '../utils/debug.js';
|
|
8
|
+
import { VerbosityLevel } from '../utils/utils.js';
|
|
8
9
|
import { SpawnError } from './index.js';
|
|
9
10
|
import { PromiseQueue } from './promise-queue.js';
|
|
10
11
|
EventEmitter.defaultMaxListeners = 1000;
|
|
@@ -62,7 +63,10 @@ export class BackgroundPty {
|
|
|
62
63
|
});
|
|
63
64
|
}
|
|
64
65
|
else {
|
|
65
|
-
|
|
66
|
+
// Print to stdout if the verbosity level is above 0
|
|
67
|
+
if (VerbosityLevel.get() > 0) {
|
|
68
|
+
process.stdout.write(data);
|
|
69
|
+
}
|
|
66
70
|
}
|
|
67
71
|
});
|
|
68
72
|
this.promiseQueue.run(async () => new Promise((resolve) => {
|
|
@@ -19,7 +19,7 @@ export declare class ResourceController<T extends StringIndexedObject> {
|
|
|
19
19
|
plan(core: ResourceConfig, desired: Partial<T> | null, state: Partial<T> | null, isStateful?: boolean): Promise<Plan<T>>;
|
|
20
20
|
planDestroy(core: ResourceConfig, parameters: Partial<T>): Promise<Plan<T>>;
|
|
21
21
|
apply(plan: Plan<T>): Promise<void>;
|
|
22
|
-
import(core: ResourceConfig, parameters: Partial<T
|
|
22
|
+
import(core: ResourceConfig, parameters: Partial<T>, autoSearchAll?: boolean): Promise<Array<ResourceJson> | null>;
|
|
23
23
|
private applyCreate;
|
|
24
24
|
private applyModify;
|
|
25
25
|
private applyDestroy;
|
|
@@ -181,7 +181,7 @@ export class ResourceController {
|
|
|
181
181
|
}
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
|
-
async import(core, parameters) {
|
|
184
|
+
async import(core, parameters, autoSearchAll = false) {
|
|
185
185
|
if (this.settings.importAndDestroy?.preventImport) {
|
|
186
186
|
throw new Error(`Type: ${this.typeId} cannot be imported`);
|
|
187
187
|
}
|
|
@@ -190,6 +190,16 @@ export class ResourceController {
|
|
|
190
190
|
isStateful: true,
|
|
191
191
|
originalDesiredConfig: structuredClone(parameters),
|
|
192
192
|
};
|
|
193
|
+
// Auto search means that no required parameters will be provided. We will try to generate it ourselves or return an
|
|
194
|
+
// empty array if they can't be.
|
|
195
|
+
if (autoSearchAll && this.settings.allowMultiple) {
|
|
196
|
+
if (this.settings.allowMultiple === true || !this.settings.allowMultiple.findAllParameters?.()) {
|
|
197
|
+
return [];
|
|
198
|
+
}
|
|
199
|
+
const parametersToImport = await this.settings.allowMultiple.findAllParameters?.();
|
|
200
|
+
const results = await Promise.all(parametersToImport.map((p) => this.import(core, p).catch(() => null)));
|
|
201
|
+
return results.filter(Boolean).flat();
|
|
202
|
+
}
|
|
193
203
|
this.addDefaultValues(parameters);
|
|
194
204
|
await this.applyTransformParameters(parameters);
|
|
195
205
|
// Use refresh parameters if specified, otherwise try to refresh as many parameters as possible here
|
|
@@ -44,6 +44,12 @@ export interface ResourceSettings<T extends StringIndexedObject> {
|
|
|
44
44
|
* @return The matched resource.
|
|
45
45
|
*/
|
|
46
46
|
matcher?: (desired: Partial<T>, current: Partial<T>) => boolean;
|
|
47
|
+
/**
|
|
48
|
+
* This method if supported by the resource returns an array of parameters that represent all of the possible
|
|
49
|
+
* instances of a resource on the system. An example of this is for the git-repository resource, this method returns
|
|
50
|
+
* a list of directories which are git repositories.
|
|
51
|
+
*/
|
|
52
|
+
findAllParameters?: () => Promise<Array<Partial<T>>>;
|
|
47
53
|
} | boolean;
|
|
48
54
|
/**
|
|
49
55
|
* If true, {@link StatefulParameter} remove() will be called before resource destruction. This is useful
|
package/dist/utils/utils.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { ResourceConfig, StringIndexedObject } from 'codify-schemas';
|
|
2
|
+
export declare const VerbosityLevel: {
|
|
3
|
+
level: number;
|
|
4
|
+
get(): number;
|
|
5
|
+
set(level: number): void;
|
|
6
|
+
};
|
|
2
7
|
export declare function isDebug(): boolean;
|
|
3
8
|
export declare function splitUserConfig<T extends StringIndexedObject>(config: ResourceConfig & T): {
|
|
4
9
|
parameters: T;
|
package/dist/utils/utils.js
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import os from 'node:os';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
export const VerbosityLevel = new class {
|
|
4
|
+
level = 0;
|
|
5
|
+
get() {
|
|
6
|
+
return this.level;
|
|
7
|
+
}
|
|
8
|
+
set(level) {
|
|
9
|
+
this.level = level;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
3
12
|
export function isDebug() {
|
|
4
13
|
return process.env.DEBUG != null && process.env.DEBUG.includes('codify'); // TODO: replace with debug library
|
|
5
14
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codify-plugin-lib",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.168",
|
|
4
4
|
"description": "Library plugin library",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"ajv": "^8.12.0",
|
|
18
18
|
"ajv-formats": "^2.1.1",
|
|
19
|
-
"codify-schemas": "1.0.
|
|
19
|
+
"codify-schemas": "1.0.74",
|
|
20
20
|
"@npmcli/promise-spawn": "^7.0.1",
|
|
21
21
|
"@homebridge/node-pty-prebuilt-multiarch": "^0.12.0-beta.5",
|
|
22
22
|
"uuid": "^10.0.0",
|
package/src/messages/handlers.ts
CHANGED
|
@@ -28,7 +28,7 @@ import { Plugin } from '../plugin/plugin.js';
|
|
|
28
28
|
|
|
29
29
|
const SupportedRequests: Record<string, { handler: (plugin: Plugin, data: any) => Promise<unknown>; requestValidator: SchemaObject; responseValidator: SchemaObject }> = {
|
|
30
30
|
'initialize': {
|
|
31
|
-
handler: async (plugin: Plugin) => plugin.initialize(),
|
|
31
|
+
handler: async (plugin: Plugin, data: any) => plugin.initialize(data),
|
|
32
32
|
requestValidator: InitializeRequestDataSchema,
|
|
33
33
|
responseValidator: InitializeResponseDataSchema
|
|
34
34
|
},
|
package/src/plugin/plugin.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
GetResourceInfoResponseData,
|
|
6
6
|
ImportRequestData,
|
|
7
7
|
ImportResponseData,
|
|
8
|
+
InitializeRequestData,
|
|
8
9
|
InitializeResponseData,
|
|
9
10
|
MatchRequestData,
|
|
10
11
|
MatchResponseData,
|
|
@@ -23,6 +24,7 @@ import { getPty } from '../pty/index.js';
|
|
|
23
24
|
import { Resource } from '../resource/resource.js';
|
|
24
25
|
import { ResourceController } from '../resource/resource-controller.js';
|
|
25
26
|
import { ptyLocalStorage } from '../utils/pty-local-storage.js';
|
|
27
|
+
import { VerbosityLevel } from '../utils/utils.js';
|
|
26
28
|
|
|
27
29
|
export class Plugin {
|
|
28
30
|
planStorage: Map<string, Plan<any>>;
|
|
@@ -46,7 +48,11 @@ export class Plugin {
|
|
|
46
48
|
return new Plugin(name, controllersMap);
|
|
47
49
|
}
|
|
48
50
|
|
|
49
|
-
async initialize(): Promise<InitializeResponseData> {
|
|
51
|
+
async initialize(data: InitializeRequestData): Promise<InitializeResponseData> {
|
|
52
|
+
if (data.verbosityLevel) {
|
|
53
|
+
VerbosityLevel.set(data.verbosityLevel);
|
|
54
|
+
}
|
|
55
|
+
|
|
50
56
|
for (const controller of this.resourceControllers.values()) {
|
|
51
57
|
await controller.initialize();
|
|
52
58
|
}
|
|
@@ -107,7 +113,7 @@ export class Plugin {
|
|
|
107
113
|
}
|
|
108
114
|
|
|
109
115
|
async import(data: ImportRequestData): Promise<ImportResponseData> {
|
|
110
|
-
const { core, parameters } = data;
|
|
116
|
+
const { core, parameters, autoSearchAll } = data;
|
|
111
117
|
|
|
112
118
|
if (!this.resourceControllers.has(core.type)) {
|
|
113
119
|
throw new Error(`Cannot get info for resource ${core.type}, resource doesn't exist`);
|
|
@@ -116,7 +122,7 @@ export class Plugin {
|
|
|
116
122
|
const result = await ptyLocalStorage.run(this.planPty, () =>
|
|
117
123
|
this.resourceControllers
|
|
118
124
|
.get(core.type!)
|
|
119
|
-
?.import(core, parameters)
|
|
125
|
+
?.import(core, parameters, autoSearchAll)
|
|
120
126
|
)
|
|
121
127
|
|
|
122
128
|
return {
|
|
@@ -6,6 +6,7 @@ import * as fs from 'node:fs/promises';
|
|
|
6
6
|
import stripAnsi from 'strip-ansi';
|
|
7
7
|
|
|
8
8
|
import { debugLog } from '../utils/debug.js';
|
|
9
|
+
import { VerbosityLevel } from '../utils/utils.js';
|
|
9
10
|
import { IPty, SpawnError, SpawnOptions, SpawnResult } from './index.js';
|
|
10
11
|
import { PromiseQueue } from './promise-queue.js';
|
|
11
12
|
|
|
@@ -76,7 +77,10 @@ export class BackgroundPty implements IPty {
|
|
|
76
77
|
data: strippedData,
|
|
77
78
|
});
|
|
78
79
|
} else {
|
|
79
|
-
|
|
80
|
+
// Print to stdout if the verbosity level is above 0
|
|
81
|
+
if (VerbosityLevel.get() > 0) {
|
|
82
|
+
process.stdout.write(data);
|
|
83
|
+
}
|
|
80
84
|
}
|
|
81
85
|
})
|
|
82
86
|
|
|
@@ -258,7 +258,8 @@ export class ResourceController<T extends StringIndexedObject> {
|
|
|
258
258
|
|
|
259
259
|
async import(
|
|
260
260
|
core: ResourceConfig,
|
|
261
|
-
parameters: Partial<T
|
|
261
|
+
parameters: Partial<T>,
|
|
262
|
+
autoSearchAll = false,
|
|
262
263
|
): Promise<Array<ResourceJson> | null> {
|
|
263
264
|
if (this.settings.importAndDestroy?.preventImport) {
|
|
264
265
|
throw new Error(`Type: ${this.typeId} cannot be imported`);
|
|
@@ -270,6 +271,20 @@ export class ResourceController<T extends StringIndexedObject> {
|
|
|
270
271
|
originalDesiredConfig: structuredClone(parameters),
|
|
271
272
|
};
|
|
272
273
|
|
|
274
|
+
// Auto search means that no required parameters will be provided. We will try to generate it ourselves or return an
|
|
275
|
+
// empty array if they can't be.
|
|
276
|
+
if (autoSearchAll && this.settings.allowMultiple) {
|
|
277
|
+
if (this.settings.allowMultiple === true || !this.settings.allowMultiple.findAllParameters?.()) {
|
|
278
|
+
return [];
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const parametersToImport = await this.settings.allowMultiple.findAllParameters?.();
|
|
282
|
+
const results = await Promise.all(parametersToImport.map((p) =>
|
|
283
|
+
this.import(core, p).catch(() => null))
|
|
284
|
+
);
|
|
285
|
+
return results.filter(Boolean).flat() as ResourceJson[];
|
|
286
|
+
}
|
|
287
|
+
|
|
273
288
|
this.addDefaultValues(parameters);
|
|
274
289
|
await this.applyTransformParameters(parameters);
|
|
275
290
|
|
|
@@ -43,7 +43,7 @@ export interface ResourceSettings<T extends StringIndexedObject> {
|
|
|
43
43
|
* If paramA is required, then if resource1.paramA === resource2.paramA then are the same resource.
|
|
44
44
|
* If resource1.paramA !== resource1.paramA, then they are different.
|
|
45
45
|
*/
|
|
46
|
-
identifyingParameters?: string[]
|
|
46
|
+
identifyingParameters?: string[];
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
49
|
* If multiple copies are allowed then a matcher must be defined to match the desired
|
|
@@ -54,7 +54,14 @@ export interface ResourceSettings<T extends StringIndexedObject> {
|
|
|
54
54
|
*
|
|
55
55
|
* @return The matched resource.
|
|
56
56
|
*/
|
|
57
|
-
matcher?: (desired: Partial<T>, current: Partial<T>) => boolean
|
|
57
|
+
matcher?: (desired: Partial<T>, current: Partial<T>) => boolean;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* This method if supported by the resource returns an array of parameters that represent all of the possible
|
|
61
|
+
* instances of a resource on the system. An example of this is for the git-repository resource, this method returns
|
|
62
|
+
* a list of directories which are git repositories.
|
|
63
|
+
*/
|
|
64
|
+
findAllParameters?: () => Promise<Array<Partial<T>>>
|
|
58
65
|
} | boolean
|
|
59
66
|
|
|
60
67
|
/**
|
package/src/utils/utils.ts
CHANGED
|
@@ -2,6 +2,18 @@ import { ResourceConfig, StringIndexedObject } from 'codify-schemas';
|
|
|
2
2
|
import os from 'node:os';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
|
|
5
|
+
export const VerbosityLevel = new class {
|
|
6
|
+
level = 0;
|
|
7
|
+
|
|
8
|
+
get() {
|
|
9
|
+
return this.level;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
set(level: number) {
|
|
13
|
+
this.level = level;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
5
17
|
export function isDebug(): boolean {
|
|
6
18
|
return process.env.DEBUG != null && process.env.DEBUG.includes('codify'); // TODO: replace with debug library
|
|
7
19
|
}
|