@seamapi/nextlove-sdk-generator 1.5.3 → 1.5.4

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.
Files changed (68) hide show
  1. package/lib/endpoints-returning-deprecated-action-attempt.d.ts +2 -0
  2. package/lib/endpoints-returning-deprecated-action-attempt.js +10 -0
  3. package/lib/endpoints-returning-deprecated-action-attempt.js.map +1 -0
  4. package/lib/generate-php-sdk/generate-php-sdk.js +4 -18
  5. package/lib/generate-php-sdk/generate-php-sdk.js.map +1 -1
  6. package/lib/generate-php-sdk/utils/php-client.d.ts +3 -3
  7. package/lib/generate-php-sdk/utils/php-client.js.map +1 -1
  8. package/lib/generate-python-sdk/class-file.d.ts +15 -2
  9. package/lib/generate-python-sdk/class-file.js +140 -21
  10. package/lib/generate-python-sdk/class-file.js.map +1 -1
  11. package/lib/generate-python-sdk/generate-python-sdk.js +65 -17
  12. package/lib/generate-python-sdk/generate-python-sdk.js.map +1 -1
  13. package/lib/generate-python-sdk/map-python-type.d.ts +1 -1
  14. package/lib/generate-python-sdk/map-python-type.js +6 -2
  15. package/lib/generate-python-sdk/map-python-type.js.map +1 -1
  16. package/lib/generate-python-sdk/templates/.gitignore.template.d.ts +2 -0
  17. package/lib/generate-python-sdk/templates/.gitignore.template.js +12 -0
  18. package/lib/generate-python-sdk/templates/.gitignore.template.js.map +1 -0
  19. package/lib/generate-python-sdk/templates/__init__.py.template.d.ts +2 -0
  20. package/lib/generate-python-sdk/templates/__init__.py.template.js +7 -0
  21. package/lib/generate-python-sdk/templates/__init__.py.template.js.map +1 -0
  22. package/lib/generate-python-sdk/templates/conftest.py.template.js +75 -6
  23. package/lib/generate-python-sdk/templates/conftest.py.template.js.map +1 -1
  24. package/lib/generate-python-sdk/templates/prebuild.py.template.d.ts +2 -0
  25. package/lib/generate-python-sdk/templates/prebuild.py.template.js +13 -0
  26. package/lib/generate-python-sdk/templates/prebuild.py.template.js.map +1 -0
  27. package/lib/generate-python-sdk/templates/pyproject.toml.template.js +6 -2
  28. package/lib/generate-python-sdk/templates/pyproject.toml.template.js.map +1 -1
  29. package/lib/generate-python-sdk/templates/seam.py.template.js +90 -14
  30. package/lib/generate-python-sdk/templates/seam.py.template.js.map +1 -1
  31. package/lib/generate-python-sdk/templates/snippets/abstract-seam.template.js +12 -5
  32. package/lib/generate-python-sdk/templates/snippets/abstract-seam.template.js.map +1 -1
  33. package/lib/generate-python-sdk/templates/snippets/resource-dataclass.template.js +6 -1
  34. package/lib/generate-python-sdk/templates/snippets/resource-dataclass.template.js.map +1 -1
  35. package/lib/generate-python-sdk/templates/snippets/seam-api-exception-class.template.d.ts +2 -0
  36. package/lib/generate-python-sdk/templates/snippets/seam-api-exception-class.template.js +17 -0
  37. package/lib/generate-python-sdk/templates/snippets/seam-api-exception-class.template.js.map +1 -0
  38. package/lib/generate-python-sdk/templates/utils/get_sentry_dsn.py.template.d.ts +2 -0
  39. package/lib/generate-python-sdk/templates/utils/get_sentry_dsn.py.template.js +6 -0
  40. package/lib/generate-python-sdk/templates/utils/get_sentry_dsn.py.template.js.map +1 -0
  41. package/lib/generate-python-sdk/templates/utils/report_error.py.template.d.ts +2 -0
  42. package/lib/generate-python-sdk/templates/utils/report_error.py.template.js +17 -0
  43. package/lib/generate-python-sdk/templates/utils/report_error.py.template.js.map +1 -0
  44. package/lib/openapi/get-parameter-and-response-schema.js +9 -9
  45. package/lib/openapi/get-parameter-and-response-schema.js.map +1 -1
  46. package/lib/openapi/map-parent-to-children-resource.d.ts +3 -0
  47. package/lib/openapi/map-parent-to-children-resource.js +17 -0
  48. package/lib/openapi/map-parent-to-children-resource.js.map +1 -0
  49. package/package.json +1 -1
  50. package/src/lib/endpoints-returning-deprecated-action-attempt.ts +10 -0
  51. package/src/lib/generate-php-sdk/generate-php-sdk.ts +6 -30
  52. package/src/lib/generate-php-sdk/utils/php-client.ts +2 -2
  53. package/src/lib/generate-python-sdk/class-file.ts +232 -49
  54. package/src/lib/generate-python-sdk/generate-python-sdk.ts +96 -23
  55. package/src/lib/generate-python-sdk/map-python-type.ts +9 -3
  56. package/src/lib/generate-python-sdk/templates/.gitignore.template.ts +11 -0
  57. package/src/lib/generate-python-sdk/templates/__init__.py.template.ts +6 -0
  58. package/src/lib/generate-python-sdk/templates/conftest.py.template.ts +75 -6
  59. package/src/lib/generate-python-sdk/templates/prebuild.py.template.ts +12 -0
  60. package/src/lib/generate-python-sdk/templates/pyproject.toml.template.ts +6 -2
  61. package/src/lib/generate-python-sdk/templates/seam.py.template.ts +90 -14
  62. package/src/lib/generate-python-sdk/templates/snippets/abstract-seam.template.ts +12 -5
  63. package/src/lib/generate-python-sdk/templates/snippets/resource-dataclass.template.ts +9 -1
  64. package/src/lib/generate-python-sdk/templates/snippets/seam-api-exception-class.template.ts +16 -0
  65. package/src/lib/generate-python-sdk/templates/utils/get_sentry_dsn.py.template.ts +5 -0
  66. package/src/lib/generate-python-sdk/templates/utils/report_error.py.template.ts +16 -0
  67. package/src/lib/openapi/get-parameter-and-response-schema.ts +8 -11
  68. package/src/lib/openapi/map-parent-to-children-resource.ts +28 -0
@@ -0,0 +1,12 @@
1
+ export default () => `dist
2
+ seamapi/utils/get_sentry_dsn.py
3
+ .env
4
+ __pycache__
5
+ */__pycache__
6
+ node_modules
7
+
8
+ .deeper
9
+ .yalc
10
+ yalc.lock
11
+ `;
12
+ //# sourceMappingURL=.gitignore.template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":".gitignore.template.js","sourceRoot":"","sources":["../../../src/lib/generate-python-sdk/templates/.gitignore.template.ts"],"names":[],"mappings":"AAAA,eAAe,GAAG,EAAE,CAAC;;;;;;;;;;CAUpB,CAAA"}
@@ -0,0 +1,2 @@
1
+ declare const _default: () => string;
2
+ export default _default;
@@ -0,0 +1,7 @@
1
+ export default () => `# flake8: noqa
2
+ # type: ignore
3
+
4
+ from seamapi.seam import Seam
5
+ from seamapi.seam import SeamApiException
6
+ `;
7
+ //# sourceMappingURL=__init__.py.template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"__init__.py.template.js","sourceRoot":"","sources":["../../../src/lib/generate-python-sdk/templates/__init__.py.template.ts"],"names":[],"mappings":"AAAA,eAAe,GAAG,EAAE,CAAC;;;;;CAKpB,CAAA"}
@@ -1,12 +1,81 @@
1
- export default () => `import pytest
2
- import random
1
+ export default () => `import random
3
2
  import string
3
+ import pytest
4
4
  from seamapi import Seam
5
+ from dotenv import load_dotenv
6
+ from typing import Any
7
+ from dataclasses import dataclass
5
8
 
6
9
 
10
+ @pytest.fixture(autouse=True)
11
+ def dotenv_fixture():
12
+ load_dotenv()
13
+
14
+
15
+ @dataclass
16
+ class SeamBackend:
17
+ url: str
18
+ sandbox_api_key: str
19
+
20
+
21
+ # TODO this should use scope="session", but there's some issue, this would
22
+ # dramatically reduce test time to switch
7
23
  @pytest.fixture(scope="function")
8
- def seam():
9
- r = ''.join(random.choices(string.ascii_uppercase + string.digits, k=10))
10
- seam = Seam(api_url=f"https://{r}.fakeseamconnect.seam.vc", api_key="seam_apikey1_token")
11
- yield seam`;
24
+ def seam_backend():
25
+ random_string = ''.join(random.choices(string.ascii_uppercase + string.digits, k=10))
26
+ yield SeamBackend(
27
+ url=f"https://{random_string}.fakeseamconnect.seam.vc",
28
+ sandbox_api_key="seam_apikey1_token",
29
+ )
30
+
31
+
32
+ @pytest.fixture
33
+ def seam(seam_backend: Any):
34
+ seam = Seam(api_url=seam_backend.url, api_key=seam_backend.sandbox_api_key)
35
+ # seam.make_request("POST", "/workspaces/reset_sandbox")
36
+ yield seam
37
+
38
+
39
+ @pytest.fixture
40
+ def fake_sentry(monkeypatch):
41
+ sentry_dsn = "https://key@sentry.io/123"
42
+
43
+ monkeypatch.setenv("SENTRY_DSN", sentry_dsn)
44
+
45
+ sentry_init_args = {}
46
+ sentry_capture_exception_calls = []
47
+ sentry_add_breadcrumb_calls = []
48
+
49
+ class TestSentryClient(object):
50
+ def __init__(self, *args, **kwargs):
51
+ sentry_init_args.update(kwargs)
52
+
53
+ def set_context(self, *args, **kwargs):
54
+ pass
55
+
56
+ monkeypatch.setattr("sentry_sdk.Client", TestSentryClient)
57
+
58
+ class TestSentryScope(object):
59
+ def set_context(self, *args, **kwargs):
60
+ pass
61
+
62
+ class TestSentryHub(object):
63
+ def __init__(self, *args, **kwargs):
64
+ self.scope = TestSentryScope()
65
+
66
+ def capture_exception(self, *args, **kwargs):
67
+ sentry_capture_exception_calls.append((args, kwargs))
68
+
69
+ def add_breadcrumb(self, *args, **kwargs):
70
+ sentry_add_breadcrumb_calls.append((args, kwargs))
71
+
72
+ monkeypatch.setattr("sentry_sdk.Hub", TestSentryHub)
73
+
74
+ yield {
75
+ "sentry_init_args": sentry_init_args,
76
+ "sentry_capture_exception_calls": sentry_capture_exception_calls,
77
+ "sentry_add_breadcrumb_calls": sentry_add_breadcrumb_calls,
78
+ "sentry_dsn": sentry_dsn,
79
+ }
80
+ `;
12
81
  //# sourceMappingURL=conftest.py.template.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"conftest.py.template.js","sourceRoot":"","sources":["../../../src/lib/generate-python-sdk/templates/conftest.py.template.ts"],"names":[],"mappings":"AAAA,eAAe,GAAG,EAAE,CAAC;;;;;;;;;;eAUN,CAAA"}
1
+ {"version":3,"file":"conftest.py.template.js","sourceRoot":"","sources":["../../../src/lib/generate-python-sdk/templates/conftest.py.template.ts"],"names":[],"mappings":"AAAA,eAAe,GAAG,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+EpB,CAAA"}
@@ -0,0 +1,2 @@
1
+ declare const _default: () => string;
2
+ export default _default;
@@ -0,0 +1,13 @@
1
+ export default () => `import os
2
+
3
+ value = os.environ.get("SENTRY_DSN", "None")
4
+ if value != "None":
5
+ value = f'"{value}"'
6
+
7
+ f = open("seamapi/utils/get_sentry_dsn.py", "w")
8
+ f.write(f"""
9
+ def get_sentry_dsn():
10
+ return {value}
11
+ """)
12
+ `;
13
+ //# sourceMappingURL=prebuild.py.template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prebuild.py.template.js","sourceRoot":"","sources":["../../../src/lib/generate-python-sdk/templates/prebuild.py.template.ts"],"names":[],"mappings":"AAAA,eAAe,GAAG,EAAE,CAAC;;;;;;;;;;;CAWpB,CAAA"}
@@ -1,6 +1,6 @@
1
1
  export default () => `[tool.poetry]
2
2
  name = "seamapi"
3
- version = "2.14.0"
3
+ version = "2.18.0"
4
4
  description = "A Python Library for Seam's API https://getseam.com"
5
5
  authors = ["Severin Ibarluzea <seveibar@gmail.com>"]
6
6
  license = "MIT"
@@ -8,14 +8,18 @@ license = "MIT"
8
8
  [tool.poetry.dependencies]
9
9
  python = "^3.7"
10
10
  requests = "^2.26.0"
11
+ dataclasses-json = "^0.5.6"
12
+ sentry-sdk = "^1.9.10"
11
13
 
12
14
  [tool.poetry.dev-dependencies]
13
15
  pytest = "^6.2.5"
14
16
  python-dotenv = "^0.19.2"
15
17
  black = "^21.12b0"
18
+ testcontainers = {extras = ["postgresql"], version = "^3.4.2"}
16
19
  responses = "^0.22.0"
17
20
 
18
21
  [build-system]
19
22
  requires = ["poetry-core>=1.0.0"]
20
- build-backend = "poetry.core.masonry.api"`;
23
+ build-backend = "poetry.core.masonry.api"
24
+ `;
21
25
  //# sourceMappingURL=pyproject.toml.template.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pyproject.toml.template.js","sourceRoot":"","sources":["../../../src/lib/generate-python-sdk/templates/pyproject.toml.template.ts"],"names":[],"mappings":"AAAA,eAAe,GAAG,EAAE,CAAC;;;;;;;;;;;;;;;;;;;0CAmBqB,CAAA"}
1
+ {"version":3,"file":"pyproject.toml.template.js","sourceRoot":"","sources":["../../../src/lib/generate-python-sdk/templates/pyproject.toml.template.ts"],"names":[],"mappings":"AAAA,eAAe,GAAG,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;CAuBpB,CAAA"}
@@ -1,19 +1,51 @@
1
1
  export default () => `import os
2
2
 
3
+ from seamapi.utils.get_sentry_dsn import get_sentry_dsn
3
4
  from .routes import Routes
4
5
  import requests
5
- from importlib.metadata import version
6
+ import sentry_sdk
7
+ import pkg_resources
6
8
  from typing import Optional, cast
7
- from .types import AbstractSeam, SeamAPIException
9
+ from .types import AbstractSeam, SeamApiException
8
10
 
9
11
 
10
12
  class Seam(AbstractSeam):
13
+ """
14
+ Initial Seam class used to interact with Seam API
15
+
16
+ ...
17
+
18
+ Attributes
19
+ ----------
20
+ api_key : str
21
+ API key (default None)
22
+ api_url : str
23
+ API url (default None)
24
+ workspaces : Workspaces
25
+ Workspaces class
26
+ connected_accounts : ConnectedAccounts
27
+ Connected accounts class
28
+ connect_webviews : ConnectWebviews
29
+ Connect webviews class
30
+ devices : Devices
31
+ Devices class
32
+ events : Events
33
+ Events class
34
+ locks : Locks
35
+ Locks class
36
+ access_codes : AccessCodes
37
+ Access codes class
38
+ action_attempts : ActionAttempts
39
+ Action attempts class
40
+ """
41
+
11
42
  api_key: str
12
43
  api_url: str = "https://connect.getseam.com"
13
44
 
14
45
  def __init__(
15
46
  self,
16
47
  api_key: Optional[str] = None,
48
+ workspace_id: Optional[str] = None,
17
49
  api_url: Optional[str] = None,
18
50
  should_report_exceptions: Optional[bool] = False,
19
51
  ):
@@ -22,8 +54,12 @@ class Seam(AbstractSeam):
22
54
  ----------
23
55
  api_key : str, optional
24
56
  API key
57
+ workspace_id : str, optional
58
+ Workspace id
25
59
  api_url : str, optional
26
60
  API url
61
+ should_report_exceptions : bool, optional
62
+ Defaults to False. If true, thrown exceptions will be reported to Seam.
27
63
  """
28
64
  Routes.__init__(self)
29
65
 
@@ -33,10 +69,34 @@ class Seam(AbstractSeam):
33
69
  raise Exception(
34
70
  "SEAM_API_KEY not found in environment, and api_key not provided"
35
71
  )
36
- if api_url is None:
37
- api_url = os.environ.get("SEAM_API_URL", self.api_url)
72
+ if workspace_id is None:
73
+ workspace_id = os.environ.get("SEAM_WORKSPACE_ID", None)
38
74
  self.api_key = api_key
39
- self.api_url = cast(str, api_url)
75
+ self.workspace_id = workspace_id
76
+
77
+ if os.environ.get("SEAM_API_URL", None) is not None:
78
+ print(
79
+ '\\n'
80
+ '\\033[93m'
81
+ 'Using the SEAM_API_URL environment variable is deprecated. '
82
+ 'Support will be removed in a later major version. Use SEAM_ENDPOINT instead.'
83
+ '\\033[0m'
84
+ )
85
+ api_url = os.environ.get("SEAM_API_URL", None) or os.environ.get("SEAM_ENDPOINT", None) or api_url
86
+ if api_url is not None:
87
+ self.api_url = cast(str, api_url)
88
+
89
+ self.should_report_exceptions = should_report_exceptions
90
+
91
+ if self.should_report_exceptions:
92
+ self.sentry_client = sentry_sdk.Hub(sentry_sdk.Client(
93
+ dsn=get_sentry_dsn(),
94
+ ))
95
+ self.sentry_client.scope.set_context("sdk_info", {
96
+ "repository": "https://github.com/seamapi/python",
97
+ "version": pkg_resources.get_distribution("seamapi").version,
98
+ "endpoint": self.api_url,
99
+ })
40
100
 
41
101
  def make_request(self, method: str, path: str, **kwargs):
42
102
  """
