ekwo-os 0.4.1
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.
- package/README.md +873 -0
- package/dist/args.d.ts +57 -0
- package/dist/args.d.ts.map +1 -0
- package/dist/args.js +134 -0
- package/dist/args.js.map +1 -0
- package/dist/assets/expected-objects.json +9432 -0
- package/dist/assets/migrations/20260911120000_core_companies.sql +260 -0
- package/dist/assets/migrations/20260911120100_accounts_journals.sql +211 -0
- package/dist/assets/migrations/20260911120200_contacts.sql +90 -0
- package/dist/assets/migrations/20260911120300_taxes.sql +146 -0
- package/dist/assets/migrations/20260911120400_entries.sql +338 -0
- package/dist/assets/migrations/20260911120500_documents.sql +279 -0
- package/dist/assets/migrations/20260911120600_payments_reconciliation.sql +251 -0
- package/dist/assets/migrations/20260911120700_bank.sql +178 -0
- package/dist/assets/migrations/20260911120800_analytics_attachments.sql +128 -0
- package/dist/assets/migrations/20260911120900_post_document.sql +279 -0
- package/dist/assets/migrations/20260911121000_reporting.sql +235 -0
- package/dist/assets/migrations/20260911121100_country_templates.sql +226 -0
- package/dist/assets/migrations/20260911121200_fec.sql +71 -0
- package/dist/assets/migrations/20260911130000_instance.sql +77 -0
- package/dist/assets/migrations/20260911130100_instance_members.sql +224 -0
- package/dist/assets/migrations/20260911140000_instance_admins.sql +112 -0
- package/dist/assets/migrations/20260911160000_tax_posting_templates_unique.sql +17 -0
- package/dist/assets/migrations/20260911170000_document_amount_paid.sql +82 -0
- package/dist/assets/migrations/20260911173000_post_payment.sql +122 -0
- package/dist/assets/migrations/20260911173100_sequence_counters_under_rls.sql +84 -0
- package/dist/assets/migrations/20260911183000_country_journal_defaults.sql +143 -0
- package/dist/assets/migrations/20260911193853_line_account_defaults.sql +274 -0
- package/dist/assets/migrations/20260911195054_products.sql +221 -0
- package/dist/assets/migrations/20260911210131_anon_surface.sql +85 -0
- package/dist/assets/migrations/20260912074712_country_packs.sql +318 -0
- package/dist/assets/migrations/20260912080311_report_code_and_region.sql +198 -0
- package/dist/assets/migrations/20260912081014_pack_certification_maintained.sql +31 -0
- package/dist/assets/migrations/20260912081015_pack_certification_backfill.sql +16 -0
- package/dist/assets/migrations/20260912090407_tax_report_boxes.sql +329 -0
- package/dist/assets/migrations/20260912091917_tax_on_base_value.sql +25 -0
- package/dist/assets/migrations/20260912091918_tax_engine_columns.sql +776 -0
- package/dist/assets/migrations/20260912094412_opening_and_closing.sql +759 -0
- package/dist/assets/migrations/20260912095825_charts_of_accounts.sql +326 -0
- package/dist/assets/migrations/20260912100412_financial_statements.sql +632 -0
- package/dist/assets/migrations/20260912104719_one_formula_evaluator.sql +209 -0
- package/dist/assets/migrations/20260912105720_entry_kind_appropriation.sql +26 -0
- package/dist/assets/migrations/20260912105721_appropriation_entry_kind.sql +444 -0
- package/dist/assets/migrations/20260912111751_document_rules.sql +274 -0
- package/dist/assets/migrations/20260912112132_cash_basis_vat_and_fx.sql +1189 -0
- package/dist/assets/migrations/20260913074512_modules.sql +493 -0
- package/dist/assets/migrations/20260913075903_asset_disposal_roles.sql +47 -0
- package/dist/assets/migrations/20260913083216_capabilities.sql +637 -0
- package/dist/assets/migrations/20260913083901_company_invitations.sql +262 -0
- package/dist/assets/migrations/20260913084402_user_preferences.sql +376 -0
- package/dist/assets/migrations/20260913084847_company_profile.sql +261 -0
- package/dist/assets/migrations/20260913085436_numbering_reads_the_pack.sql +235 -0
- package/dist/assets/migrations/20260913085932_api_keys.sql +303 -0
- package/dist/assets/migrations/20260913090216_fiscal_year_bounds.sql +159 -0
- package/dist/assets/migrations/20260913092527_entries_import.sql +219 -0
- package/dist/assets/migrations/20260913101536_null_safe_guards.sql +188 -0
- package/dist/assets/migrations/20260913102115_installer_is_named.sql +462 -0
- package/dist/assets/migrations/20260913102758_no_currency_default.sql +138 -0
- package/dist/assets/migrations/20260913103355_cash_basis_needs_a_box.sql +453 -0
- package/dist/assets/migrations/20260913104014_aged_balance_named_group.sql +79 -0
- package/dist/assets/migrations/20260913104232_foreign_key_indexes.sql +144 -0
- package/dist/assets/migrations/20260913105120_declared_no_reader.sql +41 -0
- package/dist/assets/migrations/20260913111407_pack_languages.sql +223 -0
- package/dist/assets/migrations/20260913112233_schema_comments_for_a_reader.sql +27 -0
- package/dist/assets/migrations/20260913114535_fec_opening_balances.sql +307 -0
- package/dist/assets/migrations/20260914103412_audit_log.sql +509 -0
- package/dist/assets/migrations/20260914111907_pack_upgrade.sql +428 -0
- package/dist/assets/migrations/20260914120500_rounding_reads_the_currency.sql +206 -0
- package/dist/assets/migrations/20260914121200_amounts_round_at_the_currency.sql +2403 -0
- package/dist/assets/migrations/20260914134325_schema_version_0_2_0.sql +36 -0
- package/dist/assets/migrations/20260914143915_accounts_in_use.sql +428 -0
- package/dist/assets/migrations/20260914144731_account_code_frozen.sql +99 -0
- package/dist/assets/migrations/20260914151207_schema_grants_its_own_rights.sql +284 -0
- package/dist/assets/migrations/20260914152840_pack_upgrade_records_its_own_line.sql +237 -0
- package/dist/assets/migrations/20260914163943_declaration_periodicity.sql +349 -0
- package/dist/assets/migrations/20260915094000_foreign_services_received.sql +37 -0
- package/dist/assets/migrations/20260915094500_mentions_read_a_foreign_service.sql +72 -0
- package/dist/assets/migrations/20260915153000_document_shares.sql +568 -0
- package/dist/assets/migrations/20260915160000_ec_sales_list.sql +181 -0
- package/dist/assets/migrations/20260915161842_pack_sources.sql +56 -0
- package/dist/assets/migrations/20260915170500_schema_version_0_3_0.sql +45 -0
- package/dist/assets/migrations/20260915174500_a_vat_category_is_a_code.sql +177 -0
- package/dist/assets/migrations/20260915180000_document_rule_references.sql +85 -0
- package/dist/assets/migrations/20260915181000_territories.sql +342 -0
- package/dist/assets/migrations/20260915181500_ec_sales_list_reads_the_territories.sql +222 -0
- package/dist/assets/migrations/20260915182000_intracom_triangular.sql +53 -0
- package/dist/assets/migrations/20260915182500_a_triangular_supply_says_reverse_charge.sql +99 -0
- package/dist/assets/migrations/20260915191200_a_document_knows_its_language.sql +633 -0
- package/dist/assets/migrations/20260915195000_a_price_that_holds_its_tax.sql +649 -0
- package/dist/assets/migrations/20260915200000_a_posting_names_its_boxes.sql +1004 -0
- package/dist/assets/migrations/20260916094500_a_company_files_more_than_one_declaration.sql +795 -0
- package/dist/assets/migrations/20260916103000_a_ledger_line_names_its_posting.sql +902 -0
- package/dist/assets/migrations/20260916123000_a_vocabulary_for_a_tax_that_is_not_a_vat.sql +144 -0
- package/dist/assets/migrations/20260916124000_a_box_can_be_a_rate_of_a_box.sql +525 -0
- package/dist/assets/migrations/20260916125000_a_tax_follows_the_territory.sql +1318 -0
- package/dist/assets/migrations/20260916126000_a_tax_point_and_its_exception.sql +1211 -0
- package/dist/assets/migrations/20260917090000_a_counterparty_that_learns.sql +561 -0
- package/dist/assets/migrations/20260917120000_what_the_money_pays.sql +545 -0
- package/dist/assets/migrations/20260917150000_a_filing_is_a_row.sql +488 -0
- package/dist/assets/migrations/20260917170000_when_it_is_due.sql +194 -0
- package/dist/assets/migrations/20260917180000_a_box_is_a_number_and_a_kind.sql +213 -0
- package/dist/assets/migrations/20260917190000_what_a_declaration_owes.sql +486 -0
- package/dist/assets/migrations/20260917200000_what_moved_after_it_went.sql +227 -0
- package/dist/assets/migrations/20260918090000_a_form_names_its_file.sql +27 -0
- package/dist/assets/migrations/20260918110000_a_deposit_and_what_came_back.sql +286 -0
- package/dist/assets/migrations/20260918113741_a_fourth_preset_is_named.sql +9 -0
- package/dist/assets/migrations/20260918113807_a_client_reads_and_hands_over.sql +96 -0
- package/dist/assets/migrations/20260918114322_two_definer_functions_check_their_caller.sql +75 -0
- package/dist/assets/migrations/20260918130000_every_company_somebody_keeps.sql +177 -0
- package/dist/assets/migrations/20260918140000_a_session_nobody_prepared.sql +40 -0
- package/dist/assets/migrations/20260918141107_a_line_keeps_the_tax_it_was_posted_with.sql +256 -0
- package/dist/assets/migrations/20260918141342_a_company_has_an_electronic_address.sql +66 -0
- package/dist/assets/migrations/20260918141605_an_invoice_reads_whole_from_the_views.sql +313 -0
- package/dist/assets/migrations/20260918141627_a_policy_asks_once.sql +132 -0
- package/dist/assets/migrations/20260918143352_a_suggestion_reads_the_words_once.sql +204 -0
- package/dist/assets/migrations/20260918143417_a_reference_of_the_caller_and_a_rehearsal.sql +115 -0
- package/dist/assets/migrations/20260918150712_a_company_leaves_with_its_books.sql +1119 -0
- package/dist/assets/migrations/20260918150931_a_statement_is_imported_once.sql +654 -0
- package/dist/assets/migrations/20260918161204_a_posted_document_does_not_move.sql +437 -0
- package/dist/assets/migrations/20260918161538_a_posted_entry_does_not_move.sql +252 -0
- package/dist/assets/migrations/20260918171946_an_entry_is_posted_by_post_entry.sql +289 -0
- package/dist/assets/migrations/20260918174312_schema_version_0_4_0.sql +53 -0
- package/dist/assets/modules/assets/module.json +13 -0
- package/dist/assets/modules/assets/supabase/migrations/20260913081447_assets.sql +1190 -0
- package/dist/assets/modules/assets/supabase/migrations/20260913104234_foreign_key_indexes.sql +47 -0
- package/dist/assets/modules/assets/supabase/migrations/20260913104500_assets_capabilities.sql +145 -0
- package/dist/assets/modules/assets/supabase/migrations/20260914122100_assets_round_at_the_currency.sql +564 -0
- package/dist/assets/modules/assets/supabase/migrations/20260914145012_assets_accounts_in_use.sql +37 -0
- package/dist/assets/modules/assets/supabase/migrations/20260914151530_assets_grants_its_own_rights.sql +63 -0
- package/dist/assets/modules/assets/supabase/migrations/20260918113912_assets_client_reads.sql +20 -0
- package/dist/assets/modules/assets/supabase/migrations/20260918150801_assets_leave_with_the_company.sql +41 -0
- package/dist/assets/modules/budgets/module.json +12 -0
- package/dist/assets/modules/budgets/supabase/migrations/20260913083012_budgets.sql +210 -0
- package/dist/assets/modules/budgets/supabase/migrations/20260913104233_foreign_key_indexes.sql +37 -0
- package/dist/assets/modules/budgets/supabase/migrations/20260913104501_budgets_capabilities.sql +72 -0
- package/dist/assets/modules/budgets/supabase/migrations/20260914122400_budgets_round_at_the_currency.sql +68 -0
- package/dist/assets/modules/budgets/supabase/migrations/20260914145048_budgets_accounts_in_use.sql +30 -0
- package/dist/assets/modules/budgets/supabase/migrations/20260914151812_budgets_grants_its_own_rights.sql +31 -0
- package/dist/assets/modules/budgets/supabase/migrations/20260918113954_budgets_client_reads.sql +20 -0
- package/dist/assets/modules/budgets/supabase/migrations/20260918150823_budgets_leave_with_the_company.sql +37 -0
- package/dist/assets/modules/schema/module.1.json +69 -0
- package/dist/assets/seed/00_currencies.sql +15 -0
- package/dist/assets/seed/00_territories.sql +280 -0
- package/dist/assets/seed/05_framework_generic.sql +110 -0
- package/dist/assets/seed/10_pack_be.sql +1284 -0
- package/dist/assets/seed/11_pack_fr.sql +1112 -0
- package/dist/assets/seed/12_pack_lu.sql +2484 -0
- package/dist/assets/seed/13_pack_ee.sql +733 -0
- package/dist/assets/seed/14_pack_gb.sql +796 -0
- package/dist/assets/seed/15_pack_us.sql +751 -0
- package/dist/assets/seed/90_demo_company.sql +368 -0
- package/dist/assets/seed/modules/assets/10_pack_be.sql +58 -0
- package/dist/assets/seed/modules/assets/11_pack_fr.sql +57 -0
- package/dist/assets/seed/modules/assets/14_pack_gb.sql +58 -0
- package/dist/assets/seed/modules/assets/15_pack_us.sql +60 -0
- package/dist/auth.d.ts +59 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +134 -0
- package/dist/auth.js.map +1 -0
- package/dist/bin.d.ts +6 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +8 -0
- package/dist/bin.js.map +1 -0
- package/dist/books.d.ts +60 -0
- package/dist/books.d.ts.map +1 -0
- package/dist/books.js +168 -0
- package/dist/books.js.map +1 -0
- package/dist/bootstrap.d.ts +236 -0
- package/dist/bootstrap.d.ts.map +1 -0
- package/dist/bootstrap.js +459 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/bundle.d.ts +27 -0
- package/dist/bundle.d.ts.map +1 -0
- package/dist/bundle.js +47 -0
- package/dist/bundle.js.map +1 -0
- package/dist/checklist.d.ts +35 -0
- package/dist/checklist.d.ts.map +1 -0
- package/dist/checklist.js +64 -0
- package/dist/checklist.js.map +1 -0
- package/dist/cli.d.ts +14 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +318 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/company.d.ts +59 -0
- package/dist/commands/company.d.ts.map +1 -0
- package/dist/commands/company.js +287 -0
- package/dist/commands/company.js.map +1 -0
- package/dist/commands/contact.d.ts +9 -0
- package/dist/commands/contact.d.ts.map +1 -0
- package/dist/commands/contact.js +82 -0
- package/dist/commands/contact.js.map +1 -0
- package/dist/commands/demo.d.ts +19 -0
- package/dist/commands/demo.d.ts.map +1 -0
- package/dist/commands/demo.js +72 -0
- package/dist/commands/demo.js.map +1 -0
- package/dist/commands/doctor.d.ts +12 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +68 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/document.d.ts +17 -0
- package/dist/commands/document.d.ts.map +1 -0
- package/dist/commands/document.js +217 -0
- package/dist/commands/document.js.map +1 -0
- package/dist/commands/init.d.ts +31 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +535 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.d.ts +24 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +128 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/migrate.d.ts +30 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +115 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/module.d.ts +32 -0
- package/dist/commands/module.d.ts.map +1 -0
- package/dist/commands/module.js +285 -0
- package/dist/commands/module.js.map +1 -0
- package/dist/commands/pack.d.ts +22 -0
- package/dist/commands/pack.d.ts.map +1 -0
- package/dist/commands/pack.js +481 -0
- package/dist/commands/pack.js.map +1 -0
- package/dist/commands/payment.d.ts +15 -0
- package/dist/commands/payment.d.ts.map +1 -0
- package/dist/commands/payment.js +97 -0
- package/dist/commands/payment.js.map +1 -0
- package/dist/commands/register.d.ts +20 -0
- package/dist/commands/register.d.ts.map +1 -0
- package/dist/commands/register.js +134 -0
- package/dist/commands/register.js.map +1 -0
- package/dist/commands/status.d.ts +8 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +134 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/whoami.d.ts +21 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +133 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/company.d.ts +16 -0
- package/dist/company.d.ts.map +1 -0
- package/dist/company.js +26 -0
- package/dist/company.js.map +1 -0
- package/dist/config.d.ts +24 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +50 -0
- package/dist/config.js.map +1 -0
- package/dist/connection.d.ts +79 -0
- package/dist/connection.d.ts.map +1 -0
- package/dist/connection.js +116 -0
- package/dist/connection.js.map +1 -0
- package/dist/context.d.ts +47 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +93 -0
- package/dist/context.js.map +1 -0
- package/dist/doctor.d.ts +45 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +448 -0
- package/dist/doctor.js.map +1 -0
- package/dist/grants.d.ts +88 -0
- package/dist/grants.d.ts.map +1 -0
- package/dist/grants.js +174 -0
- package/dist/grants.js.map +1 -0
- package/dist/identity.d.ts +54 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +132 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/inventory.d.ts +155 -0
- package/dist/inventory.d.ts.map +1 -0
- package/dist/inventory.js +303 -0
- package/dist/inventory.js.map +1 -0
- package/dist/migrations.d.ts +76 -0
- package/dist/migrations.d.ts.map +1 -0
- package/dist/migrations.js +226 -0
- package/dist/migrations.js.map +1 -0
- package/dist/module/read.d.ts +91 -0
- package/dist/module/read.d.ts.map +1 -0
- package/dist/module/read.js +172 -0
- package/dist/module/read.js.map +1 -0
- package/dist/output.d.ts +110 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +173 -0
- package/dist/output.js.map +1 -0
- package/dist/pack/certification.d.ts +27 -0
- package/dist/pack/certification.d.ts.map +1 -0
- package/dist/pack/certification.js +38 -0
- package/dist/pack/certification.js.map +1 -0
- package/dist/pack/compile.d.ts +75 -0
- package/dist/pack/compile.d.ts.map +1 -0
- package/dist/pack/compile.js +801 -0
- package/dist/pack/compile.js.map +1 -0
- package/dist/pack/filing.d.ts +48 -0
- package/dist/pack/filing.d.ts.map +1 -0
- package/dist/pack/filing.js +56 -0
- package/dist/pack/filing.js.map +1 -0
- package/dist/pack/read.d.ts +766 -0
- package/dist/pack/read.d.ts.map +1 -0
- package/dist/pack/read.js +2336 -0
- package/dist/pack/read.js.map +1 -0
- package/dist/pack/schema.d.ts +26 -0
- package/dist/pack/schema.d.ts.map +1 -0
- package/dist/pack/schema.js +181 -0
- package/dist/pack/schema.js.map +1 -0
- package/dist/pack/territories.d.ts +98 -0
- package/dist/pack/territories.d.ts.map +1 -0
- package/dist/pack/territories.js +0 -0
- package/dist/pack/territories.js.map +1 -0
- package/dist/pack/upgrade.d.ts +86 -0
- package/dist/pack/upgrade.d.ts.map +1 -0
- package/dist/pack/upgrade.js +76 -0
- package/dist/pack/upgrade.js.map +1 -0
- package/dist/pack/vat-codes.d.ts +273 -0
- package/dist/pack/vat-codes.d.ts.map +1 -0
- package/dist/pack/vat-codes.js +513 -0
- package/dist/pack/vat-codes.js.map +1 -0
- package/dist/profiles.d.ts +67 -0
- package/dist/profiles.d.ts.map +1 -0
- package/dist/profiles.js +187 -0
- package/dist/profiles.js.map +1 -0
- package/dist/prompt.d.ts +40 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +120 -0
- package/dist/prompt.js.map +1 -0
- package/dist/registry.d.ts +84 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +104 -0
- package/dist/registry.js.map +1 -0
- package/dist/rest.d.ts +81 -0
- package/dist/rest.d.ts.map +1 -0
- package/dist/rest.js +245 -0
- package/dist/rest.js.map +1 -0
- package/dist/schema.d.ts +15 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +15 -0
- package/dist/schema.js.map +1 -0
- package/dist/seeds.d.ts +27 -0
- package/dist/seeds.d.ts.map +1 -0
- package/dist/seeds.js +47 -0
- package/dist/seeds.js.map +1 -0
- package/dist/session.d.ts +39 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +92 -0
- package/dist/session.js.map +1 -0
- package/dist/sql.d.ts +48 -0
- package/dist/sql.d.ts.map +1 -0
- package/dist/sql.js +112 -0
- package/dist/sql.js.map +1 -0
- package/dist/status.d.ts +94 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +120 -0
- package/dist/status.js.map +1 -0
- package/dist/ui.d.ts +55 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +114 -0
- package/dist/ui.js.map +1 -0
- package/package.json +29 -0
- package/schema/output.1.json +613 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What this release defines, and what a database actually holds.
|
|
3
|
+
*
|
|
4
|
+
* `packages/cli/assets/expected-objects.json` is generated from the migrations
|
|
5
|
+
* by `scripts/generate-expected-objects.mjs` and travels inside the published
|
|
6
|
+
* package. It is an inventory, not a list kept by hand: a doctor whose
|
|
7
|
+
* expectations are typed out by a human drifts from the schema the first time
|
|
8
|
+
* somebody adds a table and forgets the list, and then it lies in both
|
|
9
|
+
* directions at once.
|
|
10
|
+
*
|
|
11
|
+
* Comparing it to a live catalogue answers two different questions. Something
|
|
12
|
+
* **missing** means the installation is behind or has been damaged — a
|
|
13
|
+
* migration that did not land, an object dropped by hand. Something **extra**
|
|
14
|
+
* means an operator added it: their table, their function, their business, and
|
|
15
|
+
* this reports it as information rather than as a fault.
|
|
16
|
+
*
|
|
17
|
+
* A policy is the exception. Row level security is the whole security model
|
|
18
|
+
* here, so a policy that is gone and a policy that was added to a table of
|
|
19
|
+
* this schema are both faults: the first opens nothing and closes everything,
|
|
20
|
+
* the second is a grant nobody reviewed.
|
|
21
|
+
*/
|
|
22
|
+
import { type GrantsSection } from './grants.js';
|
|
23
|
+
import type { SqlClient } from './sql.js';
|
|
24
|
+
export interface ExpectedColumn {
|
|
25
|
+
name: string;
|
|
26
|
+
type: string;
|
|
27
|
+
}
|
|
28
|
+
export interface ExpectedTable {
|
|
29
|
+
name: string;
|
|
30
|
+
columns: ExpectedColumn[];
|
|
31
|
+
}
|
|
32
|
+
export interface ExpectedFunction {
|
|
33
|
+
name: string;
|
|
34
|
+
/** `pg_get_function_identity_arguments`, so an overload is its own entry. */
|
|
35
|
+
arguments: string;
|
|
36
|
+
}
|
|
37
|
+
export interface ExpectedPolicy {
|
|
38
|
+
table: string;
|
|
39
|
+
name: string;
|
|
40
|
+
command: string;
|
|
41
|
+
}
|
|
42
|
+
export interface ExpectedTrigger {
|
|
43
|
+
table: string;
|
|
44
|
+
name: string;
|
|
45
|
+
}
|
|
46
|
+
export interface ExpectedType {
|
|
47
|
+
name: string;
|
|
48
|
+
kind: string;
|
|
49
|
+
labels?: string[];
|
|
50
|
+
}
|
|
51
|
+
export interface ExpectedSchema {
|
|
52
|
+
schema: string;
|
|
53
|
+
tables: ExpectedTable[];
|
|
54
|
+
views: string[];
|
|
55
|
+
functions: ExpectedFunction[];
|
|
56
|
+
policies: ExpectedPolicy[];
|
|
57
|
+
triggers: ExpectedTrigger[];
|
|
58
|
+
types: ExpectedType[];
|
|
59
|
+
/**
|
|
60
|
+
* Which of `anon`, `authenticated` and `service_role` may reach each of
|
|
61
|
+
* those objects, and with which verbs.
|
|
62
|
+
*
|
|
63
|
+
* Part of the inventory rather than a file of its own, because a privilege
|
|
64
|
+
* and the object it is on ship in the same migration: since
|
|
65
|
+
* `20260914151207` the schema grants its own rights by name instead of
|
|
66
|
+
* taking whatever a Supabase project's default privileges hand out, and a
|
|
67
|
+
* table added without its grants is exactly as broken as a table added
|
|
68
|
+
* without its policy.
|
|
69
|
+
*
|
|
70
|
+
* `doctor.ts` compares it separately from the categories above, because the
|
|
71
|
+
* rule is not the same: a missing grant is a fault, an extra one to `anon`
|
|
72
|
+
* is a fault, and an extra one to a signed-in user is worth saying out loud
|
|
73
|
+
* without failing a build.
|
|
74
|
+
*/
|
|
75
|
+
grants: GrantsSection;
|
|
76
|
+
}
|
|
77
|
+
export interface ExpectedModule extends ExpectedSchema {
|
|
78
|
+
code: string;
|
|
79
|
+
version: string;
|
|
80
|
+
}
|
|
81
|
+
export interface ExpectedObjects {
|
|
82
|
+
/** The schema version this inventory describes. */
|
|
83
|
+
schemaVersion: string | null;
|
|
84
|
+
/** The last migration it was generated from. */
|
|
85
|
+
migration: string | null;
|
|
86
|
+
socle: ExpectedSchema;
|
|
87
|
+
modules: ExpectedModule[];
|
|
88
|
+
}
|
|
89
|
+
/** One category, compared. Every entry is a printable key. */
|
|
90
|
+
export interface CategoryDiff {
|
|
91
|
+
missing: string[];
|
|
92
|
+
extra: string[];
|
|
93
|
+
/** Present on both sides and not the same: a column whose type moved. */
|
|
94
|
+
changed: string[];
|
|
95
|
+
}
|
|
96
|
+
export interface SectionComparison {
|
|
97
|
+
/** `socle`, or the module's code. */
|
|
98
|
+
code: string;
|
|
99
|
+
schema: string;
|
|
100
|
+
/**
|
|
101
|
+
* Whether this database carries the section at all. A module the operator
|
|
102
|
+
* never installed is not a fault, and nothing of it is required.
|
|
103
|
+
*/
|
|
104
|
+
installed: boolean;
|
|
105
|
+
tables: CategoryDiff;
|
|
106
|
+
columns: CategoryDiff;
|
|
107
|
+
views: CategoryDiff;
|
|
108
|
+
functions: CategoryDiff;
|
|
109
|
+
policies: CategoryDiff;
|
|
110
|
+
triggers: CategoryDiff;
|
|
111
|
+
types: CategoryDiff;
|
|
112
|
+
}
|
|
113
|
+
export interface CatalogueComparison {
|
|
114
|
+
/** Version the inventory describes. */
|
|
115
|
+
expectedVersion: string | null;
|
|
116
|
+
/** Version the database reports, which may be older or newer. */
|
|
117
|
+
databaseVersion: string | null;
|
|
118
|
+
sections: SectionComparison[];
|
|
119
|
+
missing: number;
|
|
120
|
+
extra: number;
|
|
121
|
+
changed: number;
|
|
122
|
+
/** Missing or extra policies on a table of this schema. Always a fault. */
|
|
123
|
+
policyFaults: number;
|
|
124
|
+
}
|
|
125
|
+
export declare class InventoryError extends Error {
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Where the inventory is.
|
|
129
|
+
*
|
|
130
|
+
* Published package: `dist/assets/expected-objects.json`, put there at build
|
|
131
|
+
* time by `scripts/copy-assets.mjs`. Checkout: `packages/cli/assets/`, which
|
|
132
|
+
* is the file the generator writes and the repository commits. The two
|
|
133
|
+
* candidates mirror `resolveBundleDir()`.
|
|
134
|
+
*/
|
|
135
|
+
export declare function resolveInventoryPath(): string | undefined;
|
|
136
|
+
/** The inventory this CLI ships, or `undefined` if it ships none. */
|
|
137
|
+
export declare function readExpectedObjects(path?: string | undefined): Promise<ExpectedObjects | undefined>;
|
|
138
|
+
/** The live grants of one schema, for the doctor's own check. */
|
|
139
|
+
export declare function readGrants(db: SqlClient, schema: string): Promise<GrantsSection>;
|
|
140
|
+
/** The schemas of an inventory this database actually carries. */
|
|
141
|
+
export declare function installedSections(db: SqlClient, expected: ExpectedObjects): Promise<ExpectedSchema[]>;
|
|
142
|
+
/**
|
|
143
|
+
* The inventory against the live catalogue.
|
|
144
|
+
*
|
|
145
|
+
* The database's own schema version is read and reported but never gates the
|
|
146
|
+
* comparison: an installation older than the CLI is exactly when this is worth
|
|
147
|
+
* running, and refusing to look would be refusing the case.
|
|
148
|
+
*/
|
|
149
|
+
export declare function compareCatalogue(db: SqlClient, expected: ExpectedObjects): Promise<CatalogueComparison>;
|
|
150
|
+
/** Every difference of one section, as printable lines. */
|
|
151
|
+
export declare function describeDifferences(section: SectionComparison): {
|
|
152
|
+
faults: string[];
|
|
153
|
+
information: string[];
|
|
154
|
+
};
|
|
155
|
+
//# sourceMappingURL=inventory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inventory.d.ts","sourceRoot":"","sources":["../src/inventory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What this release defines, and what a database actually holds.
|
|
3
|
+
*
|
|
4
|
+
* `packages/cli/assets/expected-objects.json` is generated from the migrations
|
|
5
|
+
* by `scripts/generate-expected-objects.mjs` and travels inside the published
|
|
6
|
+
* package. It is an inventory, not a list kept by hand: a doctor whose
|
|
7
|
+
* expectations are typed out by a human drifts from the schema the first time
|
|
8
|
+
* somebody adds a table and forgets the list, and then it lies in both
|
|
9
|
+
* directions at once.
|
|
10
|
+
*
|
|
11
|
+
* Comparing it to a live catalogue answers two different questions. Something
|
|
12
|
+
* **missing** means the installation is behind or has been damaged — a
|
|
13
|
+
* migration that did not land, an object dropped by hand. Something **extra**
|
|
14
|
+
* means an operator added it: their table, their function, their business, and
|
|
15
|
+
* this reports it as information rather than as a fault.
|
|
16
|
+
*
|
|
17
|
+
* A policy is the exception. Row level security is the whole security model
|
|
18
|
+
* here, so a policy that is gone and a policy that was added to a table of
|
|
19
|
+
* this schema are both faults: the first opens nothing and closes everything,
|
|
20
|
+
* the second is a grant nobody reviewed.
|
|
21
|
+
*/
|
|
22
|
+
import { existsSync } from 'node:fs';
|
|
23
|
+
import { readFile } from 'node:fs/promises';
|
|
24
|
+
import { fileURLToPath } from 'node:url';
|
|
25
|
+
import { describeGrants } from './grants.js';
|
|
26
|
+
import { scalar } from './sql.js';
|
|
27
|
+
export class InventoryError extends Error {
|
|
28
|
+
}
|
|
29
|
+
const CATEGORIES = ['tables', 'columns', 'views', 'functions', 'policies', 'triggers', 'types'];
|
|
30
|
+
/**
|
|
31
|
+
* Where the inventory is.
|
|
32
|
+
*
|
|
33
|
+
* Published package: `dist/assets/expected-objects.json`, put there at build
|
|
34
|
+
* time by `scripts/copy-assets.mjs`. Checkout: `packages/cli/assets/`, which
|
|
35
|
+
* is the file the generator writes and the repository commits. The two
|
|
36
|
+
* candidates mirror `resolveBundleDir()`.
|
|
37
|
+
*/
|
|
38
|
+
export function resolveInventoryPath() {
|
|
39
|
+
const candidates = [
|
|
40
|
+
new URL('./assets/expected-objects.json', import.meta.url),
|
|
41
|
+
new URL('../assets/expected-objects.json', import.meta.url),
|
|
42
|
+
];
|
|
43
|
+
for (const candidate of candidates) {
|
|
44
|
+
const path = fileURLToPath(candidate);
|
|
45
|
+
if (existsSync(path))
|
|
46
|
+
return path;
|
|
47
|
+
}
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
/** The inventory this CLI ships, or `undefined` if it ships none. */
|
|
51
|
+
export async function readExpectedObjects(path = resolveInventoryPath()) {
|
|
52
|
+
if (path === undefined)
|
|
53
|
+
return undefined;
|
|
54
|
+
const raw = await readFile(path, 'utf8');
|
|
55
|
+
let parsed;
|
|
56
|
+
try {
|
|
57
|
+
parsed = JSON.parse(raw);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
throw new InventoryError(`inventory_invalid: ${path} — ${error.message}`);
|
|
61
|
+
}
|
|
62
|
+
if (parsed.socle === undefined || !Array.isArray(parsed.modules)) {
|
|
63
|
+
throw new InventoryError(`inventory_invalid: ${path} — no socle or no modules`);
|
|
64
|
+
}
|
|
65
|
+
return parsed;
|
|
66
|
+
}
|
|
67
|
+
// ------------------------------------------------------------------ reading
|
|
68
|
+
/** The same categories, read from a live catalogue. */
|
|
69
|
+
async function readSchema(db, schema) {
|
|
70
|
+
const tables = await db.query(`select c.relname as name
|
|
71
|
+
from pg_class c join pg_namespace n on n.oid = c.relnamespace
|
|
72
|
+
where n.nspname = $1 and c.relkind in ('r', 'p')
|
|
73
|
+
order by c.relname`, [schema]);
|
|
74
|
+
const columns = await db.query(`select c.relname as table_name, a.attname as name,
|
|
75
|
+
format_type(a.atttypid, a.atttypmod) as type
|
|
76
|
+
from pg_attribute a
|
|
77
|
+
join pg_class c on c.oid = a.attrelid
|
|
78
|
+
join pg_namespace n on n.oid = c.relnamespace
|
|
79
|
+
where n.nspname = $1 and c.relkind in ('r', 'p')
|
|
80
|
+
and a.attnum > 0 and not a.attisdropped
|
|
81
|
+
order by c.relname, a.attname`, [schema]);
|
|
82
|
+
const views = await db.query(`select c.relname as name
|
|
83
|
+
from pg_class c join pg_namespace n on n.oid = c.relnamespace
|
|
84
|
+
where n.nspname = $1 and c.relkind in ('v', 'm')
|
|
85
|
+
order by c.relname`, [schema]);
|
|
86
|
+
const functions = await db.query(`select p.proname as name, pg_get_function_identity_arguments(p.oid) as arguments
|
|
87
|
+
from pg_proc p join pg_namespace n on n.oid = p.pronamespace
|
|
88
|
+
where n.nspname = $1
|
|
89
|
+
order by p.proname, pg_get_function_identity_arguments(p.oid)`, [schema]);
|
|
90
|
+
const policies = await db.query(`select c.relname as table_name, p.polname as name,
|
|
91
|
+
case p.polcmd when 'r' then 'select' when 'a' then 'insert'
|
|
92
|
+
when 'w' then 'update' when 'd' then 'delete'
|
|
93
|
+
else 'all' end as command
|
|
94
|
+
from pg_policy p
|
|
95
|
+
join pg_class c on c.oid = p.polrelid
|
|
96
|
+
join pg_namespace n on n.oid = c.relnamespace
|
|
97
|
+
where n.nspname = $1
|
|
98
|
+
order by c.relname, p.polname`, [schema]);
|
|
99
|
+
const triggers = await db.query(`select c.relname as table_name, t.tgname as name
|
|
100
|
+
from pg_trigger t
|
|
101
|
+
join pg_class c on c.oid = t.tgrelid
|
|
102
|
+
join pg_namespace n on n.oid = c.relnamespace
|
|
103
|
+
where n.nspname = $1 and not t.tgisinternal
|
|
104
|
+
order by c.relname, t.tgname`, [schema]);
|
|
105
|
+
const types = await db.query(`select t.typname as name,
|
|
106
|
+
case t.typtype when 'e' then 'enum' when 'd' then 'domain' else 'composite' end as kind,
|
|
107
|
+
case when t.typtype = 'e' then (
|
|
108
|
+
select array_agg(e.enumlabel order by e.enumsortorder)
|
|
109
|
+
from pg_enum e where e.enumtypid = t.oid
|
|
110
|
+
) end as labels
|
|
111
|
+
from pg_type t join pg_namespace n on n.oid = t.typnamespace
|
|
112
|
+
where n.nspname = $1 and t.typtype in ('e', 'd', 'c')
|
|
113
|
+
and (t.typtype <> 'c'
|
|
114
|
+
or exists (select 1 from pg_class c where c.oid = t.typrelid and c.relkind = 'c'))
|
|
115
|
+
order by t.typname`, [schema]);
|
|
116
|
+
const grants = await describeGrants((sql, params) => db.query(sql, params), schema);
|
|
117
|
+
return {
|
|
118
|
+
schema,
|
|
119
|
+
tables: tables.map((t) => ({
|
|
120
|
+
name: t.name,
|
|
121
|
+
columns: columns
|
|
122
|
+
.filter((c) => c.table_name === t.name)
|
|
123
|
+
.map((c) => ({ name: c.name, type: c.type })),
|
|
124
|
+
})),
|
|
125
|
+
views: views.map((v) => v.name),
|
|
126
|
+
functions: functions.map((f) => ({ name: f.name, arguments: f.arguments })),
|
|
127
|
+
policies: policies.map((p) => ({ table: p.table_name, name: p.name, command: p.command })),
|
|
128
|
+
triggers: triggers.map((t) => ({ table: t.table_name, name: t.name })),
|
|
129
|
+
types: types.map((t) => ({
|
|
130
|
+
name: t.name,
|
|
131
|
+
kind: t.kind,
|
|
132
|
+
...(t.labels === null ? {} : { labels: t.labels }),
|
|
133
|
+
})),
|
|
134
|
+
grants,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
/** The live grants of one schema, for the doctor's own check. */
|
|
138
|
+
export async function readGrants(db, schema) {
|
|
139
|
+
return describeGrants((sql, params) => db.query(sql, params), schema);
|
|
140
|
+
}
|
|
141
|
+
/** The schemas of an inventory this database actually carries. */
|
|
142
|
+
export async function installedSections(db, expected) {
|
|
143
|
+
const carried = await installedModules(db);
|
|
144
|
+
return [expected.socle, ...expected.modules.filter((m) => carried.has(m.code))];
|
|
145
|
+
}
|
|
146
|
+
// ---------------------------------------------------------------- comparing
|
|
147
|
+
function emptyDiff() {
|
|
148
|
+
return { missing: [], extra: [], changed: [] };
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Two keyed sets, compared.
|
|
152
|
+
*
|
|
153
|
+
* `key` is what identifies the object — a name, or a name and a signature —
|
|
154
|
+
* and `same` says whether two objects that share a key are still the same
|
|
155
|
+
* thing. Both sides are already sorted, and the keys are what is printed.
|
|
156
|
+
*/
|
|
157
|
+
function diff(expected, actual, key, same = () => undefined) {
|
|
158
|
+
const out = emptyDiff();
|
|
159
|
+
const here = new Map(actual.map((item) => [key(item), item]));
|
|
160
|
+
const there = new Set(expected.map(key));
|
|
161
|
+
for (const item of expected) {
|
|
162
|
+
const found = here.get(key(item));
|
|
163
|
+
if (found === undefined) {
|
|
164
|
+
out.missing.push(key(item));
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
const difference = same(item, found);
|
|
168
|
+
if (difference !== undefined)
|
|
169
|
+
out.changed.push(difference);
|
|
170
|
+
}
|
|
171
|
+
for (const item of actual) {
|
|
172
|
+
if (!there.has(key(item)))
|
|
173
|
+
out.extra.push(key(item));
|
|
174
|
+
}
|
|
175
|
+
return out;
|
|
176
|
+
}
|
|
177
|
+
const functionKey = (f) => `${f.name}(${f.arguments})`;
|
|
178
|
+
const policyKey = (p) => `${p.table}.${p.name}`;
|
|
179
|
+
const triggerKey = (t) => `${t.table}.${t.name}`;
|
|
180
|
+
/** One section of the inventory against one schema of the database. */
|
|
181
|
+
function compareSchema(code, expected, actual) {
|
|
182
|
+
const tables = diff(expected.tables, actual.tables, (t) => t.name);
|
|
183
|
+
// Columns, triggers and policies are compared on the tables this schema
|
|
184
|
+
// defines. On a table the operator added, they are the operator's business,
|
|
185
|
+
// and the table itself is already reported as extra.
|
|
186
|
+
const known = new Set(expected.tables.map((t) => t.name));
|
|
187
|
+
const expectedColumns = expected.tables.flatMap((t) => t.columns.map((c) => ({ key: `${t.name}.${c.name}`, type: c.type })));
|
|
188
|
+
const actualColumns = actual.tables
|
|
189
|
+
.filter((t) => known.has(t.name))
|
|
190
|
+
.flatMap((t) => t.columns.map((c) => ({ key: `${t.name}.${c.name}`, type: c.type })));
|
|
191
|
+
const columns = diff(expectedColumns, actualColumns, (c) => c.key, (a, b) => (a.type === b.type ? undefined : `${a.key} is ${b.type}, expected ${a.type}`));
|
|
192
|
+
// A column missing because its whole table is missing is already said once.
|
|
193
|
+
columns.missing = columns.missing.filter((c) => !tables.missing.includes(c.split('.')[0] ?? ''));
|
|
194
|
+
const policies = diff(expected.policies, actual.policies.filter((p) => known.has(p.table)), policyKey, (a, b) => (a.command === b.command ? undefined : `${policyKey(a)} is ${b.command}, expected ${a.command}`));
|
|
195
|
+
policies.missing = policies.missing.filter((p) => !tables.missing.includes(p.split('.')[0] ?? ''));
|
|
196
|
+
const triggers = diff(expected.triggers, actual.triggers.filter((t) => known.has(t.table)), triggerKey);
|
|
197
|
+
triggers.missing = triggers.missing.filter((t) => !tables.missing.includes(t.split('.')[0] ?? ''));
|
|
198
|
+
return {
|
|
199
|
+
code,
|
|
200
|
+
schema: expected.schema,
|
|
201
|
+
installed: true,
|
|
202
|
+
tables,
|
|
203
|
+
columns,
|
|
204
|
+
views: diff(expected.views, actual.views, (v) => v),
|
|
205
|
+
functions: diff(expected.functions, actual.functions, functionKey),
|
|
206
|
+
policies,
|
|
207
|
+
triggers,
|
|
208
|
+
types: diff(expected.types, actual.types, (t) => t.name, (a, b) => {
|
|
209
|
+
if (a.kind !== b.kind)
|
|
210
|
+
return `${a.name} is a ${b.kind}, expected a ${a.kind}`;
|
|
211
|
+
const expectedLabels = (a.labels ?? []).join(', ');
|
|
212
|
+
const actualLabels = (b.labels ?? []).join(', ');
|
|
213
|
+
if (expectedLabels === actualLabels)
|
|
214
|
+
return undefined;
|
|
215
|
+
return `${a.name} holds (${actualLabels}), expected (${expectedLabels})`;
|
|
216
|
+
}),
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
/** A section this database does not carry: nothing of it is required. */
|
|
220
|
+
function notInstalled(code, schema) {
|
|
221
|
+
return {
|
|
222
|
+
code,
|
|
223
|
+
schema,
|
|
224
|
+
installed: false,
|
|
225
|
+
tables: emptyDiff(),
|
|
226
|
+
columns: emptyDiff(),
|
|
227
|
+
views: emptyDiff(),
|
|
228
|
+
functions: emptyDiff(),
|
|
229
|
+
policies: emptyDiff(),
|
|
230
|
+
triggers: emptyDiff(),
|
|
231
|
+
types: emptyDiff(),
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
/** The module codes this database carries, whatever this CLI ships. */
|
|
235
|
+
async function installedModules(db) {
|
|
236
|
+
const present = await scalar(db, `select to_regclass('public.modules') is not null`);
|
|
237
|
+
if (present !== true)
|
|
238
|
+
return new Set();
|
|
239
|
+
const rows = await db.query('select code from modules');
|
|
240
|
+
return new Set(rows.map((r) => r.code));
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* The inventory against the live catalogue.
|
|
244
|
+
*
|
|
245
|
+
* The database's own schema version is read and reported but never gates the
|
|
246
|
+
* comparison: an installation older than the CLI is exactly when this is worth
|
|
247
|
+
* running, and refusing to look would be refusing the case.
|
|
248
|
+
*/
|
|
249
|
+
export async function compareCatalogue(db, expected) {
|
|
250
|
+
// Asked in two steps on purpose: naming the function in a `case` still
|
|
251
|
+
// resolves it, so a database that does not have it would raise rather than
|
|
252
|
+
// answer, and that database is one this is meant to report on.
|
|
253
|
+
const hasVersion = await scalar(db, `select to_regprocedure('public.ekwo_schema_version()') is not null`);
|
|
254
|
+
const databaseVersion = hasVersion === true ? ((await scalar(db, 'select ekwo_schema_version()')) ?? null) : null;
|
|
255
|
+
const sections = [compareSchema('socle', expected.socle, await readSchema(db, 'public'))];
|
|
256
|
+
const carried = await installedModules(db);
|
|
257
|
+
for (const module of expected.modules) {
|
|
258
|
+
if (!carried.has(module.code)) {
|
|
259
|
+
sections.push(notInstalled(module.code, module.schema));
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
sections.push(compareSchema(module.code, module, await readSchema(db, module.schema)));
|
|
263
|
+
}
|
|
264
|
+
let missing = 0;
|
|
265
|
+
let extra = 0;
|
|
266
|
+
let changed = 0;
|
|
267
|
+
let policyFaults = 0;
|
|
268
|
+
for (const section of sections) {
|
|
269
|
+
for (const category of CATEGORIES) {
|
|
270
|
+
missing += section[category].missing.length;
|
|
271
|
+
extra += section[category].extra.length;
|
|
272
|
+
changed += section[category].changed.length;
|
|
273
|
+
}
|
|
274
|
+
policyFaults +=
|
|
275
|
+
section.policies.missing.length + section.policies.extra.length + section.policies.changed.length;
|
|
276
|
+
}
|
|
277
|
+
return { expectedVersion: expected.schemaVersion, databaseVersion, sections, missing, extra, changed, policyFaults };
|
|
278
|
+
}
|
|
279
|
+
/** Every difference of one section, as printable lines. */
|
|
280
|
+
export function describeDifferences(section) {
|
|
281
|
+
const faults = [];
|
|
282
|
+
const information = [];
|
|
283
|
+
const where = section.code === 'socle' ? '' : `${section.code}: `;
|
|
284
|
+
for (const category of CATEGORIES) {
|
|
285
|
+
const { missing, extra, changed } = section[category];
|
|
286
|
+
for (const item of missing)
|
|
287
|
+
faults.push(`${where}missing ${singular(category)} ${item}`);
|
|
288
|
+
for (const item of changed)
|
|
289
|
+
faults.push(`${where}${item}`);
|
|
290
|
+
for (const item of extra) {
|
|
291
|
+
const line = `${where}extra ${singular(category)} ${item}`;
|
|
292
|
+
if (category === 'policies')
|
|
293
|
+
faults.push(line);
|
|
294
|
+
else
|
|
295
|
+
information.push(line);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return { faults, information };
|
|
299
|
+
}
|
|
300
|
+
function singular(category) {
|
|
301
|
+
return category === 'policies' ? 'policy' : category.replace(/s$/, '');
|
|
302
|
+
}
|
|
303
|
+
//# sourceMappingURL=inventory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inventory.js","sourceRoot":"","sources":["../src/inventory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,cAAc,EAAsB,MAAM,aAAa,CAAC;AAEjE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAmHlC,MAAM,OAAO,cAAe,SAAQ,KAAK;CAAG;AAE5C,MAAM,UAAU,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,CAAU,CAAC;AAEzG;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,UAAU,GAAG;QACjB,IAAI,GAAG,CAAC,gCAAgC,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QAC1D,IAAI,GAAG,CAAC,iCAAiC,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;KAC5D,CAAC;IACF,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;QACtC,IAAI,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;IACpC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,qEAAqE;AACrE,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAAI,GAAG,oBAAoB,EAAE;IACrE,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACzC,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACzC,IAAI,MAAuB,CAAC;IAC5B,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAoB,CAAC;IAC9C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,cAAc,CAAC,sBAAsB,IAAI,MAAO,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;IACvF,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACjE,MAAM,IAAI,cAAc,CAAC,sBAAsB,IAAI,2BAA2B,CAAC,CAAC;IAClF,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,6EAA6E;AAE7E,uDAAuD;AACvD,KAAK,UAAU,UAAU,CAAC,EAAa,EAAE,MAAc;IACrD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,KAAK,CAC3B;;;yBAGqB,EACrB,CAAC,MAAM,CAAC,CACT,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,KAAK,CAC5B;;;;;;;oCAOgC,EAChC,CAAC,MAAM,CAAC,CACT,CAAC;IACF,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,KAAK,CAC1B;;;yBAGqB,EACrB,CAAC,MAAM,CAAC,CACT,CAAC;IACF,MAAM,SAAS,GAAG,MAAM,EAAE,CAAC,KAAK,CAC9B;;;oEAGgE,EAChE,CAAC,MAAM,CAAC,CACT,CAAC;IACF,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,KAAK,CAC7B;;;;;;;;oCAQgC,EAChC,CAAC,MAAM,CAAC,CACT,CAAC;IACF,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,KAAK,CAC7B;;;;;mCAK+B,EAC/B,CAAC,MAAM,CAAC,CACT,CAAC;IACF,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,KAAK,CAC1B;;;;;;;;;;yBAUqB,EACrB,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;IAEpF,OAAO;QACL,MAAM;QACN,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACzB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,OAAO,EAAE,OAAO;iBACb,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,IAAI,CAAC;iBACtC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;SAChD,CAAC,CAAC;QACH,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAC/B,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;QAC3E,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1F,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACtE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACvB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,GAAG,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;SACnD,CAAC,CAAC;QACH,MAAM;KACP,CAAC;AACJ,CAAC;AAED,iEAAiE;AACjE,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,EAAa,EAAE,MAAc;IAC5D,OAAO,cAAc,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;AACxE,CAAC;AAED,kEAAkE;AAClE,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,EAAa,EACb,QAAyB;IAEzB,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClF,CAAC;AAED,6EAA6E;AAE7E,SAAS,SAAS;IAChB,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;AACjD,CAAC;AAED;;;;;;GAMG;AACH,SAAS,IAAI,CACX,QAAsB,EACtB,MAAoB,EACpB,GAAwB,EACxB,OAA2C,GAAG,EAAE,CAAC,SAAS;IAE1D,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;IACxB,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9D,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAEzC,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QAClC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;YAC5B,SAAS;QACX,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACrC,IAAI,UAAU,KAAK,SAAS;YAAE,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC7D,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,WAAW,GAAG,CAAC,CAAmB,EAAU,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,GAAG,CAAC;AACjF,MAAM,SAAS,GAAG,CAAC,CAAiB,EAAU,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;AACxE,MAAM,UAAU,GAAG,CAAC,CAAkB,EAAU,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;AAE1E,uEAAuE;AACvE,SAAS,aAAa,CAAC,IAAY,EAAE,QAAwB,EAAE,MAAsB;IACnF,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAEnE,wEAAwE;IACxE,4EAA4E;IAC5E,qDAAqD;IACrD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,MAAM,eAAe,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CACpD,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CACrE,CAAC;IACF,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM;SAChC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;SAChC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACxF,MAAM,OAAO,GAAG,IAAI,CAClB,eAAe,EACf,aAAa,EACb,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,EACZ,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,cAAc,CAAC,CAAC,IAAI,EAAE,CAAC,CACxF,CAAC;IACF,4EAA4E;IAC5E,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAEjG,MAAM,QAAQ,GAAG,IAAI,CACnB,QAAQ,CAAC,QAAQ,EACjB,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EACjD,SAAS,EACT,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,cAAc,CAAC,CAAC,OAAO,EAAE,CAAC,CAC3G,CAAC;IACF,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAEnG,MAAM,QAAQ,GAAG,IAAI,CACnB,QAAQ,CAAC,QAAQ,EACjB,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EACjD,UAAU,CACX,CAAC;IACF,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAEnG,OAAO;QACL,IAAI;QACJ,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,SAAS,EAAE,IAAI;QACf,MAAM;QACN,OAAO;QACP,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACnD,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC;QAClE,QAAQ;QACR,QAAQ;QACR,KAAK,EAAE,IAAI,CACT,QAAQ,CAAC,KAAK,EACd,MAAM,CAAC,KAAK,EACZ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EACb,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACP,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI;gBAAE,OAAO,GAAG,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,IAAI,gBAAgB,CAAC,CAAC,IAAI,EAAE,CAAC;YAC/E,MAAM,cAAc,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnD,MAAM,YAAY,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjD,IAAI,cAAc,KAAK,YAAY;gBAAE,OAAO,SAAS,CAAC;YACtD,OAAO,GAAG,CAAC,CAAC,IAAI,WAAW,YAAY,gBAAgB,cAAc,GAAG,CAAC;QAC3E,CAAC,CACF;KACF,CAAC;AACJ,CAAC;AAED,yEAAyE;AACzE,SAAS,YAAY,CAAC,IAAY,EAAE,MAAc;IAChD,OAAO;QACL,IAAI;QACJ,MAAM;QACN,SAAS,EAAE,KAAK;QAChB,MAAM,EAAE,SAAS,EAAE;QACnB,OAAO,EAAE,SAAS,EAAE;QACpB,KAAK,EAAE,SAAS,EAAE;QAClB,SAAS,EAAE,SAAS,EAAE;QACtB,QAAQ,EAAE,SAAS,EAAE;QACrB,QAAQ,EAAE,SAAS,EAAE;QACrB,KAAK,EAAE,SAAS,EAAE;KACnB,CAAC;AACJ,CAAC;AAED,uEAAuE;AACvE,KAAK,UAAU,gBAAgB,CAAC,EAAa;IAC3C,MAAM,OAAO,GAAG,MAAM,MAAM,CAAU,EAAE,EAAE,kDAAkD,CAAC,CAAC;IAC9F,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,IAAI,GAAG,EAAE,CAAC;IACvC,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,KAAK,CAAmB,0BAA0B,CAAC,CAAC;IAC1E,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,EAAa,EACb,QAAyB;IAEzB,uEAAuE;IACvE,2EAA2E;IAC3E,+DAA+D;IAC/D,MAAM,UAAU,GAAG,MAAM,MAAM,CAC7B,EAAE,EACF,oEAAoE,CACrE,CAAC;IACF,MAAM,eAAe,GACnB,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,MAAM,CAAS,EAAE,EAAE,8BAA8B,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEpG,MAAM,QAAQ,GAAG,CAAC,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,UAAU,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IAE1F,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAC3C,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QACtC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;YACxD,SAAS;QACX,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACzF,CAAC;IAED,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;YAClC,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;YAC5C,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;YACxC,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;QAC9C,CAAC;QACD,YAAY;YACV,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC;IACtG,CAAC;IAED,OAAO,EAAE,eAAe,EAAE,QAAQ,CAAC,aAAa,EAAE,eAAe,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;AACvH,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,mBAAmB,CAAC,OAA0B;IAI5D,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,IAAI,CAAC;IAElE,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;QAClC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QACtD,KAAK,MAAM,IAAI,IAAI,OAAO;YAAE,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,WAAW,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QACzF,KAAK,MAAM,IAAI,IAAI,OAAO;YAAE,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,GAAG,IAAI,EAAE,CAAC,CAAC;QAC3D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,GAAG,KAAK,SAAS,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC;YAC3D,IAAI,QAAQ,KAAK,UAAU;gBAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;;gBAC1C,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;AACjC,CAAC;AAED,SAAS,QAAQ,CAAC,QAAqC;IACrD,OAAO,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AACzE,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The migration runner.
|
|
3
|
+
*
|
|
4
|
+
* It applies `supabase/migrations/*.sql` in filename order and records what
|
|
5
|
+
* it did in `supabase_migrations.schema_migrations`, **in the format the
|
|
6
|
+
* Supabase CLI uses** — same schema, same table, same three columns, version
|
|
7
|
+
* being the timestamp prefix of the filename. That is the whole point: an
|
|
8
|
+
* installation set up with `ekwo init` can later be pushed to with
|
|
9
|
+
* `supabase db push`, and one set up with `supabase db push` can be brought
|
|
10
|
+
* forward with `ekwo migrate`. The two are interchangeable because they read
|
|
11
|
+
* and write the same history.
|
|
12
|
+
*
|
|
13
|
+
* Each file is applied inside one transaction together with its history row,
|
|
14
|
+
* so a migration that fails halfway leaves neither half-applied schema nor a
|
|
15
|
+
* history row that lies. Re-running resumes at the file that failed.
|
|
16
|
+
*/
|
|
17
|
+
import type { SqlClient } from './sql.js';
|
|
18
|
+
export interface Migration {
|
|
19
|
+
/** `20260911120000` — the timestamp prefix, and the primary key of the history. */
|
|
20
|
+
version: string;
|
|
21
|
+
/** `core_companies` — what the Supabase CLI stores as `name`. */
|
|
22
|
+
name: string;
|
|
23
|
+
/** `20260911120000_core_companies.sql` */
|
|
24
|
+
file: string;
|
|
25
|
+
/** Absolute path on disk. */
|
|
26
|
+
path: string;
|
|
27
|
+
}
|
|
28
|
+
/** Parses a migration filename, or returns `undefined` if it is not one. */
|
|
29
|
+
export declare function parseMigrationFile(file: string): Omit<Migration, 'path'> | undefined;
|
|
30
|
+
/** Every migration in `dir`, in the order they must be applied. */
|
|
31
|
+
export declare function listMigrations(dir: string): Promise<Migration[]>;
|
|
32
|
+
/**
|
|
33
|
+
* The history table, created exactly as the Supabase CLI creates it.
|
|
34
|
+
*
|
|
35
|
+
* The columns are added one by one with `if not exists`, so this is safe on a
|
|
36
|
+
* project the Supabase CLI has already touched, whichever version of it.
|
|
37
|
+
*/
|
|
38
|
+
export declare function ensureHistory(db: SqlClient): Promise<void>;
|
|
39
|
+
/** Versions already recorded, oldest first. */
|
|
40
|
+
export declare function appliedVersions(db: SqlClient): Promise<string[]>;
|
|
41
|
+
export interface Gap {
|
|
42
|
+
applied: string[];
|
|
43
|
+
pending: Migration[];
|
|
44
|
+
/** Versions in the database that this release does not ship — a newer installation. */
|
|
45
|
+
unknown: string[];
|
|
46
|
+
}
|
|
47
|
+
/** What separates the database from the migrations this CLI carries. */
|
|
48
|
+
export declare function migrationGap(db: SqlClient, all: Migration[]): Promise<Gap>;
|
|
49
|
+
/**
|
|
50
|
+
* Applies one migration and records it, atomically.
|
|
51
|
+
*
|
|
52
|
+
* The file is sent as a single command string, so Postgres runs it as one
|
|
53
|
+
* unit inside the transaction we opened. No file in this repository opens a
|
|
54
|
+
* transaction of its own, and none may: the runner owns that.
|
|
55
|
+
*/
|
|
56
|
+
export declare function applyMigration(db: SqlClient, migration: Migration): Promise<void>;
|
|
57
|
+
export interface ApplyResult {
|
|
58
|
+
applied: Migration[];
|
|
59
|
+
alreadyApplied: number;
|
|
60
|
+
}
|
|
61
|
+
/** Applies every pending migration, in order, reporting each one as it lands. */
|
|
62
|
+
export declare function applyMigrations(db: SqlClient, all: Migration[], onApplied?: (migration: Migration) => void): Promise<ApplyResult>;
|
|
63
|
+
/**
|
|
64
|
+
* Splits a SQL file into statements, for the `statements` column only.
|
|
65
|
+
*
|
|
66
|
+
* Execution never goes through this: the file is handed to Postgres whole.
|
|
67
|
+
* The column is what `supabase migration repair` and `supabase db diff` read
|
|
68
|
+
* back, so it should hold statements rather than one blob — but a mistake
|
|
69
|
+
* here can only make that column less pretty, never break an installation.
|
|
70
|
+
*
|
|
71
|
+
* Handles line and block comments, single- and double-quoted literals,
|
|
72
|
+
* `E''` backslash escapes and dollar quoting with tags, which is what the
|
|
73
|
+
* function bodies in this schema are made of.
|
|
74
|
+
*/
|
|
75
|
+
export declare function splitStatements(sql: string): string[];
|
|
76
|
+
//# sourceMappingURL=migrations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../src/migrations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C,MAAM,WAAW,SAAS;IACxB,mFAAmF;IACnF,OAAO,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;CACd;AAID,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,GAAG,SAAS,CAMpF;AAED,mEAAmE;AACnE,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAWtE;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAWhE;AAED,+CAA+C;AAC/C,wBAAsB,eAAe,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAKtE;AAED,MAAM,WAAW,GAAG;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,uFAAuF;IACvF,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wEAAwE;AACxE,wBAAsB,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAUhF;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAavF;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,iFAAiF;AACjF,wBAAsB,eAAe,CACnC,EAAE,EAAE,SAAS,EACb,GAAG,EAAE,SAAS,EAAE,EAChB,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,GACzC,OAAO,CAAC,WAAW,CAAC,CAOtB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAiHrD"}
|