Skip to content

fix: pin CLI template @appwrite.io/console to 15.3.0 and dedupe generated query flags#1653

Merged
ChiragAgg5k merged 6 commits into
mainfrom
fix-cli-console-sdk-pin
Jul 10, 2026
Merged

fix: pin CLI template @appwrite.io/console to 15.3.0 and dedupe generated query flags#1653
ChiragAgg5k merged 6 commits into
mainfrom
fix-cli-console-sdk-pin

Conversation

@ChiragAgg5k

@ChiragAgg5k ChiragAgg5k commented Jul 10, 2026

Copy link
Copy Markdown
Member

This PR carries the fixes needed for the full validation matrix to pass against the current 1.9.x specs (synced in appwrite/specs#86). Four independent issues, all surfaced by the new spec:

1. Pin @appwrite.io/console to 15.3.0 in the CLI template

The CLI depends on the console web SDK. The template pinned a caret range:

-    "@appwrite.io/console": "^15.1.1",
+    "@appwrite.io/console": "15.3.0",

sdk-for-cli is already pinned to exactly 15.3.0 (appwrite/sdk-for-cli@f232e97), so every regeneration reverted it back to ^15.1.1 — which can resolve to console SDKs missing the new APIs (organization memberships, OAuth2 PAR, TablesDB migrations, addons) and fail the build with errors like:

error: No matching export in "node_modules/@appwrite.io/console/dist/esm/sdk.js" for import "Mongo"

package-lock.json.twig and bun.lock.twig were regenerated via scripts/update-lockfiles.sh cli (with npm 11 — an earlier regeneration with npm 10 dropped the libc fields on optional native-binary entries, caught by Greptile and fixed).

An exact pin keeps the template byte-identical with the generated repo and makes console bumps an explicit, reviewed change here.

2. CLI: generated query flags collided with spec-declared parameters

The CLI generator adds convenience flags (--filter, --sort-*, --limit, --offset, --cursor-*, --select) to any command whose method has a queries array parameter. The new cloud usage endpoints (listEvents, listGauges) declare literal limit/offset parameters alongside queries, so the generated command registered the same option twice and Commander threw at startup:

error: "limit" cannot be bound multiple times in the same parameter list

The generated flag groups are now tracked in a constant and a group is skipped when any of its option names collides with a parameter the method already declares — the spec-declared options win:

private const array QUERY_FLAG_PARAMS = [
    'filtering' => ['filter', 'where', 'sortAsc', 'sortDesc', 'cursorAfter', 'cursorBefore'],
    'pagination' => ['limit', 'offset'],
    'select' => ['select'],
];
$collides = fn (string $group): bool => array_intersect(self::QUERY_FLAG_PARAMS[$group], $parameterNames) !== [];
...
$hasPaginationQueries = $hasQueries && !$hasSelectionOnlyQueries && !$collides('pagination');

The same constant now also feeds the buildQueries builder params, removing the previously duplicated hardcoded lists.

3. Python: service/model name collision broke generic responses

The new organization service returns the organization model. The service template aliases the import on collision:

from ..models.organization import Organization as OrganizationModel

…but the generic-response paths still emitted the bare name in the return annotation and the response parsing:

def get(self, model_type: Type[T] = dict) -> Organization[T]:   # NameError
    ...
    return Organization.with_data(response, model_type)          # resolves to the service class

On Python ≤ 3.13, return annotations are evaluated at function-definition time, so importing the module raised:

NameError: name 'Organization' is not defined

(this was the python (server) validation failure — it doesn't reproduce on Python 3.14, which defers annotation evaluation). The collision alias is now applied in all three places (return annotation, docstring, .with_data() call):

def get(self, model_type: Type[T] = dict) -> OrganizationModel[T]:
    ...
    return OrganizationModel.with_data(response, model_type)

4. Dart: enum properties in nested model-test fixtures

The model test template handles enum properties at the top level, but its sub_schema macro (used for embedded models) fell through to the string branch, so organization_test.dart built the nested BillingPlan with a raw string:

BillingPlan(
  ...
  group: 'pro',   // error: The argument type 'String' can't be assigned to 'BillingPlanGroup'
)

The macro now emits enum literals, matching the top-level behavior:

BillingPlan(
  ...
  group: BillingPlanGroup.starter,
)

…and the enums.dart import condition also triggers when an enum appears only in a nested schema (previously it only checked the definition's own properties). This was the dart (server) validation failure (dart analyze exit 3).

Verification

All generated from the current 1.9.x specs into clean output dirs:

SDK Check Result
cli bun run linux-x64 binary compile ✅ compiles
cli tsc + npm run build ✅ 0 errors
cli node dist/cli.cjs usage list-events --help ✅ single --limit/--offset
python python -m unittest (full suite) ✅ 649 tests OK
dart dart analyze ✅ 0 errors
repo vendor/bin/rector process --dry-run ✅ clean

@greptile-apps

greptile-apps Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR delivers two targeted fixes to keep CLI template generation passing against the 1.9.x console spec, plus correctness fixes in the Python and Dart SDK templates.

  • CLI query flag deduplication: Introduces QUERY_FLAG_PARAMS constant and a per-group collision check in getCliQueryConfig; when a spec-declared parameter name matches any member of a generated flag group (e.g. limit/offset alongside queries), the entire group is suppressed, preventing Commander from throwing a "cannot be bound multiple times" error.
  • Console SDK pin: @appwrite.io/console is changed from the ^15.1.1 range to an exact 15.3.0 pin across package.json, package.json.twig, package-lock.json.twig, and bun.lock.twig, keeping the template byte-identical with the generated sdk-for-cli repo.
  • Python generic response fix: api.twig and service.py.twig now apply the Model name suffix before the [T] type parameter when a generic response model name collides with the service class name, correcting both the runtime dispatch call and the return-type annotation.
  • Dart enum import guard: The enums.dart import condition is extended to also trigger when a required property's sub-schema itself has required enum-typed properties, preventing missing-import compile errors in generated tests.

Confidence Score: 5/5

All changes are narrowly scoped bug fixes with no architectural side effects; safe to merge.

The CLI deduplication logic correctly identifies flag-group collisions and skips only the affected groups, leaving other groups intact. The console SDK pin, Python Model-suffix fix, and Dart enum import guard are all mechanically straightforward and directionally correct. No incorrect branching, missing guard, or data-loss path was found.

No files require special attention.

Important Files Changed

Filename Overview
src/SDK/Language/CLI.php Introduces QUERY_FLAG_PARAMS constant and per-group collision detection to prevent duplicate Commander option registration when spec parameters share names with generated query flags
templates/cli/package.json.twig Pins @appwrite.io/console from ^15.1.1 to exact 15.3.0 to match the already-pinned sdk-for-cli repo and avoid regressions from range resolution
templates/cli/package.json Mirrors the @appwrite.io/console pin to 15.3.0 in the non-twig package.json used for local development
templates/cli/package-lock.json.twig Lockfile regenerated by update-lockfiles.sh: @appwrite.io/console bumped to 15.3.0 and prettier to 3.9.5; side-effect libc field removal already discussed in a prior review thread
templates/cli/bun.lock.twig Bun lockfile regenerated to match: @appwrite.io/console to 15.3.0 and prettier to 3.9.5
templates/python/base/requests/api.twig Fixes generic response dispatch: when the response model name matches the service name, correctly calls ServiceNameModel.with_data() instead of ServiceName.with_data(), avoiding a Python class name collision
templates/python/package/services/service.py.twig Applies the same Model-suffix guard before [T] in both the return type annotation and the docstring for generic response methods
templates/dart/test/src/models/model_test.dart.twig Extends the enums.dart import guard to also trigger when a required property's sub-schema itself has required enum properties, and adds first-enum-value initialisation in the sub_schema macro

Reviews (5): Last reviewed commit: "(fix): handle service-model name collisi..." | Re-trigger Greptile

Comment thread templates/cli/package-lock.json.twig
@ChiragAgg5k

Copy link
Copy Markdown
Member Author

Good catch — the libc fields were dropped because the lockfile was regenerated with npm 10 (Node 22) instead of the repo's canonical Node 24 / npm 11. Regenerated with npm 11.16.0; the five optional native-binary entries now retain their libc fields.

@ChiragAgg5k ChiragAgg5k changed the title fix: pin CLI template @appwrite.io/console to 15.3.0 fix: pin CLI template @appwrite.io/console to 15.3.0 and dedupe generated query flags Jul 10, 2026
@ChiragAgg5k ChiragAgg5k merged commit 4dd8e9d into main Jul 10, 2026
58 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant