codify-plugin-lib 1.0.182-beta31 → 1.0.182-beta32

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.
@@ -1,15 +1,15 @@
1
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
- import { Resource } from '../resource/resource.js';
5
4
  import { ResourceController } from '../resource/resource-controller.js';
6
5
  export declare class Plugin {
7
6
  name: string;
7
+ version: string;
8
8
  resourceControllers: Map<string, ResourceController<ResourceConfig>>;
9
9
  planStorage: Map<string, Plan<any>>;
10
10
  planPty: BackgroundPty;
11
- constructor(name: string, resourceControllers: Map<string, ResourceController<ResourceConfig>>);
12
- static create(name: string, resources: Resource<any>[]): Plugin;
11
+ constructor(name: string, version: string, resourceControllers: Map<string, ResourceController<ResourceConfig>>);
12
+ static create(): Promise<Plugin>;
13
13
  initialize(data: InitializeRequestData): Promise<InitializeResponseData>;
14
14
  getResourceInfo(data: GetResourceInfoRequestData): GetResourceInfoResponseData;
15
15
  match(data: MatchRequestData): Promise<MatchResponseData>;
@@ -4,23 +4,37 @@ import { BackgroundPty } from '../pty/background-pty.js';
4
4
  import { getPty } from '../pty/index.js';
5
5
  import { SequentialPty } from '../pty/seqeuntial-pty.js';
6
6
  import { ResourceController } from '../resource/resource-controller.js';
7
+ import { listAllResources } from '../utils/load-resources.js';
8
+ import { readNearestPackageJson } from '../utils/package-json-utils.js';
7
9
  import { ptyLocalStorage } from '../utils/pty-local-storage.js';
8
10
  import { VerbosityLevel } from '../utils/verbosity-level.js';
9
11
  export class Plugin {
10
12
  name;
13
+ version;
11
14
  resourceControllers;
12
15
  planStorage;
13
16
  planPty = new BackgroundPty();
14
- constructor(name, resourceControllers) {
17
+ constructor(name, version, resourceControllers) {
15
18
  this.name = name;
19
+ this.version = version;
16
20
  this.resourceControllers = resourceControllers;
17
21
  this.planStorage = new Map();
18
22
  }
19
- static create(name, resources) {
23
+ static async create() {
24
+ const packageJson = readNearestPackageJson();
25
+ if (!packageJson) {
26
+ throw new Error('Failed to read nearest package.json');
27
+ }
28
+ const { name, version } = packageJson;
29
+ const resourceLocations = await listAllResources();
30
+ const resources = await Promise.all(resourceLocations.map((l) => {
31
+ return import(l);
32
+ }));
33
+ console.log(resources);
20
34
  const controllers = resources
21
35
  .map((resource) => new ResourceController(resource));
22
36
  const controllersMap = new Map(controllers.map((r) => [r.typeId, r]));
23
- return new Plugin(name, controllersMap);
37
+ return new Plugin(name, version, controllersMap);
24
38
  }
25
39
  async initialize(data) {
26
40
  if (data.verbosityLevel) {
@@ -2,8 +2,8 @@ import { JSONSchemaType } from 'ajv';
2
2
  import { OS, StringIndexedObject } from 'codify-schemas';
3
3
  import { ZodObject } from 'zod';
4
4
  import { ArrayStatefulParameter, StatefulParameter } from '../stateful-parameter/stateful-parameter.js';
5
- import { RefreshContext } from './resource.js';
6
5
  import { ParsedResourceSettings } from './parsed-resource-settings.js';
6
+ import { RefreshContext } from './resource.js';
7
7
  export interface InputTransformation {
8
8
  to: (input: any) => Promise<any> | any;
9
9
  from: (current: any, original: any) => Promise<any> | any;
@@ -3,7 +3,7 @@ import path from 'node:path';
3
3
  import { addVariablesToPath, areArraysEqual, resolvePathWithVariables, tildify, untildify } from '../utils/functions.js';
4
4
  const ParameterEqualsDefaults = {
5
5
  'boolean': (a, b) => Boolean(a) === Boolean(b),
6
- 'directory': (a, b) => {
6
+ 'directory'(a, b) {
7
7
  let transformedA = resolvePathWithVariables(untildify(String(a)));
8
8
  let transformedB = resolvePathWithVariables(untildify(String(b)));
9
9
  if (transformedA.startsWith('.')) { // Only relative paths start with '.'
@@ -65,7 +65,7 @@ export function resolveFnFromEqualsFnOrString(fnOrString) {
65
65
  const ParameterTransformationDefaults = {
66
66
  'directory': {
67
67
  to: (a) => resolvePathWithVariables((untildify(String(a)))),
68
- from: (a, original) => {
68
+ from(a, original) {
69
69
  if (ParameterEqualsDefaults.directory(a, original)) {
70
70
  return original;
71
71
  }
@@ -0,0 +1 @@
1
+ export declare const listAllResources: () => Promise<string[]>;
@@ -0,0 +1,43 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ export const listAllResources = async () => {
4
+ const resourceDir = await fs.readdir('./src/resources');
5
+ const dedupSet = new Set();
6
+ const result = new Set();
7
+ for (const folder of resourceDir) {
8
+ if (await fs.stat(path.join('./src/resources', folder)).then(s => s.isDirectory()).catch(() => false)) {
9
+ for (const folderContents of await fs.readdir(path.join('./src/resources', folder))) {
10
+ const isDirectory = await fs.stat(path.join('./src/resources', folder, folderContents)).then(s => s.isDirectory());
11
+ // console.log(folderContents, isDirectory);
12
+ if (isDirectory) {
13
+ for (const innerContents of await fs.readdir(path.join('./src/resources', folder, folderContents))) {
14
+ if (!dedupSet.has(path.join('./src/resources', folder, folderContents))) {
15
+ dedupSet.add(path.join('./src/resources', folder, folderContents));
16
+ addResourceFromDir(path.join('./src/resources', folder, folderContents), result);
17
+ }
18
+ }
19
+ }
20
+ else {
21
+ if (!dedupSet.has(path.join('./src/resources', folder))) {
22
+ dedupSet.add(path.join('./src/resources', folder));
23
+ addResourceFromDir(path.join('./src/resources', folder), result);
24
+ }
25
+ }
26
+ }
27
+ }
28
+ else {
29
+ throw new Error('Only directories are allowed in resources folder');
30
+ }
31
+ }
32
+ return [...result];
33
+ };
34
+ function addResourceFromDir(dir, result) {
35
+ try {
36
+ const resourceFile = path.resolve(path.join(dir, 'resource.ts'));
37
+ if (!(fs.stat(resourceFile).then((s) => s.isFile())).catch(() => false)) {
38
+ return;
39
+ }
40
+ result.add(resourceFile);
41
+ }
42
+ catch { }
43
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Find the nearest package.json starting from a directory and walking upward.
3
+ * @param {string} startDir - Directory to start searching from
4
+ * @returns {string|null} Absolute path to package.json or null if not found
5
+ */
6
+ export declare function findNearestPackageJson(startDir?: string): string | null;
7
+ /**
8
+ * Read and parse the nearest package.json
9
+ * @param {string} startDir
10
+ * @returns {object|null}
11
+ */
12
+ export declare function readNearestPackageJson(startDir?: string): any;
@@ -0,0 +1,34 @@
1
+ import * as fs from 'node:fs';
2
+ import path from 'node:path';
3
+ /**
4
+ * Find the nearest package.json starting from a directory and walking upward.
5
+ * @param {string} startDir - Directory to start searching from
6
+ * @returns {string|null} Absolute path to package.json or null if not found
7
+ */
8
+ export function findNearestPackageJson(startDir = process.cwd()) {
9
+ let currentDir = path.resolve(startDir);
10
+ while (true) {
11
+ const pkgPath = path.join(currentDir, "package.json");
12
+ if (fs.existsSync(pkgPath)) {
13
+ return pkgPath;
14
+ }
15
+ const parentDir = path.dirname(currentDir);
16
+ if (parentDir === currentDir) {
17
+ // Reached filesystem root
18
+ return null;
19
+ }
20
+ currentDir = parentDir;
21
+ }
22
+ }
23
+ /**
24
+ * Read and parse the nearest package.json
25
+ * @param {string} startDir
26
+ * @returns {object|null}
27
+ */
28
+ export function readNearestPackageJson(startDir = process.cwd()) {
29
+ const pkgPath = findNearestPackageJson(startDir);
30
+ if (!pkgPath)
31
+ return null;
32
+ const contents = fs.readFileSync(pkgPath, 'utf8');
33
+ return JSON.parse(contents);
34
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codify-plugin-lib",
3
- "version": "1.0.182-beta31",
3
+ "version": "1.0.182-beta32",
4
4
  "description": "Library plugin library",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -177,7 +177,7 @@ describe('Plugin tests', () => {
177
177
  plugins: z
178
178
  .array(z.string())
179
179
  .describe(
180
- "Asdf plugins to install. See: https://github.com/asdf-community for a full list"
180
+ 'Asdf plugins to install. See: https://github.com/asdf-community for a full list'
181
181
  )
182
182
  })
183
183
  .strict()
@@ -22,8 +22,9 @@ import { Plan } from '../plan/plan.js';
22
22
  import { BackgroundPty } from '../pty/background-pty.js';
23
23
  import { getPty } from '../pty/index.js';
24
24
  import { SequentialPty } from '../pty/seqeuntial-pty.js';
25
- import { Resource } from '../resource/resource.js';
26
25
  import { ResourceController } from '../resource/resource-controller.js';
26
+ import { listAllResources } from '../utils/load-resources.js';
27
+ import { readNearestPackageJson } from '../utils/package-json-utils.js';
27
28
  import { ptyLocalStorage } from '../utils/pty-local-storage.js';
28
29
  import { VerbosityLevel } from '../utils/verbosity-level.js';
29
30
 
@@ -33,12 +34,27 @@ export class Plugin {
33
34
 
34
35
  constructor(
35
36
  public name: string,
37
+ public version: string,
36
38
  public resourceControllers: Map<string, ResourceController<ResourceConfig>>
37
39
  ) {
38
40
  this.planStorage = new Map();
39
41
  }
40
42
 
41
- static create(name: string, resources: Resource<any>[]) {
43
+ static async create() {
44
+ const packageJson = readNearestPackageJson();
45
+ if (!packageJson) {
46
+ throw new Error('Failed to read nearest package.json');
47
+ }
48
+
49
+ const { name, version } = packageJson;
50
+
51
+ const resourceLocations = await listAllResources();
52
+ const resources = await Promise.all(resourceLocations.map((l) => {
53
+ return import(l);
54
+ }))
55
+ console.log(resources);
56
+
57
+
42
58
  const controllers = resources
43
59
  .map((resource) => new ResourceController(resource))
44
60
 
@@ -46,7 +62,7 @@ export class Plugin {
46
62
  controllers.map((r) => [r.typeId, r] as const)
47
63
  );
48
64
 
49
- return new Plugin(name, controllersMap);
65
+ return new Plugin(name, version, controllersMap);
50
66
  }
51
67
 
52
68
  async initialize(data: InitializeRequestData): Promise<InitializeResponseData> {
@@ -3,7 +3,7 @@ import { ResourceSettings } from './resource-settings.js';
3
3
  import { ParsedResourceSettings } from './parsed-resource-settings.js';
4
4
  import { TestConfig } from '../utils/test-utils.test.js';
5
5
  import { z } from 'zod';
6
- import { OS, ResourceConfig, ResourceSchema } from 'codify-schemas';
6
+ import { OS } from 'codify-schemas';
7
7
 
8
8
  describe('Resource options parser tests', () => {
9
9
  it('Parses default values from options', () => {
@@ -15,7 +15,6 @@ import {
15
15
  resolveMatcher,
16
16
  resolveParameterTransformFn
17
17
  } from './resource-settings.js';
18
- import { JSONSchema } from '@apidevtools/json-schema-ref-parser';
19
18
 
20
19
  export interface ParsedStatefulParameterSetting extends DefaultParameterSetting {
21
20
  type: 'stateful',
@@ -12,8 +12,8 @@ import {
12
12
  tildify,
13
13
  untildify
14
14
  } from '../utils/functions.js';
15
- import { RefreshContext } from './resource.js';
16
15
  import { ParsedResourceSettings } from './parsed-resource-settings.js';
16
+ import { RefreshContext } from './resource.js';
17
17
 
18
18
  export interface InputTransformation {
19
19
  to: (input: any) => Promise<any> | any;
@@ -356,7 +356,7 @@ export interface StatefulParameterSetting extends DefaultParameterSetting {
356
356
 
357
357
  const ParameterEqualsDefaults: Partial<Record<ParameterSettingType, (a: unknown, b: unknown) => boolean>> = {
358
358
  'boolean': (a: unknown, b: unknown) => Boolean(a) === Boolean(b),
359
- 'directory': (a: unknown, b: unknown) => {
359
+ 'directory'(a: unknown, b: unknown) {
360
360
  let transformedA = resolvePathWithVariables(untildify(String(a)))
361
361
  let transformedB = resolvePathWithVariables(untildify(String(b)))
362
362
 
@@ -437,7 +437,7 @@ export function resolveFnFromEqualsFnOrString(
437
437
  const ParameterTransformationDefaults: Partial<Record<ParameterSettingType, InputTransformation>> = {
438
438
  'directory': {
439
439
  to: (a: unknown) => resolvePathWithVariables((untildify(String(a)))),
440
- from: (a: unknown, original) => {
440
+ from(a: unknown, original) {
441
441
  if (ParameterEqualsDefaults.directory!(a, original)) {
442
442
  return original;
443
443
  }
@@ -0,0 +1,48 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+
4
+ export const listAllResources = async () => {
5
+ const resourceDir = await fs.readdir('./src/resources');
6
+ const dedupSet = new Set();
7
+ const result = new Set<string>();
8
+
9
+ for (const folder of resourceDir) {
10
+ if (await fs.stat(path.join('./src/resources', folder)).then(s => s.isDirectory()).catch(() => false)) {
11
+ for (const folderContents of await fs.readdir(path.join('./src/resources', folder))) {
12
+ const isDirectory = await fs.stat(path.join('./src/resources', folder, folderContents)).then(s => s.isDirectory());
13
+
14
+ // console.log(folderContents, isDirectory);
15
+ if (isDirectory) {
16
+ for (const innerContents of await fs.readdir(path.join('./src/resources', folder, folderContents))) {
17
+ if (!dedupSet.has(path.join('./src/resources', folder, folderContents))) {
18
+ dedupSet.add(path.join('./src/resources', folder, folderContents));
19
+ addResourceFromDir(path.join('./src/resources', folder,folderContents), result);
20
+ }
21
+ }
22
+ } else {
23
+ if (!dedupSet.has(path.join('./src/resources', folder))) {
24
+ dedupSet.add(path.join('./src/resources', folder));
25
+ addResourceFromDir(path.join('./src/resources', folder), result);
26
+ }
27
+ }
28
+ }
29
+ } else {
30
+ throw new Error('Only directories are allowed in resources folder')
31
+ }
32
+ }
33
+
34
+ return [...result];
35
+ }
36
+
37
+
38
+
39
+ function addResourceFromDir(dir: string, result: Set<string>): void {
40
+ try {
41
+ const resourceFile = path.resolve(path.join(dir, 'resource.ts'));
42
+ if (!(fs.stat(resourceFile).then((s) => s.isFile())).catch(() => false)) {
43
+ return;
44
+ }
45
+
46
+ result.add(resourceFile);
47
+ } catch {}
48
+ }
@@ -0,0 +1,40 @@
1
+ import * as fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ /**
5
+ * Find the nearest package.json starting from a directory and walking upward.
6
+ * @param {string} startDir - Directory to start searching from
7
+ * @returns {string|null} Absolute path to package.json or null if not found
8
+ */
9
+ export function findNearestPackageJson(startDir = process.cwd()) {
10
+ let currentDir = path.resolve(startDir);
11
+
12
+ while (true) {
13
+ const pkgPath = path.join(currentDir, "package.json");
14
+
15
+ if (fs.existsSync(pkgPath)) {
16
+ return pkgPath;
17
+ }
18
+
19
+ const parentDir = path.dirname(currentDir);
20
+ if (parentDir === currentDir) {
21
+ // Reached filesystem root
22
+ return null;
23
+ }
24
+
25
+ currentDir = parentDir;
26
+ }
27
+ }
28
+
29
+ /**
30
+ * Read and parse the nearest package.json
31
+ * @param {string} startDir
32
+ * @returns {object|null}
33
+ */
34
+ export function readNearestPackageJson(startDir: string = process.cwd()) {
35
+ const pkgPath = findNearestPackageJson(startDir);
36
+ if (!pkgPath) return null;
37
+
38
+ const contents = fs.readFileSync(pkgPath, 'utf8');
39
+ return JSON.parse(contents);
40
+ }