@@ -53,22 +113,38 @@ class Seam(AbstractSeam):
53
113
  """
54
114
 
55
115
  url = self.api_url + path
116
+ sdk_version = pkg_resources.get_distribution("seamapi").version
56
117
  headers = {
57
118
  "Authorization": "Bearer " + self.api_key,
58
119
  "Content-Type": "application/json",
59
- "User-Agent": "Python SDK v" + version("seamapi") + " (https://github.com/seamapi/python)",
120
+ "User-Agent": "Python SDK v" + sdk_version + " (https://github.com/seamapi/python)",
121
+ "seam-sdk-name": "seamapi/python",
122
+ "seam-sdk-version": sdk_version,
60
123
  }
124
+ if self.workspace_id is not None:
125
+ headers["seam-workspace"] = self.workspace_id
61
126
  response = requests.request(method, url, headers=headers, **kwargs)
62
127
 
63
- parsed_response = response.json()
128
+ if self.should_report_exceptions and response.status_code:
129
+ # Add breadcrumb
130
+ self.sentry_client.add_breadcrumb(
131
+ category="http",
132
+ level="info",
133
+ data={
134
+ "method": method,
135
+ "url": url,
136
+ "status_code": response.status_code,
137
+ "request_id": response.headers.get("seam-request-id", "unknown"),
138
+ },
139
+ )
140
+
64
141
 
65
142
  if response.status_code != 200:
66
- raise SeamAPIException(
67
- response.status_code,
68
- response.headers.get("seam-request-id", None),
69
- parsed_response["error"],
70
- )
71
- ## TODO automatically paginate if kwargs["auto_paginate"] is True
143
+ raise SeamApiException(response)
144
+
145
+ if "application/json" in response.headers["content-type"]:
146
+ return response.json()
72
147
 
73
- return parsed_response`;
148
+ return response.text
149
+ `;
74
150
  //# sourceMappingURL=seam.py.template.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"seam.py.template.js","sourceRoot":"","sources":["../../../src/lib/generate-python-sdk/templates/seam.py.template.ts"],"names":[],"mappings":"AAAA,eAAe,GAAG,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+BAwEU,CAAA"}
1
+ {"version":3,"file":"seam.py.template.js","sourceRoot":"","sources":["../../../src/lib/generate-python-sdk/templates/seam.py.template.ts"],"names":[],"mappings":"AAAA,eAAe,GAAG,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoJpB,CAAA"}
@@ -1,9 +1,16 @@
1
1
  export default () => `@dataclass
2
2
  class AbstractSeam(AbstractRoutes):
3
- api_key: str
4
- api_url: str
3
+ api_key: str
4
+ workspace_id: str
5
+ api_url: str
5
6
 
6
- @abc.abstractmethod
7
- def __init__(self, api_key: Optional[str] = None):
8
- raise NotImplementedError`;
7
+ @abc.abstractmethod
8
+ def __init__(
9
+ self,
10
+ api_key: Optional[str] = None,
11
+ workspace_id: Optional[str] = None,
12
+ api_url: Optional[str] = None,
13
+ should_report_exceptions: Optional[bool] = False,
14
+ ):
15
+ raise NotImplementedError`;
9
16
  //# sourceMappingURL=abstract-seam.template.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"abstract-seam.template.js","sourceRoot":"","sources":["../../../../src/lib/generate-python-sdk/templates/snippets/abstract-seam.template.ts"],"names":[],"mappings":"AAAA,eAAe,GAAG,EAAE,CAAC;;;;;;;8BAOS,CAAA"}
1
+ {"version":3,"file":"abstract-seam.template.js","sourceRoot":"","sources":["../../../../src/lib/generate-python-sdk/templates/snippets/abstract-seam.template.ts"],"names":[],"mappings":"AAAA,eAAe,GAAG,EAAE,CAAC;;;;;;;;;;;;;;kCAca,CAAA"}
@@ -5,6 +5,11 @@ ${parameters.map((p) => ` ${p.name}: ${p.type}`).join("\n")}
5
5
  @staticmethod
6
6
  def from_dict(d: Dict[str, Any]):
7
7
  return ${name}(
8
- ${parameters.map((p) => ` ${p.name}=d.get("${p.name}", None),`).join("\n")}
8
+ ${parameters
9
+ .map((p) => {
10
+ const is_dict_param = p.type.startsWith("Dict") || p.name === "properties";
11
+ return ` ${p.name}=${is_dict_param ? "DeepAttrDict(" : ""}d.get("${p.name}", None)${is_dict_param ? ")" : ""},`;
12
+ })
13
+ .join("\n")}
9
14
  )`;
10
15
  //# sourceMappingURL=resource-dataclass.template.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"resource-dataclass.template.js","sourceRoot":"","sources":["../../../../src/lib/generate-python-sdk/templates/snippets/resource-dataclass.template.ts"],"names":[],"mappings":"AAAA,eAAe,CACb,IAAY,EACZ,UAGE,EACF,EAAE,CAAC;QACG,IAAI;EACV,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;;;aAI/C,IAAI;EACf,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACvE,CAAA"}
1
+ {"version":3,"file":"resource-dataclass.template.js","sourceRoot":"","sources":["../../../../src/lib/generate-python-sdk/templates/snippets/resource-dataclass.template.ts"],"names":[],"mappings":"AAAA,eAAe,CACb,IAAY,EACZ,UAGE,EACF,EAAE,CAAC;QACG,IAAI;EACV,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;;;aAI/C,IAAI;EACf,UAAU;KACT,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;IACT,MAAM,aAAa,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY,CAAA;IAE1E,OAAO,SAAS,CAAC,CAAC,IAAI,IAAI,aAAa,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,UAC5D,CAAC,CAAC,IACJ,WAAW,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAA;AACxC,CAAC,CAAC;KACD,IAAI,CAAC,IAAI,CAAC;QACL,CAAA"}
@@ -0,0 +1,2 @@
1
+ declare const _default: () => string;
2
+ export default _default;
@@ -0,0 +1,17 @@
1
+ export default () => `class SeamApiException(Exception):
2
+ def __init__(
3
+ self,
4
+ response,
5
+ ):
6
+ self.status_code = response.status_code
7
+ self.request_id = response.headers.get("seam-request-id", None)
8
+
9
+ self.metadata = None
10
+ if "application/json" in response.headers["content-type"]:
11
+ parsed_response = response.json()
12
+ self.metadata = parsed_response.get("error", None)
13
+
14
+ super().__init__(
15
+ f"SeamApiException: status={self.status_code}, request_id={self.request_id}, metadata={self.metadata}"
16
+ )`;
17
+ //# sourceMappingURL=seam-api-exception-class.template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seam-api-exception-class.template.js","sourceRoot":"","sources":["../../../../src/lib/generate-python-sdk/templates/snippets/seam-api-exception-class.template.ts"],"names":[],"mappings":"AAAA,eAAe,GAAG,EAAE,CAAC;;;;;;;;;;;;;;;QAeb,CAAA"}
@@ -0,0 +1,2 @@
1
+ declare const _default: () => string;
2
+ export default _default;
@@ -0,0 +1,6 @@
1
+ export default () => `import os
2
+
3
+ def get_sentry_dsn():
4
+ # This is replaced with a hard-coded value during the build process (see scripts/prebuild.py)
5
+ return os.environ.get("SENTRY_DSN", None)`;
6
+ //# sourceMappingURL=get_sentry_dsn.py.template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get_sentry_dsn.py.template.js","sourceRoot":"","sources":["../../../../src/lib/generate-python-sdk/templates/utils/get_sentry_dsn.py.template.ts"],"names":[],"mappings":"AAAA,eAAe,GAAG,EAAE,CAAC;;;;4CAIuB,CAAA"}
@@ -0,0 +1,2 @@
1
+ declare const _default: () => string;
2
+ export default _default;
@@ -0,0 +1,17 @@
1
+ export default () => `from seamapi.types import SeamApiException
2
+
3
+ """
4
+ A decorator for model methods that will report errors to Sentry (if enabled).
5
+ Expects that the model has a \`seam\` attribute that is a \`Seam\` instance.
6
+ """
7
+ def report_error(f):
8
+ def wrapper(self, *args, **kwargs):
9
+ try:
10
+ return f(self, *args, **kwargs)
11
+ except Exception as error:
12
+ if self.seam.should_report_exceptions and type(error) is not SeamApiException:
13
+ self.seam.sentry_client.capture_exception(error)
14
+
15
+ raise error
16
+ return wrapper`;
17
+ //# sourceMappingURL=report_error.py.template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report_error.py.template.js","sourceRoot":"","sources":["../../../../src/lib/generate-python-sdk/templates/utils/report_error.py.template.ts"],"names":[],"mappings":"AAAA,eAAe,GAAG,EAAE,CAAC;;;;;;;;;;;;;;;iBAeJ,CAAA"}
@@ -29,14 +29,14 @@ export const getParameterAndResponseSchema = (route) => {
29
29
  nullable,
30
30
  };
