Skip to content

Commit f0a6764

Browse files
committed
Merge remote-tracking branch 'upstream/master' into tests-dotnet
2 parents 8bfe93e + cd71267 commit f0a6764

File tree

136 files changed

+5712
-308
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

136 files changed

+5712
-308
lines changed

src/SDK/Language.php

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,25 @@ abstract public function getKeywords(): array;
3232
*/
3333
abstract public function getIdentifierOverrides(): array;
3434

35+
/**
36+
* Get the static access operator for the language (e.g. '::' for PHP, '.' for JS)
37+
* @return string
38+
*/
39+
abstract public function getStaticAccessOperator(): string;
40+
41+
/**
42+
* Get the string quote character for the language (e.g. '"' for PHP, "'" for JS)
43+
* @return string
44+
*/
45+
abstract public function getStringQuote(): string;
46+
47+
/**
48+
* Wrap elements in an array syntax for the language
49+
* @param string $elements Comma-separated elements
50+
* @return string
51+
*/
52+
abstract public function getArrayOf(string $elements): string;
53+
3554
/**
3655
* @return array<array>
3756
*/
@@ -137,4 +156,124 @@ protected function toUpperSnakeCase($str): string
137156
{
138157
return \strtoupper($this->toSnakeCase($str));
139158
}
159+
160+
public function isPermissionString(string $string): bool
161+
{
162+
$pattern = '/^\["(read|update|delete|write)\(\\"[^\\"]+\\"\)"(,\s*"(read|update|delete|write)\(\\"[^\\"]+\\"\)")*\]$/';
163+
return preg_match($pattern, $string) === 1;
164+
}
165+
166+
public function extractPermissionParts(string $string): array
167+
{
168+
$inner = substr($string, 1, -1);
169+
preg_match_all('/"(read|update|delete|write)\(\\"([^\\"]+)\\"\)"/', $inner, $matches, PREG_SET_ORDER);
170+
171+
$result = [];
172+
foreach ($matches as $match) {
173+
$action = $match[1];
174+
$roleString = $match[2];
175+
176+
$role = null;
177+
$id = null;
178+
$innerRole = null;
179+
180+
if (strpos($roleString, ':') !== false) {
181+
$role = explode(':', $roleString, 2)[0];
182+
$idString = explode(':', $roleString, 2)[1];
183+
184+
if (strpos($idString, '/') !== false) {
185+
$id = explode('/', $idString, 2)[0];
186+
$innerRole = explode('/', $idString, 2)[1];
187+
} else {
188+
$id = $idString;
189+
}
190+
} else {
191+
$role = $roleString;
192+
}
193+
194+
$result[] = [
195+
'action' => $action,
196+
'role' => $role,
197+
'id' => $id ?? null,
198+
'innerRole' => $innerRole
199+
];
200+
}
201+
202+
return $result;
203+
}
204+
205+
public function hasPermissionParam(array $parameters): bool
206+
{
207+
foreach ($parameters as $param) {
208+
$example = $param['example'] ?? '';
209+
if (!empty($example) && is_string($example) && $this->isPermissionString($example)) {
210+
return true;
211+
}
212+
}
213+
return false;
214+
}
215+
216+
/**
217+
* Get the prefix for Permission and Role classes (e.g., 'sdk.' for Node)
218+
* @return string
219+
*/
220+
protected function getPermissionPrefix(): string
221+
{
222+
return '';
223+
}
224+
225+
/**
226+
* Transform permission action name for language-specific casing
227+
* Override in child classes if needed (e.g., DotNet uses ucfirst)
228+
* @param string $action
229+
* @return string
230+
*/
231+
protected function transformPermissionAction(string $action): string
232+
{
233+
return $action;
234+
}
235+
236+
/**
237+
* Transform permission role name for language-specific casing
238+
* Override in child classes if needed (e.g., DotNet uses ucfirst)
239+
* @param string $role
240+
* @return string
241+
*/
242+
protected function transformPermissionRole(string $role): string
243+
{
244+
return $role;
245+
}
246+
247+
/**
248+
* Generate permission example code for the language
249+
* @param string $example Permission string example
250+
* @return string
251+
*/
252+
public function getPermissionExample(string $example): string
253+
{
254+
$permissions = [];
255+
$staticOp = $this->getStaticAccessOperator();
256+
$quote = $this->getStringQuote();
257+
$prefix = $this->getPermissionPrefix();
258+
259+
foreach ($this->extractPermissionParts($example) as $permission) {
260+
$args = [];
261+
if ($permission['id'] !== null) {
262+
$args[] = $quote . $permission['id'] . $quote;
263+
}
264+
if ($permission['innerRole'] !== null) {
265+
$args[] = $quote . $permission['innerRole'] . $quote;
266+
}
267+
$argsString = implode(', ', $args);
268+
269+
$action = $permission['action'];
270+
$role = $permission['role'];
271+
$action = $this->transformPermissionAction($action);
272+
$role = $this->transformPermissionRole($role);
273+
274+
$permissions[] = $prefix . 'Permission' . $staticOp . $action . '(' . $prefix . 'Role' . $staticOp . $role . '(' . $argsString . '))';
275+
}
276+
277+
return $this->getArrayOf(implode(', ', $permissions));
278+
}
140279
}

