freelang-v4 4.3.0

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 (261) hide show
  1. package/README.md +548 -0
  2. package/dist/ast.d.ts +367 -0
  3. package/dist/ast.js +4 -0
  4. package/dist/ast.js.map +1 -0
  5. package/dist/async-basic.test.d.ts +1 -0
  6. package/dist/async-basic.test.js +88 -0
  7. package/dist/async-basic.test.js.map +1 -0
  8. package/dist/async-jest.test.d.ts +1 -0
  9. package/dist/async-jest.test.js +99 -0
  10. package/dist/async-jest.test.js.map +1 -0
  11. package/dist/channel-jest.test.d.ts +1 -0
  12. package/dist/channel-jest.test.js +148 -0
  13. package/dist/channel-jest.test.js.map +1 -0
  14. package/dist/checker-jest.test.d.ts +1 -0
  15. package/dist/checker-jest.test.js +160 -0
  16. package/dist/checker-jest.test.js.map +1 -0
  17. package/dist/checker.d.ts +149 -0
  18. package/dist/checker.js +1565 -0
  19. package/dist/checker.js.map +1 -0
  20. package/dist/checker.test.d.ts +1 -0
  21. package/dist/checker.test.js +217 -0
  22. package/dist/checker.test.js.map +1 -0
  23. package/dist/compiler-jest.test.d.ts +1 -0
  24. package/dist/compiler-jest.test.js +233 -0
  25. package/dist/compiler-jest.test.js.map +1 -0
  26. package/dist/compiler.d.ts +127 -0
  27. package/dist/compiler.js +1588 -0
  28. package/dist/compiler.js.map +1 -0
  29. package/dist/compiler.test.d.ts +1 -0
  30. package/dist/compiler.test.js +313 -0
  31. package/dist/compiler.test.js.map +1 -0
  32. package/dist/db-100m-full.d.ts +5 -0
  33. package/dist/db-100m-full.js +78 -0
  34. package/dist/db-100m-full.js.map +1 -0
  35. package/dist/db-100m-no-index.d.ts +12 -0
  36. package/dist/db-100m-no-index.js +119 -0
  37. package/dist/db-100m-no-index.js.map +1 -0
  38. package/dist/db-100m-real.d.ts +5 -0
  39. package/dist/db-100m-real.js +131 -0
  40. package/dist/db-100m-real.js.map +1 -0
  41. package/dist/db-100m-streaming.d.ts +15 -0
  42. package/dist/db-100m-streaming.js +164 -0
  43. package/dist/db-100m-streaming.js.map +1 -0
  44. package/dist/db-100m-test.d.ts +5 -0
  45. package/dist/db-100m-test.js +111 -0
  46. package/dist/db-100m-test.js.map +1 -0
  47. package/dist/db-jest.test.d.ts +1 -0
  48. package/dist/db-jest.test.js +182 -0
  49. package/dist/db-jest.test.js.map +1 -0
  50. package/dist/db-runtime.d.ts +24 -0
  51. package/dist/db-runtime.js +204 -0
  52. package/dist/db-runtime.js.map +1 -0
  53. package/dist/db.d.ts +249 -0
  54. package/dist/db.js +593 -0
  55. package/dist/db.js.map +1 -0
  56. package/dist/file-io-jest.test.d.ts +1 -0
  57. package/dist/file-io-jest.test.js +225 -0
  58. package/dist/file-io-jest.test.js.map +1 -0
  59. package/dist/for-of-jest.test.d.ts +1 -0
  60. package/dist/for-of-jest.test.js +230 -0
  61. package/dist/for-of-jest.test.js.map +1 -0
  62. package/dist/for-of.test.d.ts +1 -0
  63. package/dist/for-of.test.js +305 -0
  64. package/dist/for-of.test.js.map +1 -0
  65. package/dist/function-literal-jest.test.d.ts +1 -0
  66. package/dist/function-literal-jest.test.js +180 -0
  67. package/dist/function-literal-jest.test.js.map +1 -0
  68. package/dist/function-literal.test.d.ts +1 -0
  69. package/dist/function-literal.test.js +245 -0
  70. package/dist/function-literal.test.js.map +1 -0
  71. package/dist/generics-jest.test.d.ts +1 -0
  72. package/dist/generics-jest.test.js +93 -0
  73. package/dist/generics-jest.test.js.map +1 -0
  74. package/dist/ir-gen.d.ts +15 -0
  75. package/dist/ir-gen.js +400 -0
  76. package/dist/ir-gen.js.map +1 -0
  77. package/dist/ir.d.ts +114 -0
  78. package/dist/ir.js +5 -0
  79. package/dist/ir.js.map +1 -0
  80. package/dist/lexer.d.ts +110 -0
  81. package/dist/lexer.js +467 -0
  82. package/dist/lexer.js.map +1 -0
  83. package/dist/lexer.test.d.ts +1 -0
  84. package/dist/lexer.test.js +426 -0
  85. package/dist/lexer.test.js.map +1 -0
  86. package/dist/main.d.ts +2 -0
  87. package/dist/main.js +241 -0
  88. package/dist/main.js.map +1 -0
  89. package/dist/module-jest.test.d.ts +1 -0
  90. package/dist/module-jest.test.js +123 -0
  91. package/dist/module-jest.test.js.map +1 -0
  92. package/dist/parser.d.ts +56 -0
  93. package/dist/parser.js +1060 -0
  94. package/dist/parser.js.map +1 -0
  95. package/dist/parser.test.d.ts +1 -0
  96. package/dist/parser.test.js +461 -0
  97. package/dist/parser.test.js.map +1 -0
  98. package/dist/pattern-matching-jest.test.d.ts +1 -0
  99. package/dist/pattern-matching-jest.test.js +158 -0
  100. package/dist/pattern-matching-jest.test.js.map +1 -0
  101. package/dist/pkg/init.d.ts +1 -0
  102. package/dist/pkg/init.js +118 -0
  103. package/dist/pkg/init.js.map +1 -0
  104. package/dist/pkg/install.d.ts +1 -0
  105. package/dist/pkg/install.js +77 -0
  106. package/dist/pkg/install.js.map +1 -0
  107. package/dist/pkg/registry.d.ts +23 -0
  108. package/dist/pkg/registry.js +106 -0
  109. package/dist/pkg/registry.js.map +1 -0
  110. package/dist/pkg/run.d.ts +1 -0
  111. package/dist/pkg/run.js +76 -0
  112. package/dist/pkg/run.js.map +1 -0
  113. package/dist/pkg/toml.d.ts +5 -0
  114. package/dist/pkg/toml.js +117 -0
  115. package/dist/pkg/toml.js.map +1 -0
  116. package/dist/repl.d.ts +15 -0
  117. package/dist/repl.js +197 -0
  118. package/dist/repl.js.map +1 -0
  119. package/dist/runtime/bytecode.d.ts +92 -0
  120. package/dist/runtime/bytecode.js +253 -0
  121. package/dist/runtime/bytecode.js.map +1 -0
  122. package/dist/runtime/value.d.ts +102 -0
  123. package/dist/runtime/value.js +302 -0
  124. package/dist/runtime/value.js.map +1 -0
  125. package/dist/runtime/vm.d.ts +65 -0
  126. package/dist/runtime/vm.js +293 -0
  127. package/dist/runtime/vm.js.map +1 -0
  128. package/dist/struct-instance-jest.test.d.ts +1 -0
  129. package/dist/struct-instance-jest.test.js +209 -0
  130. package/dist/struct-instance-jest.test.js.map +1 -0
  131. package/dist/struct-instance.test.d.ts +1 -0
  132. package/dist/struct-instance.test.js +291 -0
  133. package/dist/struct-instance.test.js.map +1 -0
  134. package/dist/struct-jest.test.d.ts +1 -0
  135. package/dist/struct-jest.test.js +176 -0
  136. package/dist/struct-jest.test.js.map +1 -0
  137. package/dist/struct.test.d.ts +1 -0
  138. package/dist/struct.test.js +231 -0
  139. package/dist/struct.test.js.map +1 -0
  140. package/dist/trait-jest.test.d.ts +1 -0
  141. package/dist/trait-jest.test.js +120 -0
  142. package/dist/trait-jest.test.js.map +1 -0
  143. package/dist/vm-jest.test.d.ts +1 -0
  144. package/dist/vm-jest.test.js +569 -0
  145. package/dist/vm-jest.test.js.map +1 -0
  146. package/dist/vm.d.ts +81 -0
  147. package/dist/vm.js +1956 -0
  148. package/dist/vm.js.map +1 -0
  149. package/dist/vm.test.d.ts +1 -0
  150. package/dist/vm.test.js +337 -0
  151. package/dist/vm.test.js.map +1 -0
  152. package/dist/web-repl/sandbox.d.ts +11 -0
  153. package/dist/web-repl/sandbox.js +76 -0
  154. package/dist/web-repl/sandbox.js.map +1 -0
  155. package/dist/web-repl/server.d.ts +1 -0
  156. package/dist/web-repl/server.js +111 -0
  157. package/dist/web-repl/server.js.map +1 -0
  158. package/dist/while-loop-jest.test.d.ts +1 -0
  159. package/dist/while-loop-jest.test.js +201 -0
  160. package/dist/while-loop-jest.test.js.map +1 -0
  161. package/dist/while-loop.test.d.ts +1 -0
  162. package/dist/while-loop.test.js +262 -0
  163. package/dist/while-loop.test.js.map +1 -0
  164. package/docs/EXPERIENCE.md +787 -0
  165. package/docs/README.md +175 -0
  166. package/docs/V1_V2_V3_ANALYSIS.md +107 -0
  167. package/docs/_config.yml +36 -0
  168. package/docs/api-reference.md +459 -0
  169. package/docs/architecture.md +470 -0
  170. package/docs/benchmarks.md +295 -0
  171. package/docs/comparison.md +454 -0
  172. package/docs/index.md +335 -0
  173. package/docs/language-completeness.md +228 -0
  174. package/docs/learning-guide.md +651 -0
  175. package/package.json +65 -0
  176. package/src/api/deploy_key.fl +294 -0
  177. package/src/api/issue.fl +302 -0
  178. package/src/api/org.fl +356 -0
  179. package/src/api/repo.fl +394 -0
  180. package/src/api/team.fl +299 -0
  181. package/src/api/user.fl +385 -0
  182. package/src/api/webhook.fl +273 -0
  183. package/src/ast.ts +158 -0
  184. package/src/async-basic.test.ts +94 -0
  185. package/src/async-jest.test.ts +107 -0
  186. package/src/channel-jest.test.ts +158 -0
  187. package/src/checker-jest.test.ts +189 -0
  188. package/src/checker.test.ts +279 -0
  189. package/src/checker.ts +1861 -0
  190. package/src/commands/analyze.fl +227 -0
  191. package/src/commands/auth.fl +315 -0
  192. package/src/commands/batch.fl +349 -0
  193. package/src/commands/config.fl +199 -0
  194. package/src/commands/deploy_key.fl +352 -0
  195. package/src/commands/issue.fl +275 -0
  196. package/src/commands/main.fl +492 -0
  197. package/src/commands/org.fl +425 -0
  198. package/src/commands/repo.fl +581 -0
  199. package/src/commands/team.fl +244 -0
  200. package/src/commands/user.fl +423 -0
  201. package/src/commands/webhook.fl +400 -0
  202. package/src/compiler-jest.test.ts +275 -0
  203. package/src/compiler.test.ts +375 -0
  204. package/src/compiler.ts +1770 -0
  205. package/src/config.fl +175 -0
  206. package/src/core/batch.fl +355 -0
  207. package/src/core/cache.fl +284 -0
  208. package/src/core/ensure.fl +324 -0
  209. package/src/db-100m-full.ts +96 -0
  210. package/src/db-100m-no-index.ts +133 -0
  211. package/src/db-100m-real.ts +152 -0
  212. package/src/db-100m-streaming.ts +154 -0
  213. package/src/db-100m-test.ts +136 -0
  214. package/src/db-jest.test.ts +161 -0
  215. package/src/db-runtime.ts +242 -0
  216. package/src/db.ts +676 -0
  217. package/src/errors.fl +134 -0
  218. package/src/for-of-jest.test.ts +246 -0
  219. package/src/for-of.test.ts +308 -0
  220. package/src/function-literal-jest.test.ts +193 -0
  221. package/src/function-literal.test.ts +248 -0
  222. package/src/generics-jest.test.ts +104 -0
  223. package/src/http/client.fl +327 -0
  224. package/src/ir-gen.ts +459 -0
  225. package/src/ir.ts +80 -0
  226. package/src/lexer.test.ts +499 -0
  227. package/src/lexer.ts +522 -0
  228. package/src/main.ts +223 -0
  229. package/src/models.fl +162 -0
  230. package/src/module-jest.test.ts +145 -0
  231. package/src/parser.test.ts +542 -0
  232. package/src/parser.ts +1211 -0
  233. package/src/pattern-matching-jest.test.ts +170 -0
  234. package/src/pkg/init.ts +91 -0
  235. package/src/pkg/install.ts +56 -0
  236. package/src/pkg/registry.ts +103 -0
  237. package/src/pkg/run.ts +49 -0
  238. package/src/pkg/toml.ts +129 -0
  239. package/src/repl.ts +190 -0
  240. package/src/runtime/bytecode.ts +291 -0
  241. package/src/runtime/value.ts +322 -0
  242. package/src/runtime/vm.ts +354 -0
  243. package/src/self-host/bootstrap.fl +68 -0
  244. package/src/self-host/interpreter.fl +361 -0
  245. package/src/self-host/lexer-simple.fl +22 -0
  246. package/src/self-host/lexer.fl +305 -0
  247. package/src/self-host/parser.fl +580 -0
  248. package/src/struct-instance-jest.test.ts +221 -0
  249. package/src/struct-instance.test.ts +293 -0
  250. package/src/struct-jest.test.ts +187 -0
  251. package/src/struct.test.ts +234 -0
  252. package/src/trait-jest.test.ts +136 -0
  253. package/src/vm-jest.test.ts +754 -0
  254. package/src/vm.ts +1976 -0
  255. package/src/web-repl/public/index.html +50 -0
  256. package/src/web-repl/public/main.js +105 -0
  257. package/src/web-repl/public/style.css +225 -0
  258. package/src/web-repl/sandbox.ts +88 -0
  259. package/src/web-repl/server.ts +97 -0
  260. package/src/while-loop-jest.test.ts +218 -0
  261. package/src/while-loop.test.ts +267 -0
