codify-plugin-lib 1.0.94 → 1.0.95

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.
@@ -34,16 +34,16 @@ export class Plugin {
34
34
  const resource = this.resourceControllers.get(data.type);
35
35
  const schema = resource.settings.schema;
36
36
  const requiredPropertyNames = (resource.settings.import?.requiredParameters
37
- ?? schema.required
37
+ ?? schema?.required
38
38
  ?? null);
39
39
  return {
40
40
  plugin: this.name,
41
41
  type: data.type,
42
42
  dependencies: resource.dependencies,
43
43
  schema: schema,
44
- import: resource.settings.import ? {
44
+ import: {
45
45
  requiredParameters: requiredPropertyNames,
46
- } : undefined,
46
+ },
47
47
  };
48
48
  }
49
49
  async import(data) {
@@ -94,6 +94,27 @@ export class ParsedResourceSettings {
94
94
  && Object.values(this.parameterSettings).some((v) => v.type === 'stateful')) {
95
95
  throw new Error(`Resource: ${this.id}. Stateful parameters are not allowed if multiples of a resource exist`);
96
96
  }
97
+ const schema = this.settings.schema;
98
+ if (!this.settings.import && (schema?.oneOf
99
+ && Array.isArray(schema.oneOf)
100
+ && schema.oneOf.some((s) => s.required))
101
+ || (schema?.anyOf
102
+ && Array.isArray(schema.anyOf)
103
+ && schema.anyOf.some((s) => s.required))
104
+ || (schema?.allOf
105
+ && Array.isArray(schema.allOf)
106
+ && schema.allOf.some((s) => s.required))
107
+ || (schema?.then
108
+ && Array.isArray(schema.then)
109
+ && schema.then.some((s) => s.required))
110
+ || (schema?.else
111
+ && Array.isArray(schema.else)
112
+ && schema.else.some((s) => s.required))) {
113
+ throw new Error(`In the schema of ${this.settings.id}, a conditional required was declared (within anyOf, allOf, oneOf, else, or then) but an` +
114
+ 'import.requiredParameters was not found in the resource settings. This is required because Codify uses the required parameter to' +
115
+ 'determine the prompt to ask users during imports. It can\'t parse which parameters are needed when' +
116
+ 'required is declared conditionally.');
117
+ }
97
118
  }
98
119
  validateParameterEqualsFn(parameter, key) {
99
120
  if (parameter.type === 'stateful') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codify-plugin-lib",
3
- "version": "1.0.94",
3
+ "version": "1.0.95",
4
4
  "description": "Library plugin library",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -101,4 +101,81 @@ describe('Plugin tests', () => {
101
101
  await testPlugin.apply({ plan })
102
102
  expect(resource.modify.calledOnce).to.be.true;
103
103
  });
104
+
105
+ it('Can get resource info', async () => {
106
+ const schema = {
107
+ "$schema": "http://json-schema.org/draft-07/schema",
108
+ "$id": "https://www.codifycli.com/asdf-schema.json",
109
+ "title": "Asdf resource",
110
+ "type": "object",
111
+ "properties": {
112
+ "plugins": {
113
+ "type": "array",
114
+ "description": "Asdf plugins to install. See: https://github.com/asdf-community for a full list",
115
+ "items": {
116
+ "type": "string"
117
+ }
118
+ }
119
+ },
120
+ "required": ["plugins"],
121
+ "additionalProperties": false
122
+ }
123
+
124
+
125
+ const resource = new class extends TestResource {
126
+ getSettings(): ResourceSettings<TestConfig> {
127
+ return {
128
+ id: 'typeId',
129
+ schema,
130
+ }
131
+ }
132
+ }
133
+ const testPlugin = Plugin.create('testPlugin', [resource as any])
134
+
135
+ const resourceInfo = await testPlugin.getResourceInfo({ type: 'typeId' })
136
+ expect(resourceInfo.import).toMatchObject({
137
+ requiredParameters: [
138
+ 'plugins'
139
+ ]
140
+ })
141
+ })
142
+
143
+ it('Get resource info to default import to the one specified in the resource settings', async () => {
144
+ const schema = {
145
+ "$schema": "http://json-schema.org/draft-07/schema",
146
+ "$id": "https://www.codifycli.com/asdf-schema.json",
147
+ "title": "Asdf resource",
148
+ "type": "object",
149
+ "properties": {
150
+ "plugins": {
151
+ "type": "array",
152
+ "description": "Asdf plugins to install. See: https://github.com/asdf-community for a full list",
153
+ "items": {
154
+ "type": "string"
155
+ }
156
+ }
157
+ },
158
+ "required": ["plugins"],
159
+ "additionalProperties": false
160
+ }
161
+
162
+
163
+ const resource = new class extends TestResource {
164
+ getSettings(): ResourceSettings<TestConfig> {
165
+ return {
166
+ id: 'typeId',
167
+ schema,
168
+ import: {
169
+ requiredParameters: []
170
+ }
171
+ }
172
+ }
173
+ }
174
+ const testPlugin = Plugin.create('testPlugin', [resource as any])
175
+
176
+ const resourceInfo = await testPlugin.getResourceInfo({ type: 'typeId' })
177
+ expect(resourceInfo.import).toMatchObject({
178
+ requiredParameters: []
179
+ })
180
+ })
104
181
  });