31
31
  }
32
- const response_obj_type = response_obj_ref?.split("/")?.pop();
33
- const response_arr_type = response_arr_ref?.split("/")?.pop();
34
- return {
35
- response_obj_type,
36
- response_arr_type,
37
- parameter_schema,
38
- res_return_schema: res_return_schema,
39
- nullable,
40
- };
32
+ else {
33
+ return {
34
+ response_obj_type: response_obj_ref?.split("/")?.pop(),
35
+ response_arr_type: response_arr_ref?.split("/")?.pop(),
36
+ parameter_schema,
37
+ res_return_schema: res_return_schema,
38
+ nullable,
39
+ };
40
+ }
41
41
  };
42
42
  //# sourceMappingURL=get-parameter-and-response-schema.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-parameter-and-response-schema.js","sourceRoot":"","sources":["../../src/lib/openapi/get-parameter-and-response-schema.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAE1D,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,KAAY,EAAE,EAAE;IAC5D,MAAM,eAAe,GACnB,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAEpE,MAAM,QAAQ,GAAG,CAAC,CAChB,eAAe;QACf,UAAU,IAAI,eAAe;QAC7B,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAC1E,CAAA;IAED,IAAI,CAAC,eAAe,EAAE;QACpB,OAAO,EAAE,QAAQ,EAAE,CAAA;KACpB;IAED,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE;QAC3B,KAAK,CAAC,IAAI,CAAC,WAAW,GAAG;YACvB,OAAO,EAAE;gBACP,kBAAkB,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE;aACnE;SACK,CAAA;KACT;IAED,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,kBAAkB,CAAC,EAAE;QACzD,OAAO,EAAE,QAAQ,EAAE,CAAA;KACpB;IAED,MAAM,gBAAgB,GAAG,gBAAgB,CACvC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAC1D,CAAA;IACD,MAAM,iBAAiB,GAAI,eAAuB,CAAC,UAAU,CAC3D,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CACtC,CAAA;IAED,MAAM,gBAAgB,GAAG,iBAAiB,EAAE,IAAI,CAAA;IAChD,MAAM,gBAAgB,GAAG,iBAAiB,EAAE,KAAK,EAAE,IAAI,CAAA;IAEvD,IAAI,CAAC,gBAAgB,IAAI,CAAC,gBAAgB,EAAE;QAC1C,OAAO;YACL,iBAAiB,EAAE,SAAS;YAC5B,iBAAiB,EAAE,SAAS;YAC5B,gBAAgB;YAChB,QAAQ;SACT,CAAA;KACF;IAED,MAAM,iBAAiB,GAAG,gBAAgB,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,EAAG,CAAA;IAC9D,MAAM,iBAAiB,GAAG,gBAAgB,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,EAAG,CAAA;IAE9D,OAAO;QACL,iBAAiB;QACjB,iBAAiB;QACjB,gBAAgB;QAChB,iBAAiB,EAAE,iBAA0C;QAC7D,QAAQ;KACT,CAAA;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"get-parameter-and-response-schema.js","sourceRoot":"","sources":["../../src/lib/openapi/get-parameter-and-response-schema.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAE1D,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,KAAY,EAAE,EAAE;IAC5D,MAAM,eAAe,GACnB,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAEpE,MAAM,QAAQ,GAAG,CAAC,CAChB,eAAe;QACf,UAAU,IAAI,eAAe;QAC7B,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAC1E,CAAA;IAED,IAAI,CAAC,eAAe,EAAE;QACpB,OAAO,EAAE,QAAQ,EAAE,CAAA;KACpB;IAED,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE;QAC3B,KAAK,CAAC,IAAI,CAAC,WAAW,GAAG;YACvB,OAAO,EAAE;gBACP,kBAAkB,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE;aACnE;SACK,CAAA;KACT;IAED,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,kBAAkB,CAAC,EAAE;QACzD,OAAO,EAAE,QAAQ,EAAE,CAAA;KACpB;IAED,MAAM,gBAAgB,GAAG,gBAAgB,CACvC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAC1D,CAAA;IACD,MAAM,iBAAiB,GAAI,eAAuB,CAAC,UAAU,CAC3D,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CACtC,CAAA;IAED,MAAM,gBAAgB,GAAG,iBAAiB,EAAE,IAAI,CAAA;IAChD,MAAM,gBAAgB,GAAG,iBAAiB,EAAE,KAAK,EAAE,IAAI,CAAA;IAEvD,IAAI,CAAC,gBAAgB,IAAI,CAAC,gBAAgB,EAAE;QAC1C,OAAO;YACL,iBAAiB,EAAE,SAAS;YAC5B,iBAAiB,EAAE,SAAS;YAC5B,gBAAgB;YAChB,QAAQ;SACT,CAAA;KACF;SAAM;QACL,OAAO;YACL,iBAAiB,EAAE,gBAAgB,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE;YACtD,iBAAiB,EAAE,gBAAgB,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE;YACtD,gBAAgB;YAChB,iBAAiB,EAAE,iBAA0C;YAC7D,QAAQ;SACT,CAAA;KACF;AACH,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { Route } from "../../lib/types.js";
2
+ declare const mapParentToChildrenResources: (routes: Route[]) => Record<string, string[]>;
3
+ export default mapParentToChildrenResources;
@@ -0,0 +1,17 @@
1
+ const mapParentToChildrenResources = (routes) => routes.reduce((acc, route) => {
2
+ if (!route.post?.["x-fern-sdk-group-name"])
3
+ return acc;
4
+ const [parent_resource_name, child_resource_name] = route.post["x-fern-sdk-group-name"];
5
+ if (!parent_resource_name)
6
+ return acc;
7
+ if (!acc[parent_resource_name]) {
8
+ acc[parent_resource_name] = [];
9
+ }
10
+ if (child_resource_name &&
11
+ !acc[parent_resource_name].includes(child_resource_name)) {
12
+ acc[parent_resource_name].push(child_resource_name);
13
+ }
14
+ return acc;
15
+ }, {});
16
+ export default mapParentToChildrenResources;
17
+ //# sourceMappingURL=map-parent-to-children-resource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map-parent-to-children-resource.js","sourceRoot":"","sources":["../../src/lib/openapi/map-parent-to-children-resource.ts"],"names":[],"mappings":"AAEA,MAAM,4BAA4B,GAAG,CACnC,MAAe,EACW,EAAE,CAC5B,MAAM,CAAC,MAAM,CAAC,CAAC,GAA6B,EAAE,KAAK,EAAE,EAAE;IACrD,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,uBAAuB,CAAC;QAAE,OAAO,GAAG,CAAA;IAEtD,MAAM,CAAC,oBAAoB,EAAE,mBAAmB,CAAC,GAC/C,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAA;IAErC,IAAI,CAAC,oBAAoB;QAAE,OAAO,GAAG,CAAA;IAErC,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE;QAC9B,GAAG,CAAC,oBAAoB,CAAC,GAAG,EAAE,CAAA;KAC/B;IAED,IACE,mBAAmB;QACnB,CAAC,GAAG,CAAC,oBAAoB,CAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EACzD;QACA,GAAG,CAAC,oBAAoB,CAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAA;KACrD;IAED,OAAO,GAAG,CAAA;AACZ,CAAC,EAAE,EAAE,CAAC,CAAA;AAER,eAAe,4BAA4B,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seamapi/nextlove-sdk-generator",
3
- "version": "1.5.3",
3
+ "version": "1.5.4",
4
4
  "description": "Utilities for building NextLove SDK Generators",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -0,0 +1,10 @@
