Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ Metrics/BlockLength:
- 'packages/forest_admin_datasource_toolkit/lib/forest_admin_datasource_toolkit/components/query/filter_factory.rb'
- 'packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/action/base_action.rb'
- 'packages/forest_admin_datasource_mongoid/lib/forest_admin_datasource_mongoid/collection.rb'
- 'packages/forest_admin_rails/lib/tasks/forest_admin_rails_tasks.rake'
- 'packages/forest_admin_rpc_agent/lib/forest_admin_rpc_agent/routes/sse.rb'
- 'packages/forest_admin_rpc_agent/lib/forest_admin_rpc_agent/http/router.rb'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class AgentFactory
include ForestAdminDatasourceCustomizer::DSL::DatasourceHelpers

attr_reader :customizer, :container, :has_env_secret
attr_accessor :schema_only_mode

def setup(options)
@options = options
Expand Down Expand Up @@ -55,7 +56,22 @@ def build
# Reset route cache to ensure routes are computed with all customizations
ForestAdminAgent::Http::Router.reset_cached_routes!

send_schema
if @schema_only_mode
generate_schema_only
else
send_schema
end
end

def generate_schema_only
datasource = @container.resolve(:datasource)
schema = build_schema(datasource)
schema_path = Facades::Container.cache(:schema_path)

write_schema_file(schema_path, schema)
@logger.log('Info', "[ForestAdmin] Schema generated successfully at #{schema_path}")

schema
end

def reload!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,83 @@ module Builder
expect(described_class.instance.container.resolve(:datasource))
.to eq(described_class.instance.customizer.datasource({}))
end

it 'calls send_schema when schema_only_mode is false' do
instance = described_class.instance
instance.schema_only_mode = false
allow(instance).to receive(:send_schema)

instance.build

expect(instance).to have_received(:send_schema)
end

it 'calls generate_schema_only when schema_only_mode is true' do
instance = described_class.instance
instance.schema_only_mode = true
allow(instance).to receive(:generate_schema_only)

instance.build

expect(instance).to have_received(:generate_schema_only)
ensure
instance.schema_only_mode = false
end
end

describe 'generate_schema_only' do
it 'generates schema and writes to default path' do
instance = described_class.instance
logger = instance_spy(Services::LoggerService)
instance.instance_variable_set(:@logger, logger)

datasource = instance_double(ForestAdminDatasourceToolkit::Datasource)
instance.container.register(:datasource, datasource)

allow(Facades::Container).to receive(:cache).with(:schema_path).and_return('/path/to/schema.json')
allow(ForestAdminAgent::Utils::Schema::SchemaEmitter).to receive_messages(generate: [], meta: {})
allow(File).to receive(:write)

instance.generate_schema_only

expect(File).to have_received(:write).with('/path/to/schema.json', anything)
expect(logger).to have_received(:log).with('Info', '[ForestAdmin] Schema generated successfully at /path/to/schema.json')
end

it 'returns the generated schema' do
instance = described_class.instance
logger = instance_spy(Services::LoggerService)
instance.instance_variable_set(:@logger, logger)

datasource = instance_double(ForestAdminDatasourceToolkit::Datasource)
instance.container.register(:datasource, datasource)

allow(Facades::Container).to receive(:cache).with(:schema_path).and_return('/path/to/schema.json')
allow(ForestAdminAgent::Utils::Schema::SchemaEmitter).to receive_messages(generate: [{ name: 'Book' }], meta: { liana: 'forest-rails' })
allow(File).to receive(:write)

result = instance.generate_schema_only

expect(result).to eq({ meta: { liana: 'forest-rails' }, collections: [{ name: 'Book' }] })
end

it 'does not call post_schema' do
instance = described_class.instance
logger = instance_spy(Services::LoggerService)
instance.instance_variable_set(:@logger, logger)

datasource = instance_double(ForestAdminDatasourceToolkit::Datasource)
instance.container.register(:datasource, datasource)

allow(Facades::Container).to receive(:cache).with(:schema_path).and_return('/path/to/schema.json')
allow(ForestAdminAgent::Utils::Schema::SchemaEmitter).to receive_messages(generate: [], meta: {})
allow(File).to receive(:write)
allow(instance).to receive(:post_schema)

instance.generate_schema_only

expect(instance).not_to have_received(:post_schema)
end
end

describe 'reload!' do
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,43 @@
# desc "Explaining what the task does"
# task :forest_admin_rails do
# # Task goes here
# end
namespace :forest_admin do
namespace :schema do
desc 'Generate the Forest Admin schema file without starting the server or sending it to the API'
task generate: :environment do
require 'forest_admin_agent'

debug_mode = ENV['debug'] == 'true'

puts '[ForestAdmin] Starting schema generation...'

# Force eager loading of all models
Rails.application.eager_load!

# Check if create_agent.rb exists
create_agent_path = Rails.root.join('lib', 'forest_admin_rails', 'create_agent.rb')
unless File.exist?(create_agent_path)
puts '[ForestAdmin] Error: create_agent.rb not found at lib/forest_admin_rails/create_agent.rb'
puts '[ForestAdmin] Run `rails generate forest_admin_rails <ENV_SECRET>` to create it.'
exit 1
end

# Setup the agent factory
agent_factory = ForestAdminAgent::Builder::AgentFactory.instance
agent_factory.setup(ForestAdminRails.config)

# Enable schema-only mode (generates schema without sending to API)
agent_factory.schema_only_mode = true

# Load and execute the create_agent.rb file
require create_agent_path

# Call setup! which will generate the schema
begin
ForestAdminRails::CreateAgent.setup!
puts '[ForestAdmin] Schema generation completed!'
rescue StandardError => e
puts "[ForestAdmin] Error during schema generation: #{e.message}"
puts e.backtrace.first(10).join("\n") if debug_mode
exit 1
end
end
end
end
Loading