usePromptProvider()

in packages/angular_devkit/core/src/json/schema/registry.ts [442:579]


  usePromptProvider(provider: PromptProvider) {
    const isSetup = !!this._promptProvider;

    this._promptProvider = provider;

    if (isSetup) {
      return;
    }

    this._ajv.addKeyword({
      keyword: 'x-prompt',
      errors: false,
      valid: true,
      compile: (schema, parentSchema, it) => {
        const compilationSchemInfo = this._currentCompilationSchemaInfo;
        if (!compilationSchemInfo) {
          return () => true;
        }

        const path = '/' + this.normalizeDataPathArr(it).join('/');

        let type: string | undefined;
        let items: Array<string | { label: string; value: string | number | boolean }> | undefined;
        let message: string;
        if (typeof schema == 'string') {
          message = schema;
        } else {
          message = schema.message;
          type = schema.type;
          items = schema.items;
        }

        const propertyTypes = getTypesOfSchema(parentSchema as JsonObject);
        if (!type) {
          if (propertyTypes.size === 1 && propertyTypes.has('boolean')) {
            type = 'confirmation';
          } else if (Array.isArray((parentSchema as JsonObject).enum)) {
            type = 'list';
          } else if (
            propertyTypes.size === 1 &&
            propertyTypes.has('array') &&
            (parentSchema as JsonObject).items &&
            Array.isArray(((parentSchema as JsonObject).items as JsonObject).enum)
          ) {
            type = 'list';
          } else {
            type = 'input';
          }
        }

        let multiselect;
        if (type === 'list') {
          multiselect =
            schema.multiselect === undefined
              ? propertyTypes.size === 1 && propertyTypes.has('array')
              : schema.multiselect;

          const enumValues = multiselect
            ? (parentSchema as JsonObject).items &&
              ((parentSchema as JsonObject).items as JsonObject).enum
            : (parentSchema as JsonObject).enum;
          if (!items && Array.isArray(enumValues)) {
            items = [];
            for (const value of enumValues) {
              if (typeof value == 'string') {
                items.push(value);
              } else if (typeof value == 'object') {
                // Invalid
              } else {
                items.push({ label: value.toString(), value });
              }
            }
          }
        }

        const definition: PromptDefinition = {
          id: path,
          type,
          message,
          raw: schema,
          items,
          multiselect,
          propertyTypes,
          default:
            typeof (parentSchema as JsonObject).default == 'object' &&
            (parentSchema as JsonObject).default !== null &&
            !Array.isArray((parentSchema as JsonObject).default)
              ? undefined
              : ((parentSchema as JsonObject).default as string[]),
          async validator(data: JsonValue) {
            try {
              const result = await it.self.validate(parentSchema, data);
              // If the schema is sync then false will be returned on validation failure
              if (result) {
                return result;
              } else if (it.self.errors?.length) {
                // Validation errors will be present on the Ajv instance when sync
                return it.self.errors[0].message;
              }
            } catch (e) {
              // If the schema is async then an error will be thrown on validation failure
              if (Array.isArray(e.errors) && e.errors.length) {
                return e.errors[0].message;
              }
            }

            return false;
          },
        };

        compilationSchemInfo.promptDefinitions.push(definition);

        return function (this: { promptFieldsWithValue: Set<string> }) {
          // If 'this' is undefined in the call, then it defaults to the global
          // 'this'.
          if (this && this.promptFieldsWithValue) {
            this.promptFieldsWithValue.add(path);
          }

          return true;
        };
      },
      metaSchema: {
        oneOf: [
          { type: 'string' },
          {
            type: 'object',
            properties: {
              'type': { type: 'string' },
              'message': { type: 'string' },
            },
            additionalProperties: true,
            required: ['message'],
          },
        ],
      },
    });
  }