1
+ export const endpoints_returning_deprecated_action_attempt = [
2
+ "/access_codes/delete",
3
+ "/access_codes/unmanaged/delete",
4
+ "/access_codes/update",
5
+ "/noise_sensors/noise_thresholds/delete",
6
+ "/noise_sensors/noise_thresholds/update",
7
+ "/thermostats/climate_setting_schedules/update",
8
+ ]
9
+
10
+ export default endpoints_returning_deprecated_action_attempt
@@ -4,7 +4,7 @@ import { getParameterAndResponseSchema } from "lib/index.js"
4
4
  import { generateResourceObjectClass } from "./utils/generate-resource-object-class.js"
5
5
  import { pascalCase } from "change-case"
6
6
  import { getPhpType } from "./utils/get-php-type.js"
7
- import { PhpClient, type PhpClientIdentifiers } from "./utils/php-client.js"
7
+ import { PhpClient, type PhpClientIdentifier } from "./utils/php-client.js"
8
8
  import { generateSeamClient } from "./utils/generate-seam-client.js"
9
9
  import { deepExtractResourceObjectSchemas } from "./utils/deep-extract-resource-object-schemas.js"
10
10
  import readmeMdTemplate from "./templates/readme.md.template.js"
@@ -14,6 +14,7 @@ import gitignoreTemplate from "./templates/gitignore.template.js"
14
14
  import envExampleTemplate from "./templates/env.example.template.js"
15
15
  import testFixtureTemplate from "./templates/test-fixture.template.js"
16
16
  import smokeTestTemplate from "./templates/smoke-test.template.js"
17
+ import mapParentToChildrenResources from "lib/openapi/map-parent-to-children-resource.js"
17
18
 
18
19
  export const generatePhpSDK = async () => {
19
20
  const openapi: OpenAPISchema = await axios
@@ -64,43 +65,18 @@ export const generatePhpSDK = async () => {
64
65
  }
65
66
  }
66
67
 
67
- const parent_resource_to_children_map = routes.reduce(
68
- (acc: Record<string, string[]>, route) => {
69
- if (!route.post?.["x-fern-sdk-group-name"]) return acc
70
-
71
- const [parent_resource_name, child_resource_name] =
72
- route.post["x-fern-sdk-group-name"]
73
-
74
- // Making TS happy
75
- if (!parent_resource_name) return acc
76
-
77
- if (!acc[parent_resource_name]) {
78
- acc[parent_resource_name] = []
79
- }
80
-
81
- if (
82
- child_resource_name &&
83
- !acc[parent_resource_name]!.includes(child_resource_name)
84
- ) {
85
- acc[parent_resource_name]!.push(child_resource_name)
86
- }
87
-
88
- return acc
89
- },
90
- {}
91
- )
92
-
68
+ const parent_to_children_resources_map = mapParentToChildrenResources(routes)
93
69
  const clients: Record<string, PhpClient> = {}
94
70
 
95
71
  const processClient = (resource_name: string) => {
96
- const child_client_identifiers: PhpClientIdentifiers[] = (
97
- parent_resource_to_children_map[resource_name] ?? []
72
+ const child_client_identifiers: PhpClientIdentifier[] = (
73
+ parent_to_children_resources_map[resource_name] ?? []
98
74
  ).map((child_resource) => ({
99
75
  client_name: pascalCase(`${resource_name} ${child_resource}`),
100
76
  namespace: child_resource,
101
77
  }))
102
78
  const is_parent_client = Object.keys(
103
- parent_resource_to_children_map
79
+ parent_to_children_resources_map
104
80
  ).includes(resource_name)
105
81
  const pascal_resource_name = pascalCase(resource_name)
106
82
 
@@ -16,7 +16,7 @@ export type PhpClientMethod = {
16
16
 
17
17
  type ClientName = string
18
18
  type Namespace = string
19
- export type PhpClientIdentifiers = {
19
+ export type PhpClientIdentifier = {
20
20
  client_name: ClientName
21
21
  namespace: Namespace
22
22
  }
@@ -28,7 +28,7 @@ export class PhpClient {
28
28
  public client_name: ClientName,
29
29
  public namespace: Namespace,
30
30
  public is_parent_client: boolean,
31
- public child_client_identifiers: PhpClientIdentifiers[]
31
+ public child_client_identifiers: PhpClientIdentifier[]
32
32
  ) {
33
33
  this.methods = []
34
34
  }