@@ -59,10 +59,10 @@ export class Plugin {
59
59
 
60
60
  const resource = this.resourceControllers.get(data.type)!;
61
61
 
62
- const schema = resource.settings.schema as JSONSchemaType<any>;
62
+ const schema = resource.settings.schema as JSONSchemaType<any> | undefined;
63
63
  const requiredPropertyNames = (
64
64
  resource.settings.import?.requiredParameters
65
- ?? schema.required
65
+ ?? schema?.required
66
66
  ?? null
67
67
  ) as null | string[];
68
68
 
@@ -71,9 +71,9 @@ export class Plugin {
71
71
  type: data.type,
72
72
  dependencies: resource.dependencies,
73
73
  schema: schema as Record<string, unknown> | undefined,
74
- import: resource.settings.import ? {
74
+ import: {
75
75
  requiredParameters: requiredPropertyNames,
76
- } : undefined,
76
+ },
77
77
  }
78
78
  }
79
79
 
@@ -2,6 +2,7 @@ import { describe, expect, it } from 'vitest';
2
2
  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
+ import { JSONSchemaType } from 'ajv';
5
6
 
6
7
  describe('Resource options parser tests', () => {
7
8
  it('Parses default values from options', () => {
@@ -21,4 +22,48 @@ describe('Resource options parser tests', () => {
21
22
  propB: 'propB'
22
23
  })
23
24
  })
25
+
26
+ it('Throws an error when an import.requiredParameters is not declared', () => {
27
+ const schema = {
28
+ "$schema": "http://json-schema.org/draft-07/schema",
29
+ "$id": "https://www.codifycli.com/git-clone.json",
30
+ "title": "Git-clone resource",
31
+ "type": "object",
32
+ "properties": {
33
+ "remote": {
34
+ "type": "string",
35
+ "description": "Remote tracking url to clone repo from. Equivalent to repository and only one should be specified"
36
+ },
37
+ "repository": {
38
+ "type": "string",
39
+ "description": "Remote repository to clone repo from. Equivalent to remote and only one should be specified"
40
+ },
41
+ "parentDirectory": {
42
+ "type": "string",
43
+ "description": "Parent directory to clone into. The folder name will use default git semantics which extracts the last part of the clone url. Only one of parentDirectory or directory can be specified"
44
+ },
45
+ "directory": {
46
+ "type": "string",
47
+ "description": "Directory to clone contents into. This value is directly passed into git clone. This differs from parent directory in that the last part of the path will be the folder name of the repo"
48
+ },
49
+ "autoVerifySSH": {
50
+ "type": "boolean",
51
+ "description": "Automatically verifies the ssh connection for ssh git clones. Defaults to true."
52
+ }
53
+ },
54
+ "additionalProperties": false,
55
+ "oneOf": [
56
+ { "required": ["repository", "directory"] },
57
+ { "required": ["repository", "parentDirectory"] },
58
+ { "required": ["remote", "directory"] }
59
+ ]
60
+ }
61
+
62
+ const option: ResourceSettings<TestConfig> = {
63
+ id: 'typeId',
64
+ schema,
65
+ }
66
+
67
+ expect(() => new ParsedResourceSettings(option)).throws;
68
+ })
24
69
  })
@@ -2,6 +2,7 @@ import { StringIndexedObject } from 'codify-schemas';
2
2
 
3
3
  import { ParameterSetting, resolveEqualsFn, ResourceSettings, StatefulParameterSetting } from './resource-settings.js';
4
4
  import { StatefulParameter as StatefulParameterImpl } from './stateful-parameter.js'
5
+ import { JSONSchemaType } from 'ajv';
5
6
 
6
7
  export class ParsedResourceSettings<T extends StringIndexedObject> implements ResourceSettings<T> {
7
8
  private cache = new Map<string, unknown>();
@@ -130,6 +131,36 @@ export class ParsedResourceSettings<T extends StringIndexedObject> implements Re
130
131
  && Object.values(this.parameterSettings).some((v) => v.type === 'stateful')) {
131
132
  throw new Error(`Resource: ${this.id}. Stateful parameters are not allowed if multiples of a resource exist`)
132
133
  }
134
+
135
+
136
+ const schema = this.settings.schema as JSONSchemaType<any>;
137
+ if (!this.settings.import && (schema?.oneOf
138
+ && Array.isArray(schema.oneOf)
139
+ && schema.oneOf.some((s) => s.required)
140
+ )
141
+ || (schema?.anyOf
142
+ && Array.isArray(schema.anyOf)
143
+ && schema.anyOf.some((s) => s.required)
144
+ )
145
+ || (schema?.allOf
146
+ && Array.isArray(schema.allOf)
147
+ && schema.allOf.some((s) => s.required)
148
+ )
149
+ || (schema?.then
150
+ && Array.isArray(schema.then)
151
+ && schema.then.some((s) => s.required)
152
+ )
153
+ || (schema?.else
154
+ && Array.isArray(schema.else)
155
+ && schema.else.some((s) => s.required)
156
+ )
157
+ ) {
158
+ throw new Error(`In the schema of ${this.settings.id}, a conditional required was declared (within anyOf, allOf, oneOf, else, or then) but an` +
159
+ 'import.requiredParameters was not found in the resource settings. This is required because Codify uses the required parameter to' +
160
+ 'determine the prompt to ask users during imports. It can\'t parse which parameters are needed when' +
161
+ 'required is declared conditionally.'
162
+ )
163
+ }
133
164
  }
134
165
 
135
166
  private validateParameterEqualsFn(parameter: ParameterSetting, key: string): void {