Mojolicious-Plugin-Fondation-OpenAPI

 view release on metacpan or  search on metacpan

README.md  view on Meta::CPAN


    'Fondation::OpenAPI' => {
        backend => 'main',          # optional -- falls back to DBIx::Async default
        schemas => { ... },         # optional -- column overrides
        no_validator_js => 0,       # optional -- default 0 (client validation on)
    }

### `no_validator_js`

When set to `1`, `openapi generate` still writes `public/js/validators.js`
but the generated `validate()` function accepts everything
(`return { valid: true, errors: [] }`). Server-side OpenAPI validation is
unaffected. Use it to rely solely on server validation (e.g. during testing).

Re-enable client validation by setting it back to `0` (or removing the key)
and regenerating. The same setting is exposed as a boolean parameter in the
plugin's `fondation_meta` `setup` block (default `0`).

### `pattern` in column overrides

Column `pattern` (like `minLength`, `maxLength`, `format`...) is a flat

README.md  view on Meta::CPAN

# OUTPUT FILES

- `share/openapi.json`

    OpenAPI 3.0.3 specification with API Base schemas, contextual
    projections (only when different), and CRUD paths. Committed to the
    application repository.

- `public/js/validators.js`

    Client-side form validation via `FondationValidators.validate()`.
    Consumed by [Fondation::Asset](https://metacpan.org/pod/Fondation%3A%3AAsset) bundles. Committed to the application
    repository.

Always run `openapi generate` before `asset generate`.

# SEE ALSO

[Mojolicious::Plugin::Fondation::OpenAPI::Command::openapi](https://metacpan.org/pod/Mojolicious%3A%3APlugin%3A%3AFondation%3A%3AOpenAPI%3A%3ACommand%3A%3Aopenapi),
[Fondation::Model::DBIx::Async](https://metacpan.org/pod/Fondation%3A%3AModel%3A%3ADBIx%3A%3AAsync),
[Mojolicious::Plugin::OpenAPI](https://metacpan.org/pod/Mojolicious%3A%3APlugin%3A%3AOpenAPI)

lib/Mojolicious/Plugin/Fondation/OpenAPI.pm  view on Meta::CPAN


  'Fondation::OpenAPI' => {
      backend => 'main',          # optional -- falls back to DBIx::Async default
      schemas => { ... },         # optional -- column overrides
      no_validator_js => 0,       # optional -- default 0 (client validation on)
  }

=head3 C<no_validator_js>

When set to C<1>, C<openapi generate> still writes C<public/js/validators.js>
but the generated C<validate()> function accepts everything
(C<return { valid: true, errors: [] }>). Server-side OpenAPI validation is
unaffected. Use it to rely solely on server validation (e.g. during testing).

Re-enable client validation by setting it back to C<0> (or removing the key)
and regenerating. The same setting is exposed as a boolean parameter in the
plugin's C<fondation_meta> C<setup> block (default C<0>).

=head3 C<pattern> in column overrides

Column C<pattern> (like C<minLength>, C<maxLength>, C<format>...) is a flat

lib/Mojolicious/Plugin/Fondation/OpenAPI.pm  view on Meta::CPAN

=over

=item C<share/openapi.json>

OpenAPI 3.0.3 specification with API Base schemas, contextual
projections (only when different), and CRUD paths. Committed to the
application repository.

=item C<public/js/validators.js>

Client-side form validation via C<FondationValidators.validate()>.
Consumed by L<Fondation::Asset> bundles. Committed to the application
repository.

=back

Always run C<openapi generate> before C<asset generate>.

=head1 SEE ALSO

L<Mojolicious::Plugin::Fondation::OpenAPI::Command::openapi>,

lib/Mojolicious/Plugin/Fondation/OpenAPI/Command/openapi.pm  view on Meta::CPAN


        $schemas_js .= "  }\n";
        $schemas_js .= "};\n\n";
    }

    my $validators = <<'VALIDATORS';
var FondationSchemas = {};
SCHEMAS_PLACEHOLDER

window.FondationValidators = {
    validate: function(schemaName, data) {
        var schema = FondationSchemas[schemaName];
        if (!schema) return { valid: false, errors: ['Schema not found: ' + schemaName] };

        var errors = [];

        for (var prop in schema.properties) {
            var rules = schema.properties[prop];
            var val   = data[prop];

            // Skip readOnly fields (server-managed, not in forms)

lib/Mojolicious/Plugin/Fondation/OpenAPI/Command/openapi.pm  view on Meta::CPAN

        };
    }
};
VALIDATORS

    $validators =~ s/SCHEMAS_PLACEHOLDER/$schemas_js/;

    # no_validator_js: replace the whole client-side validation logic with an
    # accept-everything stub, so only server-side OpenAPI validation applies.
    if ($permissive) {
        my $start_marker = "validate: function(schemaName, data) {\n";
        my $end_marker   = "\n    }\n};";
        my $s            = index($validators, $start_marker);
        my $e            = index($validators, $end_marker, $s);
        if ($s >= 0 && $e > $s) {
            substr($validators, $s + length($start_marker),
                $e - $s - length($start_marker),
                "        return { valid: true, errors: [] };\n");
        }
    }

lib/Mojolicious/Plugin/Fondation/OpenAPI/Command/openapi.pm  view on Meta::CPAN


=over

=item C<share/openapi.json>

OpenAPI 3.0.3 specification with schemas and CRUD paths. Loaded at
runtime by L<Mojolicious::Plugin::OpenAPI> for request validation.

=item C<public/js/validators.js>

Client-side validation (C<FondationValidators.validate()>) consumed
by L<Fondation::Asset> bundles.

=back

Options:

  --output FILE   Output path relative to $app->home (default: share/openapi.json)
  -y              Overwrite without confirmation prompt

=head1 CRUD PATHS

t/04-validators-js.t  view on Meta::CPAN

# ==========================================================================
# 1. validators.js structure
# ==========================================================================

{
    my $app = build_app;
    my $js  = generate_validators($app);

    like($js, qr/var FondationSchemas = \{\};/, 'FondationSchemas declaration');
    like($js, qr/window\.FondationValidators/,   'FondationValidators global');
    like($js, qr/validate: function/,            'validate function exists');
}

# ==========================================================================
# 2. Only 3 schemas in validators (Bar, Foo, FooCreate)
# ==========================================================================

{
    my $app = build_app;
    my $js  = generate_validators($app);

t/05-runtime.t  view on Meta::CPAN

                models => {
                    foo => {source => 'Foo'},
                },
            }},
            {'Fondation::TestOpenAPI' => {}},
            {'Fondation::OpenAPI' => {}},
        ],
    });

    my $c = $app->build_controller;
    ok(!$c->has_helper('openapi.validate'), 'openapi helper not registered without spec');
}

# ==========================================================================
# 2. Spec file exists → OpenAPI plugin loaded
# ==========================================================================

{
    my $tmpdir = tempdir(CLEANUP => 1);
    my $dbfile = "$tmpdir/test.db";
    my $app    = create_test_app($tmpdir);

t/05-runtime.t  view on Meta::CPAN

                models => {
                    foo => {source => 'Foo'},
                },
            }},
            {'Fondation::TestOpenAPI' => {}},
            {'Fondation::OpenAPI' => {}},
        ],
    });

    my $c = $app->build_controller;
    ok($c->has_helper('openapi.validate'), 'openapi helper registered with spec');
}

# ==========================================================================
# 3. Development mode → Swagger UI routes added
# ==========================================================================

{
    my $tmpdir = tempdir(CLEANUP => 1);
    my $dbfile = "$tmpdir/test.db";
    my $app    = create_test_app($tmpdir);



( run in 0.547 second using v1.01-cache-2.11-cpan-ad19def0cd9 )