Repository: linkml/linkml

Issue:
LinkML Patterns should generate JSON Schema Patterns
**Describe the bug**

Specifying a [LinkML Pattern](https://linkml.io/linkml-model/docs/pattern/) in a **TypeDefinition**, for example, results in a pattern in a JSON-LD `pattern` attribute. But it doesn't generate a [JSON Schema `pattern`](https://json-schema.org/understanding-json-schema/reference/string.html#regular-expressions).

**To reproduce**
Steps to reproduce the behavior:
1. Create a schema with a pattern in any of the [Applicable Classes](https://linkml.io/linkml-model/docs/pattern/#applicable-classes)
2. Generate JSON-LD
3. Confirm the `pattern` attribute appears
4. Generate JSON Schema
5. Confirm the `pattern` does NOT appear

**Expected behavior**
The resulting JSON Schema has the specified pattern.

**Additional context**
JSON-LD patterns cannot be validated with COTS software. Whereas [JSON Schema `pattern` entries](https://json-schema.org/understanding-json-schema/reference/string.html#regular-expressions) can be validated with any JSON Schema validator.

Comments:

Patch:
diff --git a/linkml/generators/jsonschemagen.py b/linkml/generators/jsonschemagen.py
index 9cf8aabc..f1440339 100644
--- a/linkml/generators/jsonschemagen.py
+++ b/linkml/generators/jsonschemagen.py
@@ -387,6 +387,14 @@ class JsonSchemaGenerator(Generator):
             return JsonSchema()
 
         constraints = JsonSchema()
+        if slot.range in self.schemaview.all_types().keys():
+            # types take lower priority
+            schema_type = self.schemaview.induced_type(slot.range)
+            constraints.add_keyword("pattern", schema_type.pattern)
+            constraints.add_keyword("minimum", schema_type.minimum_value)
+            constraints.add_keyword("maximum", schema_type.maximum_value)
+            constraints.add_keyword("const", schema_type.equals_string)
+            constraints.add_keyword("const", schema_type.equals_number)
         constraints.add_keyword("pattern", slot.pattern)
         constraints.add_keyword("minimum", slot.minimum_value)
         constraints.add_keyword("maximum", slot.maximum_value)
diff --git a/linkml/utils/generator.py b/linkml/utils/generator.py
index c3e8e3d6..62d925bb 100644
--- a/linkml/utils/generator.py
+++ b/linkml/utils/generator.py
@@ -210,7 +210,6 @@ class Generator(metaclass=abc.ABCMeta):
         # See https://github.com/linkml/linkml/issues/923 for discussion on how
         # to simplify the overall framework
         if isinstance(schema, Generator):
-            logging.info("Instantiating generator with another generator is deprecated")
             gen = schema
             self.schema = gen.schema
             self.synopsis = gen.synopsis


Test patch:
diff --git a/tests/test_issues/input/issue_1371/test.schema.yaml b/tests/test_issues/input/issue_1371/test.schema.yaml
new file mode 100644
index 00000000..31df0a13
--- /dev/null
+++ b/tests/test_issues/input/issue_1371/test.schema.yaml
@@ -0,0 +1,26 @@
+# test.schema.yaml
+id: http://example.org/pattern
+name: pattern
+
+imports:
+  - https://w3id.org/linkml/types
+
+slots:
+  us_phone_number:
+    range: string
+    pattern: \d{3} \d{3} \d{4}
+  de_phone_number:
+    range: DePhoneNumber
+
+classes:
+  Test:
+    tree_root: true
+    slots:
+      - us_phone_number
+      - de_phone_number
+
+types:
+  DePhoneNumber:
+    uri: xsd:String
+    base: str
+    pattern: 0\d{3}-\d{8}
diff --git a/tests/test_issues/test_linkml_issue_1371.py b/tests/test_issues/test_linkml_issue_1371.py
new file mode 100644
index 00000000..3a543051
--- /dev/null
+++ b/tests/test_issues/test_linkml_issue_1371.py
@@ -0,0 +1,13 @@
+import json
+from pathlib import Path
+
+from linkml.generators import JsonSchemaGenerator
+
+SCHEMA = str(Path(__file__).parent / "input" / "issue_1371" / "test.schema.yaml")
+
+
+def test_json_schema():
+    jschema = json.loads(JsonSchemaGenerator(SCHEMA).serialize())
+    props = jschema["$defs"]["Test"]["properties"]
+    assert props["de_phone_number"]["pattern"] == r"0\d{3}-\d{8}"
+    assert props["us_phone_number"]["pattern"] == r"\d{3} \d{3} \d{4}"