src/SDK/Language/Android.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,11 @@ public function getFiles(): array
125125
'destination' => '/library/src/main/java/{{ sdk.namespace | caseSlash }}/Query.kt',
126126
'template' => '/android/library/src/main/java/io/package/Query.kt.twig',
127127
],
128+
[
129+
'scope' => 'default',
130+
'destination' => '/library/src/main/java/{{ sdk.namespace | caseSlash }}/Operator.kt',
131+
'template' => '/android/library/src/main/java/io/package/Operator.kt.twig',
132+
],
128133
[
129134
'scope' => 'default',
130135
'destination' => '/library/src/main/java/{{ sdk.namespace | caseSlash }}/exceptions/{{spec.title | caseUcfirst}}Exception.kt',

src/SDK/Language/Apple.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ public function getFiles(): array
7575
'destination' => '/Sources/{{ spec.title | caseUcfirst}}/Query.swift',
7676
'template' => 'swift/Sources/Query.swift.twig',
7777
],
78+
[
79+
'scope' => 'default',
80+
'destination' => '/Sources/{{ spec.title | caseUcfirst}}/Operator.swift',
81+
'template' => 'swift/Sources/Operator.swift.twig',
82+
],
7883
[
7984
'scope' => 'default',
8085
'destination' => '/Sources/{{ spec.title | caseUcfirst}}/Models/UploadProgress.swift',
@@ -219,7 +224,7 @@ public function getFiles(): array
219224
[
220225
'scope' => 'default',
221226
'destination' => '/Sources/{{ spec.title | caseUcfirst}}/Services/Realtime.swift',
222-
'template' => '/swift/Sources/Services/Realtime.swift.twig',
227+
'template' => '/apple/Sources/Services/Realtime.swift.twig',
223228
],
224229
[
225230
'scope' => 'default',

src/SDK/Language/Dart.php

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,21 @@ public function getIdentifierOverrides(): array
121121
];
122122
}
123123

124+
public function getStaticAccessOperator(): string
125+
{
126+
return '.';
127+
}
128+
129+
public function getStringQuote(): string
130+
{
131+
return "'";
132+
}
133+
134+
public function getArrayOf(string $elements): string
135+
{
136+
return '[' . $elements . ']';
137+
}
138+
124139
/**
125140
* @param array $parameter
126141
* @return string
@@ -240,7 +255,8 @@ public function getParamExample(array $param): string
240255
}
241256

242257
return match ($type) {
243-
self::TYPE_ARRAY, self::TYPE_FILE, self::TYPE_INTEGER, self::TYPE_NUMBER => $example,
258+
self::TYPE_ARRAY => $this->isPermissionString($example) ? $this->getPermissionExample($example) : $example,
259+
self::TYPE_FILE, self::TYPE_INTEGER, self::TYPE_NUMBER => $example,
244260
self::TYPE_BOOLEAN => ($example) ? 'true' : 'false',
245261
self::TYPE_OBJECT => ($decoded = json_decode($example, true)) !== null
246262
? (empty($decoded) && $example === '{}'
@@ -342,6 +358,11 @@ public function getFiles(): array
342358
'destination' => '/lib/query.dart',
343359
'template' => 'dart/lib/query.dart.twig',
344360
],
361+
[
362+
'scope' => 'default',
363+
'destination' => '/lib/operator.dart',
364+
'template' => 'dart/lib/operator.dart.twig',
365+
],
345366
[
346367
'scope' => 'default',
347368
'destination' => '/lib/{{ language.params.packageName }}.dart',
@@ -432,6 +453,11 @@ public function getFiles(): array
432453
'destination' => '/test/query_test.dart',
433454
'template' => 'dart/test/query_test.dart.twig',
434455
],
456+
[
457+
'scope' => 'default',
458+
'destination' => '/test/operator_test.dart',
459+
'template' => 'dart/test/operator_test.dart.twig',
460+
],
435461
[
436462
'scope' => 'default',
437463
'destination' => '/test/role_test.dart',

src/SDK/Language/Deno.php

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,21 @@ public function getName(): string
1212
return 'Deno';
1313
}
1414

15+
public function getStaticAccessOperator(): string
16+
{
17+
return '.';
18+
}
19+
20+
public function getStringQuote(): string
21+
{
22+
return "'";
23+
}
24+
25+
public function getArrayOf(string $elements): string
26+
{
27+
return '[' . $elements . ']';
28+
}
29+
1530
/**
1631
* @return array
1732
*/
@@ -63,11 +78,21 @@ public function getFiles(): array
6378
'destination' => 'src/query.ts',
6479
'template' => 'deno/src/query.ts.twig',
6580
],
81+
[
82+
'scope' => 'default',
83+
'destination' => 'src/operator.ts',
84+
'template' => 'deno/src/operator.ts.twig',
85+
],
6686
[
6787
'scope' => 'default',
6888
'destination' => 'test/query.test.ts',
6989
'template' => 'deno/test/query.test.ts.twig',
7090
],
91+
[
92+
'scope' => 'default',
93+
'destination' => 'test/operator.test.ts',
94+
'template' => 'deno/test/operator.test.ts.twig',
95+
],
7196
[
7297
'scope' => 'default',
7398
'destination' => 'src/inputFile.ts',
@@ -176,7 +201,8 @@ public function getParamExample(array $param): string
176201
}
177202