package/src/api/org.fl ADDED
@@ -0,0 +1,356 @@
1
+ // FreeLang v4.2 — Gogs CLI OrgService
2
+ // 조직 관리 API 서비스
3
+ // 250라인: list, get, create, update, delete, ensure
4
+
5
+ /// 조직 서비스
6
+ struct OrgService {
7
+ client: HttpClient
8
+ cache: CacheManager
9
+ }
10
+
11
+ /// OrgService 생성
12
+ fn new_org_service(client: HttpClient, cache: CacheManager) -> OrgService {
13
+ OrgService {
14
+ client: client,
15
+ cache: cache
16
+ }
17
+ }
18
+
19
+ // ==================== 조직 CRUD ====================
20
+
21
+ /// 조직 목록 조회
22
+ async fn list_orgs(service: OrgService) -> Result<[Organization]> {
23
+ var cache_key = "orgs:list"
24
+
25
+ // 캐시 확인
26
+ var cached = cache_get(service.cache, cache_key)
27
+ if cached != "" {
28
+ println("[cache] hit: orgs list")
29
+ var orgs_arr = json_parse(cached) as [Organization]
30
+ return Result::Ok(orgs_arr)
31
+ }
32
+
33
+ // API 호출
34
+ var resp = await http_get(service.client, "/api/v1/user/orgs")
35
+
36
+ if is_error(resp.status) {
37
+ return Result::Err(response_to_error(resp))
38
+ }
39
+
40
+ // 캐시 저장
41
+ cache_set(service.cache, cache_key, resp.body)
42
+
43
+ // 파싱
44
+ var orgs_arr = json_parse(resp.body) as [Organization]
45
+ Result::Ok(orgs_arr)
46
+ }
47
+
48
+ /// 조직 상세 조회
49
+ async fn get_org(service: OrgService, name: str) -> Result<Organization> {
50
+ var cache_key = "org:" + name
51
+
52
+ // 캐시 확인
53
+ var cached = cache_get(service.cache, cache_key)
54
+ if cached != "" {
55
+ println("[cache] hit: " + cache_key)
56
+ var org = json_parse(cached) as Organization
57
+ return Result::Ok(org)
58
+ }
59
+
60
+ // API 호출
61
+ var path = "/api/v1/orgs/" + name
62
+ var resp = await http_get(service.client, path)
63
+
64
+ if is_error(resp.status) {
65
+ return Result::Err(response_to_error(resp))
66
+ }
67
+
68
+ // 캐시 저장
69
+ cache_set(service.cache, cache_key, resp.body)
70
+
71
+ // 파싱
72
+ var org = json_parse(resp.body) as Organization
73
+ Result::Ok(org)
74
+ }
75
+
76
+ /// 조직 생성
77
+ async fn create_org(service: OrgService, req: CreateOrgRequest) -> Result<Organization> {
78
+ var json_data = json_stringify(req)
79
+ var resp = await http_post_json(service.client, "/api/v1/orgs", json_data)
80
+
81
+ if is_error(resp.status) {
82
+ return Result::Err(response_to_error(resp))
83
+ }
84
+
85
+ // 캐시 무효화
86
+ cache_invalidate(service.cache, "orgs:list")
87
+
88
+ // 파싱
89
+ var org = json_parse(resp.body) as Organization
90
+ Result::Ok(org)
91
+ }
92
+
93
+ /// 조직 업데이트
94
+ async fn update_org(service: OrgService, name: str, req: UpdateOrgRequest) -> Result<Organization> {
95
+ var path = "/api/v1/orgs/" + name
96
+ var json_data = json_stringify(req)
97
+ var resp = await http_patch(service.client, path, json_data)
98
+
99
+ if is_error(resp.status) {
100
+ return Result::Err(response_to_error(resp))
101
+ }
102
+
103
+ // 캐시 무효화
104
+ var cache_key = "org:" + name
105
+ cache_invalidate(service.cache, cache_key)
106
+ cache_invalidate(service.cache, "orgs:list")
107
+
108
+ // 파싱
109
+ var org = json_parse(resp.body) as Organization
110
+ Result::Ok(org)
111
+ }
112
+
113
+ /// 조직 삭제
114
+ async fn delete_org(service: OrgService, name: str) -> Result<str> {
115
+ var path = "/api/v1/orgs/" + name
116
+ var resp = await http_delete(service.client, path)
117
+
118
+ if is_error(resp.status) {
119
+ return Result::Err(response_to_error(resp))
120
+ }
121
+
122
+ // 캐시 무효화
123
+ var cache_key = "org:" + name
124
+ cache_invalidate(service.cache, cache_key)
125
+ cache_invalidate(service.cache, "orgs:list")
126
+
127
+ Result::Ok("Organization deleted")
128
+ }
129
+
130
+ // ==================== Ensure 패턴 ====================
131
+
132
+ /// 조직 ensure (멱등성 보증)
133
+ async fn ensure_org(service: OrgService, req: CreateOrgRequest) -> Result<EnsureAction> {
134
+ var path = "/api/v1/orgs/" + req.username
135
+
136
+ // desired 상태 정의
137
+ var desired_json = json_stringify(req)
138
+
139
+ var ctx = EnsureContext {
140
+ name: req.username,
141
+
142
+ get_fn: async fn() -> Result<str> {
143
+ var resp = await http_get(service.client, path)
144
+ if is_error(resp.status) {
145
+ if resp.status == 404 {
146
+ Result::Ok("") // 없음
147
+ } else {
148
+ Result::Err(response_to_error(resp))
149
+ }
150
+ } else {
151
+ Result::Ok(resp.body)
152
+ }
153
+ },
154
+
155
+ create_fn: async fn() -> Result<str> {
156
+ var json_data = json_stringify(req)
157
+ var resp = await http_post_json(service.client, "/api/v1/orgs", json_data)
158
+ if is_error(resp.status) {
159
+ Result::Err(response_to_error(resp))
160
+ } else {
161
+ // 캐시 무효화
162
+ cache_invalidate(service.cache, "orgs:list")
163
+ Result::Ok(resp.body)
164
+ }
165
+ },
166
+
167
+ update_fn: async fn(changes: [str]) -> Result<str> {
168
+ var update_req = UpdateOrgRequest {
169
+ full_name: req.full_name,
170
+ email: req.email,
171
+ website: req.website,
172
+ location: req.location,
173
+ bio: req.bio
174
+ }
175
+ var json_data = json_stringify(update_req)
176
+ var resp = await http_patch(service.client, path, json_data)
177
+ if is_error(resp.status) {
178
+ Result::Err(response_to_error(resp))
179
+ } else {
180
+ // 캐시 무효화
181
+ var cache_key = "org:" + req.username
182
+ cache_invalidate(service.cache, cache_key)
183
+ cache_invalidate(service.cache, "orgs:list")
184
+ Result::Ok(resp.body)
185
+ }
186
+ },
187
+
188
+ delete_fn: async fn() -> Result<str> {
189
+ var resp = await http_delete(service.client, path)
190
+ if is_error(resp.status) {
191
+ Result::Err(response_to_error(resp))
192
+ } else {
193
+ // 캐시 무효화
194
+ var cache_key = "org:" + req.username
195
+ cache_invalidate(service.cache, cache_key)
196
+ cache_invalidate(service.cache, "orgs:list")
197
+ Result::Ok("")
198
+ }
199
+ },
200
+
201
+ desired: desired_json
202
+ }
203
+
204
+ var action = await ensure(ctx)
205
+ Result::Ok(action)
206
+ }
207
+
208
+ // ==================== 조직 멤버 ====================
209
+
210
+ /// 조직 멤버 목록
211
+ async fn list_org_members(service: OrgService, org_name: str) -> Result<[User]> {
212
+ var cache_key = "org_members:" + org_name
213
+
214
+ // 캐시 확인
215
+ var cached = cache_get(service.cache, cache_key)
216
+ if cached != "" {
217
+ println("[cache] hit: " + cache_key)
218
+ var members_arr = json_parse(cached) as [User]
219
+ return Result::Ok(members_arr)
220
+ }
221
+
222
+ // API 호출
223
+ var path = "/api/v1/orgs/" + org_name + "/members"
224
+ var resp = await http_get(service.client, path)
225
+
226
+ if is_error(resp.status) {
227
+ return Result::Err(response_to_error(resp))
228
+ }
229
+
230
+ // 캐시 저장
231
+ cache_set(service.cache, cache_key, resp.body)
232
+
233
+ // 파싱
234
+ var members_arr = json_parse(resp.body) as [User]
235
+ Result::Ok(members_arr)
236
+ }
237
+
238
+ /// 조직 멤버 추가
239
+ async fn add_org_member(service: OrgService, org_name: str, username: str) -> Result<str> {
240
+ var path = "/api/v1/orgs/" + org_name + "/members/" + username
241
+ var resp = await http_put(service.client, path, "{}")
242
+
243
+ if is_error(resp.status) {
244
+ return Result::Err(response_to_error(resp))
245
+ }
246
+
247
+ // 캐시 무효화
248
+ var cache_key = "org_members:" + org_name
249
+ cache_invalidate(service.cache, cache_key)
250
+
251
+ Result::Ok("Member added to organization")
252
+ }
253
+
254
+ /// 조직 멤버 제거
255
+ async fn remove_org_member(service: OrgService, org_name: str, username: str) -> Result<str> {
256
+ var path = "/api/v1/orgs/" + org_name + "/members/" + username
257
+ var resp = await http_delete(service.client, path)
258
+
259
+ if is_error(resp.status) {
260
+ return Result::Err(response_to_error(resp))
261
+ }
262
+
263
+ // 캐시 무효화
264
+ var cache_key = "org_members:" + org_name
265
+ cache_invalidate(service.cache, cache_key)
266
+
267
+ Result::Ok("Member removed from organization")
268
+ }
269
+
270
+ // ==================== 조직 저장소 ====================
271
+
272
+ /// 조직 저장소 목록
273
+ async fn list_org_repos(service: OrgService, org_name: str) -> Result<[Repo]> {
274
+ var cache_key = "org_repos:" + org_name
275
+
276
+ // 캐시 확인
277
+ var cached = cache_get(service.cache, cache_key)
278
+ if cached != "" {
279
+ println("[cache] hit: " + cache_key)
280
+ var repos_arr = json_parse(cached) as [Repo]
281
+ return Result::Ok(repos_arr)
282
+ }
283
+
284
+ // API 호출
285
+ var path = "/api/v1/orgs/" + org_name + "/repos"
286
+ var resp = await http_get(service.client, path)
287
+
288
+ if is_error(resp.status) {
289
+ return Result::Err(response_to_error(resp))
290
+ }
291
+
292
+ // 캐시 저장
293
+ cache_set(service.cache, cache_key, resp.body)
294
+
295
+ // 파싱
296
+ var repos_arr = json_parse(resp.body) as [Repo]
297
+ Result::Ok(repos_arr)
298
+ }
299
+
300
+ // ==================== 조직 검색 ====================
301
+
302
+ /// 조직 검색
303
+ async fn search_orgs(service: OrgService, query: str) -> Result<[Organization]> {
304
+ var path = "/api/v1/orgs/search?q=" + query
305
+ var resp = await http_get(service.client, path)
306
+
307
+ if is_error(resp.status) {
308
+ return Result::Err(response_to_error(resp))
309
+ }
310
+
311
+ // 파싱
312
+ var orgs_arr = json_parse(resp.body) as [Organization]
313
+ Result::Ok(orgs_arr)
314
+ }
315
+
316
+ // ==================== 별명 (Alias) ====================
317
+
318
+ /// 조직 목록 조회 (별명)
319
+ async fn list_all_orgs(service: OrgService) -> Result<[Organization]> {
320
+ await list_orgs(service)
321
+ }
322
+
323
+ /// 조직 생성 (별명)
324
+ async fn new_org(service: OrgService, name: str, full_name: str) -> Result<Organization> {
325
+ var req = CreateOrgRequest {
326
+ username: name,
327
+ full_name: full_name,
328
+ email: "",
329
+ website: "",
330
+ location: "",
331
+ bio: ""
332
+ }
333
+ await create_org(service, req)
334
+ }
335
+
336
+ /// 조직 삭제 (별명)
337
+ async fn rm_org(service: OrgService, name: str) -> Result<str> {
338
+ await delete_org(service, name)
339
+ }
340
+
341
+ // UpdateOrgRequest 모델 정의
342
+ struct UpdateOrgRequest {
343
+ full_name: str
344
+ email: str
345
+ website: str
346
+ location: str
347
+ bio: str
348
+ }
349
+
350
+ // 필요한 함수들 (다른 모듈에서 임포트):
351
+ // - http_get, http_post_json, http_delete, http_patch, http_put
352
+ // - is_error, response_to_error
353
+ // - cache_get, cache_set, cache_invalidate
354
+ // - json_stringify, json_parse
355
+ // - ensure, EnsureContext, EnsureAction
356
+ // - println, length