178203
return match ($type) {
179-
self::TYPE_ARRAY, self::TYPE_INTEGER, self::TYPE_NUMBER => $example,
204+
self::TYPE_ARRAY => $this->isPermissionString($example) ? $this->getPermissionExample($example) : $example,
205+
self::TYPE_INTEGER, self::TYPE_NUMBER => $example,
180206
self::TYPE_FILE => 'InputFile.fromPath(\'/path/to/file.png\', \'file.png\')',
181207
self::TYPE_BOOLEAN => ($example) ? 'true' : 'false',
182208
self::TYPE_OBJECT => ($example === '{}')

src/SDK/Language/DotNet.php

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,31 @@ public function getIdentifierOverrides(): array
146146
];
147147
}
148148

149+
public function getStaticAccessOperator(): string
150+
{
151+
return '.';
152+
}
153+
154+
public function getStringQuote(): string
155+
{
156+
return '"';
157+
}
158+
159+
public function getArrayOf(string $elements): string
160+
{
161+
return 'new List<string> { ' . $elements . ' }';
162+
}
163+
164+
protected function transformPermissionAction(string $action): string
165+
{
166+
return ucfirst($action);
167+
}
168+
169+
protected function transformPermissionRole(string $role): string
170+
{
171+
return ucfirst($role);
172+
}
173+
149174
public function getPropertyOverrides(): array
150175
{
151176
return [
@@ -282,9 +307,11 @@ public function getParamExample(array $param): string
282307
case self::TYPE_FILE:
283308
case self::TYPE_NUMBER:
284309
case self::TYPE_INTEGER:
285-
case self::TYPE_ARRAY:
286310
$output .= $example;
287311
break;
312+
case self::TYPE_ARRAY:
313+
$output .= $this->isPermissionString($example) ? $this->getPermissionExample($example) : $example;
314+
break;
288315
case self::TYPE_OBJECT:
289316
if ($example === '{}') {
290317
$output .= '[object]';
@@ -381,6 +408,11 @@ public function getFiles(): array
381408
'destination' => '{{ spec.title | caseUcfirst }}/Query.cs',
382409
'template' => 'dotnet/Package/Query.cs.twig',
383410
],
411+
[
412+
'scope' => 'default',
413+
'destination' => '{{ spec.title | caseUcfirst }}/Operator.cs',
414+
'template' => 'dotnet/Package/Operator.cs.twig',
415+
],
384416
[
385417
'scope' => 'default',
386418
'destination' => '{{ spec.title | caseUcfirst }}/Role.cs',

src/SDK/Language/Flutter.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ public function getFiles(): array
8585
'destination' => '/lib/query.dart',
8686
'template' => 'dart/lib/query.dart.twig',
8787
],
88+
[
89+
'scope' => 'default',
90+
'destination' => '/lib/operator.dart',
91+
'template' => 'dart/lib/operator.dart.twig',
92+
],
8893
[
8994
'scope' => 'definition',
9095
'destination' => '/lib/src/models/{{definition.name | caseSnake }}.dart',
@@ -275,6 +280,11 @@ public function getFiles(): array
275280
'destination' => '/test/query_test.dart',
276281
'template' => 'dart/test/query_test.dart.twig',
277282
],
283+
[
284+
'scope' => 'default',
285+
'destination' => '/test/operator_test.dart',
286+
'template' => 'dart/test/operator_test.dart.twig',
287+
],
278288
[
279289
'scope' => 'default',
280290
'destination' => '/test/role_test.dart',

0 commit comments

Comments
 (0)