From c1e085c20901d958ba04e88e26121d6e3fb5d702 Mon Sep 17 00:00:00 2001 From: Thomas Guillet Date: Fri, 19 Apr 2024 11:33:35 +0200 Subject: [PATCH 1/6] test: test content --- dev-test/config.yml | 1251 ++++++++++++++++++++++++++++++++++--------- dev-test/index.html | 252 +-------- 2 files changed, 1000 insertions(+), 503 deletions(-) diff --git a/dev-test/config.yml b/dev-test/config.yml index 31c7f12ae97a..088744f146a7 100644 --- a/dev-test/config.yml +++ b/dev-test/config.yml @@ -1,281 +1,1006 @@ +locale: fr backend: - name: test-repo + name: github-large + repo: betagouv/aides-jeunes + branch: main + commit_messages: + create: Crée {{slug}} + update: Met à jour {{slug}} + delete: Supprime {{slug}} + uploadMedia: Nouvelle image {{path}} + deleteMedia: Suppression de l'image {{path}} -site_url: https://example.com +media_folder: public/img/institutions +public_folder: img/institutions +slug: + encoding: ascii + clean_accents: true + +# local_backend: true publish_mode: editorial_workflow -media_folder: assets/uploads -collections: # A list of collections the CMS should be able to edit - - name: 'posts' # Used in routes, ie.: /admin/collections/:slug/edit - label: 'Posts' # Used in the UI - label_singular: 'Post' # Used in the UI, ie: "New Post" - description: > - The description is a great place for tone setting, high level information, and editing - guidelines that are specific to a collection. - folder: '_posts' - slug: '{{year}}-{{month}}-{{day}}-{{slug}}' - summary: '{{title}} -- {{year}}/{{month}}/{{day}}' - create: true # Allow users to create new documents in this collection - view_filters: - - label: Posts With Index - field: title - pattern: 'This is post #' - - label: Posts Without Index - field: title - pattern: front matter post - - label: Drafts - field: draft - pattern: true - view_groups: - - label: Year - field: date - pattern: \d{4} - - label: Drafts - field: draft - fields: # The fields each document in this collection have - - { label: 'Title', name: 'title', widget: 'string', tagname: 'h1' } - - { label: 'Draft', name: 'draft', widget: 'boolean', default: false } - - { - label: 'Publish Date', - name: 'date', - widget: 'datetime', - date_format: 'YYYY-MM-DD', - time_format: 'HH:mm', - format: 'YYYY-MM-DD HH:mm', - } - - label: 'Cover Image' - name: 'image' - widget: 'image' - required: false - tagname: '' +root: ../../.. - - { label: 'Body', name: 'body', widget: 'markdown', hint: 'Main content goes here.' } +patterns: + pattern_url: &pattern_url + - "^(https?:\/\/)" + - 'Le champ doit contenir une url valide' - - name: 'restaurants' # Used in routes, ie.: /admin/collections/:slug/edit - label: 'Restaurants' # Used in the UI - label_singular: 'Restaurant' # Used in the UI, ie: "New Post" - description: > - Restaurants is an entry type used for testing galleries, relations and other widgets. - The tests must be written in such way that adding new fields does not affect previous flows. - folder: '_restaurants' - slug: '{{year}}-{{month}}-{{day}}-{{slug}}' - summary: '{{title}} -- {{year}}/{{month}}/{{day}}' - create: true # Allow users to create new documents in this collection - fields: # The fields each document in this collection have - - { label: 'Title', name: 'title', widget: 'string', tagname: 'h1' } - - { label: 'Body', name: 'body', widget: 'markdown', hint: 'Main content goes here.' } - - { name: 'gallery', widget: 'image', choose_url: true, media_library: {config: {multiple: true, max_files: 999}}} - - { name: 'post', widget: relation, collection: posts, multiple: true, search_fields: [ "title" ], display_fields: [ "title" ], value_field: "{{slug}}", filters: [ {field: "draft", values: [false]} ] } - - name: authors - label: Authors - label_singular: 'Author' +fields: + field_empty: &field_empty + widget: object + fields: + - label: empty + widget: hidden + name: empty + field_numeric_value: &field_numeric_value + label: Valeur + name: value + widget: number + step: -1 + field_numeric_operator: &field_numeric_operator + label: Opérateur + name: operator + widget: select + options: + - label: Supérieur à + value: '>' + - label: Supérieur ou égal à + value: '>=' + - label: Égal à + value: '=' + - label: Inférieur à + value: '<' + - label: Inférieur ou égal à + value: '<=' + field_number: &field_number + widget: object + fields: + - *field_numeric_operator + - *field_numeric_value + field_age: &field_age + <<: *field_number + label: Age + name: age + field_regions: &field_regions + label: Condition géographique régionale + name: regions + widget: object + fields: + - label: Régions + name: values + widget: select + multiple: true + options: + - label: Auvergne-Rhône-Alpes + value: '84' + - label: Bourgogne-Franche-Comté + value: '27' + - label: Bretagne + value: '53' + - label: Centre-Val de Loire + value: '24' + - label: Corse + value: '94' + - label: Grand Est + value: '44' + - label: Guadeloupe + value: '01' + - label: Guyane + value: '03' + - label: Hauts-de-France + value: '32' + - label: Île-de-France + value: '11' + - label: La Réunion + value: '04' + - label: Martinique + value: '02' + - label: Mayotte + value: '06' + - label: Normandie + value: '28' + - label: Nouvelle-Aquitaine + value: '75' + - label: Occitanie + value: '76' + - label: Pays de la Loire + value: '52' + - label: Provence-Alpes-Côte d'Azur + value: '93' + field_departements: &field_departements + label: Condition géographique départementale + name: departements + widget: object + fields: + - label: Code des départements + name: values + widget: list + hint: Pour saisir plusieurs département, séparez les codes des départements par une virgule. + field_epcis: &field_epcis + label: Condition géographique d'EPCI + name: epcis + widget: object + fields: + - label: Code SIREN des EPCI + name: values + widget: list + hint: Pour saisir plusieurs EPCI, séparez les codes SIREN par une virgule. + field_excluded_epcis: &field_excluded_epcis + label: Condition d'exclusion géographique d'EPCI + name: excluded_epcis + widget: object + fields: + - label: Code SIREN des EPCI exclues + name: values + widget: list + hint: Pour saisir plusieurs EPCI, séparez les codes SIREN par une virgule. + field_communes: &field_communes + label: Condition géographique communale + name: communes + widget: object + fields: + - label: Code INSEE des communes + name: values widget: list + hint: Pour saisir plusieurs communes, séparez les codes INSEE des communes par une virgule. + field_boursier: &field_boursier + <<: *field_empty + label: Boursier + name: boursier + field_mention_baccalaureat: &field_mention_baccalaureat + label: Mention au bac + name: mention_baccalaureat + widget: object + fields: + - label: Valeurs + name: values + widget: select + multiple: true + options: + - label: Mention assez bien + value: mention_assez_bien + - label: Mention bien + value: mention_bien + - label: Mention très bien + value: mention_tres_bien + - label: Mention très bien avec félicitations du jury + value: mention_tres_bien_felicitations_jury + - label: Autre + value: non_renseignee + field_select_regime_securite_sociale: &field_select_regime_securite_sociale + widget: select + multiple: true + required: false + options: + - label: Régime général + value: regime_general + - label: Régime agricole + value: regime_agricole + - label: Autres régimes + value: autres_regimes + field_regime_securite_sociale: &field_regime_securite_sociale + label: Régime de sécurité sociale + name: regime_securite_sociale + widget: object + fields: + - <<: *field_select_regime_securite_sociale + label: Inclus + name: includes + - <<: *field_select_regime_securite_sociale + label: Exclus + name: excludes + field_quotient_familial: &field_quotient_familial + label: Quotient familial + name: quotient_familial + widget: object + fields: + - *field_numeric_operator + - <<: *field_numeric_value + label: Montant + - label: Période + name: period + widget: select + options: + - label: Par mois + value: month + - label: Par an + value: year + field_taux_incapacite: &field_taux_incapacite + label: Taux d'incapacité + name: taux_incapacite + fields: + - *field_numeric_operator + - <<: *field_numeric_value + label: Taux + value_type: float + min: 0 + max: 1 + hint: Le taux est exprimé par un nombre entre 0 et 1. Exemple 0.8 pour 80%. + field_formation_sanitaire_social: &field_formation_sanitaire_social + <<: *field_empty + label: En formation sanitaire et sociale + name: formation_sanitaire_social + field_beneficiaire_rsa: &field_beneficiaire_rsa + <<: *field_empty + label: Bénéficiaire RSA + name: beneficiaire_rsa + field_attached_to_institution: &field_attached_to_institution + <<: *field_empty + label: Habite dans le périmètre géographique l'institution (uniquement commune, epci, département ou région) + name: attached_to_institution + field_exclude_epcis: &field_exclude_epcis + <<: *field_empty + label: Exclure les EPCI + name: exclude_epcis + field_select_statut_occupation_logement: &field_select_statut_occupation_logement + widget: select + multiple: true + required: false + options: + - label: Propriétaire primo-accédant + value: primo_accedant + - label: Propriétaire + value: proprietaire + - label: Locataire + value: locataire_vide + - label: Locataire de meublé ou hotel + value: locataire_meuble + - label: 'Logé gratuitement' + value: loge_gratuitement + - label: 'Locataire foyer' + value: locataire_foyer + - label: 'Sans domicile stable' + value: sans_domicile + field_statut_occupation_logement: &field_statut_occupation_logement + label: Statut d'occupation du logement + name: statut_occupation_logement + widget: object + fields: + - <<: *field_select_statut_occupation_logement + label: Inclus + name: includes + - <<: *field_select_statut_occupation_logement + label: Exclus + name: excludes + field_difficultes_acces_ou_frais_logement: &field_difficultes_acces_ou_frais_logement + <<: *field_empty + label: Difficultés importantes pour accéder à un logement ou pour payer les frais liés à un logement + name: difficultes_acces_ou_frais_logement + field_agence_travail_temporaire: &field_agence_travail_temporaire + <<: *field_empty + name: agence_travail_temporaire + label: Intérimaire d'une agence de travail temporaire + # common fields + field_benefit_image: &field_benefit_image + label: Logo + name: imgSrc + widget: hidden + allow_multiple: false + required: false + public_folder: 'img/benefits' + media_folder: '/public/img/benefits' + hint: Utile si vous voulez afficher le logo de l'aide à la place de l'image de l'institution. + field_benefit_name: &field_benefit_name + label: Nom de l'aide + name: label + widget: string + field_institution: &field_institution + label: Institution + name: institution + widget: relation + collection: institutions + value_field: '{{slug}}' + display_fields: ['{{name}}'] + search_fields: [slug, name] + allow_multiple: false + options_length: -1 + filter: + label: 'Type :' + target: 'type' + hint: Si votre institution n'apparaît pas dans la liste, vous pouvez [l'ajouter ici](https://contribuer-aides-jeunes.netlify.app/admin/#/collections/institutions/new). + field_description: &field_description + label: Courte description + name: description + widget: description + field_unmodeled_conditions: &field_unmodeled_conditions + label: Conditions non prises en compte par le simulateur + label_singular: Condition non prise en compte par le simulateur + hint: | + Certains critères d'éligibilité ne peuvent pas être demandés (trop précis) + ni pris en compte (trop complexe) dans le cadre d'un simulateur grand public. + Cette liste permet d'informer les usagers sur ces critères supplémentaires. + Par exemple : Signer un contrat d’engagement réciproque (CER) avec votre département + ou un Projet Personnalisé d’Accès à l’Emploi (PPAE) avec France travail. + name: conditions + widget: list + collapsed: false + field: + label: Texte + name: text + widget: string + pattern: + [ + '\.$', + "La condition doit commencer par un verbe à l'infinitif et se terminer par un point", + ] + field_link_information: &field_link_information + label: Lien vers la page d'informations de référence + hint: Vers un site institutionnel de préférence (par exemple, pour les aides nationales il s'agit souvent de service-public.fr) + name: link + widget: string + pattern: *pattern_url + field_link_instructions: &field_link_instructions + label: Lien vers des instructions à suivre + name: instructions + widget: string + pattern: *pattern_url + required: false + required_group: cta + field_link_form: &field_link_form + label: Lien vers un formulaire à imprimer + name: form + widget: string + pattern: *pattern_url + required: false + required_group: cta + field_link_teleservice: &field_link_teleservice + label: Lien vers un téléservice + hint: Lorsqu'il y a la possibilité de faire la démarche en ligne. + name: teleservice + widget: string + pattern: *pattern_url + required: false + required_group: cta + field_definite_article: &field_definite_article + label: Article défini + name: prefix + hint: | + L'ajout d'un article défini permet la formation de phrase grammaticalement correcte. + Par exemple, dans la phrase « Comment obtenir l'aide exceptionnelle ? », on choisit le préfixe « l' ». Pour « Comment obtenir les aides au logement ? », on choisit le préfixe « les ». + widget: select + required: true + options: [le, la, les, l’, une, un, l’aide] + field_result_type: &field_result_type + label: Type du résultat + name: type + default: 'float' + widget: select + options: + - label: Valeur numérique + value: float + - label: Éligibilité (Oui / Non) + value: bool + - label: Autre + value: mixed + field_result_unit: &field_result_unit + label: Unité lorsque le type de résultat est une valeur numérique + hint: Il s'agit de spécifier l'unité du montant. + name: unit + widget: select + default: € + required: false + options: + - label: € + value: € + - label: '%' + value: '%' + - label: séances + value: séances + field_amount_legend: &field_amount_legend + label: Légende associée à la valeur numérique + hint: Cette légende permet d'ajouter des informations complémentaires sur le montant. Par exemple, si vous écrivez "maximum" dans ce champ, et que vous avez indiqué "200 €" en montant, cela affichera "200 € maximum". + name: legend + widget: string + required: false + field_amount_reliability: &field_amount_reliability + label: Niveau de fiabilité lorsque le résultat est un montant + name: floorAt + widget: select + required: false + options: + - label: 10 (pour arrondir à la dizaine inférieure) + value: 10 + - label: 1 (pour l'euro inférieur) + value: 1 + - label: 0.01 (pour éviter l'arrondi) + value: 0.01 + field_specific_interest: &field_specific_interest + label: Faut-il limiter l'affichage de l'aide en fonction d'un intérêt particulier ? + name: interestFlag + hint: | + En fin de parcours, des questions sont posées pour connaitre certains intérêts des usagers. + Cela permet d'éviter d'afficher certaines aides qui ne seraient pas pertinentes pour les usagers. + widget: select + required: false + options: + - label: Oui, l'afficher en cas d'intérêt pour le BAFA ou le BAFD. + value: _interetBafa + - label: Oui, l'afficher en cas d'intérêt pour passer le permis de conduire. + value: _interetPermisDeConduire + - label: Oui, l'afficher en cas d'intérêt pour faire des études à l'étranger. + value: _interetEtudesEtranger + - label: Oui, l'afficher en cas d'intérêt pour faire une formation dans le sanitaire et social. + value: _interetAidesSanitaireSocial + field_openfisca_linked_entity: &field_openfisca_linked_entity + label: Entité de rattachement de la variable dans OpenFisca + name: entity + widget: select + hint: Cette variable fait le lien avec le moteur de calculs. Tant que vous ne savez pas quoi y indiquer, nous recommandons de laisser Ménage. + options: + - label: Famille + value: familles + - label: Foyer Fiscal + value: foyers_fiscaux + - label: Individu + value: individus + - label: Ménage + value: menages + field_openfisca_period: &field_openfisca_period + label: Période de la variable dans OpenFisca + name: openfiscaPeriod + widget: select + hint: Cette variable fait le lien avec le moteur de calculs. Tant que vous ne savez pas quoi y indiquer, nous recommandons de laisser Mois. + options: + - label: Mois + value: thisMonth + - label: Année + value: thisYear + field_benefit_max_amount: &field_benefit_max_amount + label: Montant maximal de l'aide + name: montant + widget: number + required: false + step: -1 + field_benefit_amount_periodicity: &field_benefit_amount_periodicity + label: "Périodicité de l'aide" + name: periodicite + widget: select + hint: Cette variable permet de définir la fréquence de versement de l'aide. + required: true + default: autre + options: + - label: Ponctuelle + value: ponctuelle + - label: Mensuelle (/ mois) + value: mensuelle + - label: Annuelle (/ an) + value: annuelle + - label: Autre + value: autre + field_eligibility_profile: &field_eligibility_profile + label: profil d'éligibilité + label_singular: profils d'éligibilité + hint: Cette aide est-elle destinée à des publics spécifiques ? (lycéen(ne)s, apprenti(e)s, en recherche d'emploi, etc.) + name: profils + widget: list + collapsed: false + default: [] + types: + - label: Lycéen ou lycéenne + name: lyceen + widget: object fields: - - { label: 'Name', name: 'name', widget: 'string', hint: 'First and Last' } - - { label: 'Description', name: 'description', widget: 'markdown' } - - - name: 'faq' # Used in routes, ie.: /admin/collections/:slug/edit - label: 'FAQ' # Used in the UI - folder: '_faqs' - create: true # Allow users to create new documents in this collection - fields: # The fields each document in this collection have - - { label: 'Question', name: 'title', widget: 'string', tagname: 'h1' } - - { label: 'Answer', name: 'body', widget: 'markdown' } - - - name: 'settings' - label: 'Settings' - delete: false # Prevent users from deleting documents in this collection - editor: - preview: false - files: - - name: 'general' - label: 'Site Settings' - file: '_data/settings.json' - description: 'General Site Settings' + - label: Conditions à satisfaire simultanément + label_singular: Condition à satisfaire + name: conditions + default: [] + widget: list + collapsed: false + types: + - *field_age + - *field_boursier + - *field_formation_sanitaire_social + - label: Année d'étude + name: annee_etude + widget: object + fields: + - label: Valeurs + name: values + widget: select + multiple: true + options: + - label: CAP - 1ère année + value: cap_1 + - label: CAP - 2ème année + value: cap_2 + - label: Seconde + value: seconde + - label: Première + value: premiere + - label: Terminale + value: terminale + - label: Autre + value: autre + - label: Dans l'enseignement supérieur + name: enseignement_superieur + widget: object fields: - - { label: 'Global title', name: 'site_title', widget: 'string' } - - label: 'Post Settings' - name: posts - widget: 'object' - fields: - - { - label: 'Number of posts on frontpage', - name: front_limit, - widget: number, - min: 1, - max: 10, - } - - { label: 'Default Author', name: author, widget: string } - - { - label: 'Default Thumbnail', - name: thumb, - widget: image, - class: 'thumb', - required: false, - } - - - name: 'authors' - label: 'Authors' - file: '_data/authors.yml' - description: 'Author descriptions' + - label: Conditions à satisfaire simultanément + label_singular: Condition à satisfaire + name: conditions + default: [] + widget: list + collapsed: false + types: + - *field_age + - *field_boursier + - *field_mention_baccalaureat + - *field_formation_sanitaire_social + - label: Année d'étude + name: annee_etude + widget: object + fields: + - label: Valeurs + name: values + widget: select + multiple: true + options: + - label: BTS + value: bts_1 + - label: BUT + value: but_1 + - label: CPGE + value: cpge_1 + - label: Licence - 1ère année + value: licence_1 + - label: Licence - 2ème année + value: licence_2 + - label: Licence - 3ème année + value: licence_3 + - label: Master - 1ère année + value: master_1 + - label: Master - 2ème année + value: master_2 + - label: Doctorat - 1ère année + value: doctorat_1 + - label: Doctorat - 2ème année + value: doctorat_2 + - label: Doctorat - 3ème année + value: doctorat_3 + - label: Autre + value: autre + - label: Scolarisé ou scolarisée + name: etudiant + widget: object + fields: + - label: Conditions à satisfaire simultanément + label_singular: Condition à satisfaire + name: conditions + default: [] + widget: list + collapsed: false + types: + - *field_age + - *field_formation_sanitaire_social + - *field_boursier + - label: Année d'étude + name: annee_etude + widget: object + fields: + - label: Valeurs + name: values + widget: select + multiple: true + options: + - label: CAP - 1ère année + value: cap_1 + - label: CAP - 2ème année + value: cap_2 + - label: Seconde + value: seconde + - label: Première + value: premiere + - label: Terminale + value: terminale + - label: BTS + value: bts_1 + - label: BUT + value: but_1 + - label: CPGE + value: cpge_1 + - label: Licence - 1ère année + value: licence_1 + - label: Licence - 2ème année + value: licence_2 + - label: Licence - 3ème année + value: licence_3 + - label: Master - 1ère année + value: master_1 + - label: Master - 2ème année + value: master_2 + - label: Doctorat - 1ère année + value: doctorat_1 + - label: Doctorat - 2ème année + value: doctorat_2 + - label: Doctorat - 3ème année + value: doctorat_3 + - label: Autre + value: autre + - label: Stagiaire + name: stagiaire + widget: object + fields: + - label: Conditions à satisfaire simultanément + label_singular: Condition à satisfaire + name: conditions + default: [] + widget: list + collapsed: false + types: + - *field_formation_sanitaire_social + - *field_age + - *field_boursier + - label: Apprenti ou apprentie + name: apprenti + widget: object + fields: + - label: Conditions à satisfaire simultanément + label_singular: Condition à satisfaire + name: conditions + default: [] + widget: list + collapsed: false + types: + - *field_formation_sanitaire_social + - *field_age + - *field_boursier + - label: En contrat de professionnalisation + name: professionnalisation + widget: object + fields: + - label: Conditions à satisfaire simultanément + label_singular: Condition à satisfaire + name: conditions + default: [] + widget: list + collapsed: false + types: + - *field_formation_sanitaire_social + - *field_age + - label: En recherche d'emploi + name: chomeur + widget: object fields: - - name: authors - label: Authors - label_singular: 'Author' + - label: Conditions à satisfaire simultanément + label_singular: Condition à satisfaire + name: conditions + default: [] widget: list - fields: - - { label: 'Name', name: 'name', widget: 'string', hint: 'First and Last' } - - { label: 'Description', name: 'description', widget: 'markdown' } + collapsed: false + types: + - *field_age + - label: Salarié ou salariée + name: salarie + widget: object + fields: + - label: Conditions à satisfaire simultanément + label_singular: Condition à satisfaire + name: conditions + default: [] + widget: list + collapsed: false + types: + - *field_age + - label: Travailleur indépendant ou travailleuse indépendante + name: independant + widget: object + fields: + - label: Conditions à satisfaire simultanément + label_singular: Condition à satisfaire + name: conditions + default: [] + widget: list + collapsed: false + types: + - *field_age + - label: En service civique + name: service_civique + widget: object + fields: + - label: Conditions à satisfaire simultanément + label_singular: Condition à satisfaire + name: conditions + default: [] + widget: list + collapsed: false + types: + - *field_age + - label: Bénéficiaire RSA + name: beneficiaire_rsa + widget: object + fields: + - label: Conditions à satisfaire simultanément + label_singular: Condition à satisfaire + name: conditions + default: [] + widget: list + collapsed: false + types: + - *field_age + - label: En situation de handicap + name: situation_handicap + widget: object + fields: + - label: Conditions à satisfaire simultanément + label_singular: Condition à satisfaire + name: conditions + default: [] + widget: list + collapsed: false + types: + - *field_taux_incapacite + - label: Inactif ou inactive + name: inactif + widget: object + fields: + - label: Conditions à satisfaire simultanément + label_singular: Condition à satisfaire + name: conditions + default: [] + widget: list + collapsed: false + types: + - *field_age + field_private_benefit: &field_private_benefit + label: Masquer l'aide + name: private + required: false + widget: hidden + field_benefit_partial_support: &field_benefit_partial_support + label: L'aide ne couvre qu'une partie des frais + name: participation + widget: hidden + field_benefit_id: &field_benefit_id + name: id + widget: hidden + field_benefit_source: &field_benefit_source + name: source + widget: hidden + field_not_operator: &field_not_operator + name: not + widget: hidden + field_voluntary_conditions: &field_voluntary_conditions + label: Conditions bénévoles à satisfaire + name: voluntary_conditions + hint: Un lien dynamique vers la plateforme jeveuxaider.gouv.fr s'ajoutera à la suite de la dernière condition pour orienter l'utilisateur vers des organismes de bénévolat à proximité + required: false + widget: list + collapsed: false + field: + label: Texte + name: text + widget: string + pattern: + [ + '\.$', + "La condition doit commencer par un verbe à l'infinitif et se terminer par un point", + ] + field_teleservice_prefill: &field_teleservice_prefill + name: teleservicePrefill + widget: hidden + # champs propre aux aides javascript + field_general_conditions: &field_general_conditions + label: Conditions générales à satisfaire simultanément + label_singular: Condition générale à satisfaire + name: conditions_generales + default: [] + widget: list + collapsed: false + types: + - *field_age + - *field_regions + - *field_departements + - *field_epcis + - *field_excluded_epcis + - *field_communes + - *field_regime_securite_sociale + - *field_quotient_familial + - *field_formation_sanitaire_social + - *field_beneficiaire_rsa + - *field_attached_to_institution + - *field_statut_occupation_logement + - *field_not_operator + - *field_difficultes_acces_ou_frais_logement + - *field_agence_travail_temporaire + # champs propre aux aides openfisca + field_benefit_position: &field_benefit_position + label: Pondération de l'aide sur la page de résultat + name: top + widget: hidden + field_benefit_warning_message: &field_benefit_warning_message + label: Affiche un message d'avertissement spécifique + name: warning + widget: hidden + field_openfisca_eligibility_source: &openfisca_eligibility_source + label: Référence à la règle de calcul OpenFisca + name: openfisca_eligibility_source + widget: hidden + field_benefit_teleservices: &field_benefit_teleservices + label: Liens vers plusieurs téléservices + name: teleservices + widget: hidden + field_benefit_ressources_year_minus_two: &field_benefit_ressources_year_minus_two + label: Aide calculée en fonction des revenus N-2 + name: isBaseRessourcesYearMinusTwo + widget: hidden + field_benefit_msa_specific: &field_benefit_msa_specific + label: Aide restreinte aux usagers de la MSA + name: msa + widget: hidden + field_benefit_institution: &field_benefit_institution + label: Référence aux types de lieux à proximité supervisant l'aide + name: lieuxTypes + widget: hidden + field_benefit_set_to_zero_recently: &field_benefit_set_to_zero_recently + label: L'aide OpenFisca a été remise à zéro récemment + name: setToZeroRecently + widget: hidden + field_benefit_capital_dependant: &field_benefit_capital_dependant + label: L'attribution de l'aide est dépendante du capital personnel + name: isBaseRessourcesPatrimoine + widget: hidden + field_benefit_openfisca_mapping: &field_benefit_openfisca_mapping + label: Identifiant OpenFisca de l'aide + name: openfisca_eligibility_source + widget: hidden - - name: 'kitchenSink' # all the things in one entry, for documentation and quick testing - label: 'Kitchen Sink' - folder: '_sink' +collections: + - name: benefits_javascript + label: Aides avec critères d'éligibilités + label_singular: Aide avec critères d'éligibilités + identifier_field: label + folder: 'data/benefits/javascript' create: true + delete: false + editor: + preview: true + slug: '{{fields.institution}}-{{label}}' + summary: '{{label}} ({{fields.institution}})' + extension: yml fields: - - label: 'Related Post' - name: 'post' - widget: 'relationKitchenSinkPost' - collection: 'posts' - display_fields: ['title', 'datetime'] - search_fields: ['title', 'body'] - value_field: 'title' - - { label: 'Title', name: 'title', widget: 'string' } - - { label: 'Boolean', name: 'boolean', widget: 'boolean', default: true } - - { label: 'Map', name: 'map', widget: 'map' } - - { label: 'Text', name: 'text', widget: 'text', hint: 'Plain text, not markdown' } - - { label: 'Number', name: 'number', widget: 'number', hint: 'To infinity and beyond!' } - - { label: 'Markdown', name: 'markdown', widget: 'markdown' } - - { label: 'Datetime', name: 'datetime', widget: 'datetime' } - - { label: 'Image', name: 'image', widget: 'image' } - - { label: 'File', name: 'file', widget: 'file' } - - { label: 'Select', name: 'select', widget: 'select', options: ['a', 'b', 'c'] } - - { - label: 'Select multiple', - name: 'select_multiple', - widget: 'select', - options: ['a', 'b', 'c'], - multiple: true, - } - - { label: 'Hidden', name: 'hidden', widget: 'hidden', default: 'hidden' } - - { label: 'Color', name: 'color', widget: 'color' } - - label: 'Object' - name: 'object' - widget: 'object' - collapsed: true - fields: - - label: 'Related Post' - name: 'post' - widget: 'relationKitchenSinkPost' - collection: 'posts' - search_fields: ['title', 'body'] - value_field: 'title' - - { label: 'String', name: 'string', widget: 'string' } - - { label: 'Boolean', name: 'boolean', widget: 'boolean', default: false } - - { label: 'Text', name: 'text', widget: 'text' } - - { label: 'Number', name: 'number', widget: 'number' } - - { label: 'Markdown', name: 'markdown', widget: 'markdown' } - - { label: 'Datetime', name: 'datetime', widget: 'datetime' } - - { label: 'Image', name: 'image', widget: 'image' } - - { label: 'File', name: 'file', widget: 'file' } - - { label: 'Select', name: 'select', widget: 'select', options: ['a', 'b', 'c'] } - - label: 'List' - name: 'list' - widget: 'list' - fields: - - { label: 'String', name: 'string', widget: 'string' } - - { label: 'Boolean', name: 'boolean', widget: 'boolean' } - - { label: 'Text', name: 'text', widget: 'text' } - - { label: 'Number', name: 'number', widget: 'number' } - - { label: 'Markdown', name: 'markdown', widget: 'markdown' } - - { label: 'Datetime', name: 'datetime', widget: 'datetime' } - - { label: 'Image', name: 'image', widget: 'image' } - - { label: 'File', name: 'file', widget: 'file' } - - { label: 'Select', name: 'select', widget: 'select', options: ['a', 'b', 'c'] } - - label: 'Object' - name: 'object' - widget: 'object' - fields: - - { label: 'String', name: 'string', widget: 'string' } - - { label: 'Boolean', name: 'boolean', widget: 'boolean' } - - { label: 'Text', name: 'text', widget: 'text' } - - { label: 'Number', name: 'number', widget: 'number' } - - { label: 'Markdown', name: 'markdown', widget: 'markdown' } - - { label: 'Datetime', name: 'datetime', widget: 'datetime' } - - { label: 'Image', name: 'image', widget: 'image' } - - { label: 'File', name: 'file', widget: 'file' } - - { label: 'Select', name: 'select', widget: 'select', options: ['a', 'b', 'c'] } - - label: 'List' - name: 'list' - widget: 'list' - fields: - - label: 'Related Post' - name: 'post' - widget: 'relationKitchenSinkPost' - collection: 'posts' - search_fields: ['title', 'body'] - value_field: 'title' - - { label: 'String', name: 'string', widget: 'string' } - - { label: 'Boolean', name: 'boolean', widget: 'boolean' } - - { label: 'Text', name: 'text', widget: 'text' } - - { label: 'Number', name: 'number', widget: 'number' } - - { label: 'Markdown', name: 'markdown', widget: 'markdown' } - - { label: 'Datetime', name: 'datetime', widget: 'datetime' } - - { label: 'Image', name: 'image', widget: 'image' } - - { label: 'File', name: 'file', widget: 'file' } - - { label: 'Select', name: 'select', widget: 'select', options: ['a', 'b', 'c'] } - - { label: 'Hidden', name: 'hidden', widget: 'hidden', default: 'hidden' } - - label: 'Object' - name: 'object' - widget: 'object' - fields: - - { label: 'String', name: 'string', widget: 'string' } - - { label: 'Boolean', name: 'boolean', widget: 'boolean' } - - { label: 'Text', name: 'text', widget: 'text' } - - { label: 'Number', name: 'number', widget: 'number' } - - { label: 'Markdown', name: 'markdown', widget: 'markdown' } - - { label: 'Datetime', name: 'datetime', widget: 'datetime' } - - { label: 'Image', name: 'image', widget: 'image' } - - { label: 'File', name: 'file', widget: 'file' } - - { - label: 'Select', - name: 'select', - widget: 'select', - options: ['a', 'b', 'c'], - } - - label: 'Typed List' - name: 'typed_list' - widget: 'list' - types: - - label: 'Type 1 Object' - name: 'type_1_object' - widget: 'object' - fields: - - { label: 'String', name: 'string', widget: 'string' } - - { label: 'Boolean', name: 'boolean', widget: 'boolean' } - - { label: 'Text', name: 'text', widget: 'text' } - - label: 'Type 2 Object' - name: 'type_2_object' - widget: 'object' - fields: - - { label: 'Number', name: 'number', widget: 'number' } - - { label: 'Select', name: 'select', widget: 'select', options: ['a', 'b', 'c'] } - - { label: 'Datetime', name: 'datetime', widget: 'datetime' } - - { label: 'Markdown', name: 'markdown', widget: 'markdown' } - - label: 'Type 3 Object' - name: 'type_3_object' - widget: 'object' - fields: - - { label: 'Image', name: 'image', widget: 'image' } - - { label: 'File', name: 'file', widget: 'file' } - - name: pages # a nested collection - label: Pages - label_singular: 'Page' - folder: _pages + - *field_benefit_name + - *field_benefit_image + - *field_institution + - *field_description + - *field_definite_article + - *field_general_conditions + - *field_voluntary_conditions + - *field_eligibility_profile + - *field_unmodeled_conditions + - *field_specific_interest + - *field_result_type + - *field_result_unit + - *field_benefit_amount_periodicity + - *field_amount_legend + - *field_benefit_max_amount + - *field_link_information + - *field_link_teleservice + - *field_link_form + - *field_link_instructions + - *field_amount_reliability + # hidden fields + - *field_benefit_position + - *field_private_benefit + - *field_benefit_partial_support + - *field_benefit_id + - *field_benefit_source + - *field_teleservice_prefill + - name: benefits_openfisca + label: Aides complexes + label_singular: Aide complexe + identifier_field: label + folder: 'data/benefits/openfisca' + create: true + delete: false + editor: + preview: true + slug: '{{label}}' + extension: yml + fields: + - *field_benefit_name + - *field_benefit_image + - *field_institution + - *field_description + - *field_definite_article + - *field_unmodeled_conditions + - *field_voluntary_conditions + - *field_specific_interest + - *field_result_type + - *field_result_unit + - *field_benefit_amount_periodicity + - *field_amount_legend + - *field_link_information + - *field_link_teleservice + - *field_link_form + - *field_link_instructions + - *field_amount_reliability + - *field_openfisca_linked_entity + - *field_openfisca_period + - *field_private_benefit + # hidden fields + - *field_benefit_position + - *field_benefit_warning_message + - *field_benefit_teleservices + - *field_benefit_ressources_year_minus_two + - *field_benefit_msa_specific + - *field_benefit_partial_support + - *field_benefit_institution + - *field_benefit_set_to_zero_recently + - *field_benefit_capital_dependant + - *field_benefit_openfisca_mapping + - *field_teleservice_prefill + - name: institutions + label: Institutions + label_singular: institution + identifier_field: name + folder: 'data/institutions' create: true - nested: { depth: 100 } + delete: false + editor: + preview: false + slug: '{{name}}' + extension: yml + fields: + - label: Nom de votre institution + hint: Département de la Gironde, Ville de Canéjan, Mauges Communauté, etc. + name: name + widget: string + - label: Logo + name: imgSrc + widget: image + allow_multiple: false + pattern: ['(\.png|\.jpg|\.jpeg)', 'Seul les images au format JPG et PNG sont supportées'] + - label: Type d'institution + name: type + widget: relation + collection: institution_types + value_field: '{{slug}}' + display_fields: [name] + search_fields: [slug, name] + - label: Code INSEE + hint: Pour les communes, départements, régions + name: code_insee + widget: string + required: false + required_group: identifier + - label: Code SIREN + hint: En cas de doute, il est possible de rechercher sur https://annuaire-entreprises.data.gouv.fr + name: code_siren + widget: string + required: false + required_group: identifier + - label: Article défini + name: prefix + widget: hidden + required: false + - label: Types de lieux à proximité + name: lieuxTypes + widget: hidden + required: false + - label: repository + name: repository + widget: hidden + required: false + - label: Départements + name: departments + widget: hidden + required: false + - *field_benefit_position + - name: institution_types + label: Types d'institution + label_singular: Type d'institution + identifier_field: name + folder: 'data/institution_types' + create: true + delete: false + editor: + preview: false + slug: '{{name}}' + extension: yml fields: - - label: Title - name: title + - label: Nom de votre type d'institution + hint: Commune, EPCI, CAF, MSA, autres, etc. + name: name widget: string - meta: { path: { widget: string, label: 'Path', index_file: 'index' } } diff --git a/dev-test/index.html b/dev-test/index.html index 8147bcc0118d..a0f5acc64e77 100644 --- a/dev-test/index.html +++ b/dev-test/index.html @@ -1,242 +1,14 @@ - + - - - - Decap CMS Development Test - - - - - - - + + + Decap CMS + + + + + From 533b2055efa18126975e511a015a8264605ba4e3 Mon Sep 17 00:00:00 2001 From: Thomas Guillet Date: Fri, 19 Apr 2024 12:25:45 +0200 Subject: [PATCH 2/6] feat: add a fast read access git backend proxy --- package-lock.json | 200 ++++++++++++++++++ packages/decap-cms-app/package.json | 1 + packages/decap-cms-app/src/extensions.js | 3 + packages/decap-cms-backend-git/README.md | 7 + packages/decap-cms-backend-git/package.json | 42 ++++ .../src/implementation.ts | 160 ++++++++++++++ packages/decap-cms-backend-git/src/index.ts | 6 + .../decap-cms-backend-git/webpack.config.js | 3 + 8 files changed, 422 insertions(+) create mode 100644 packages/decap-cms-backend-git/README.md create mode 100644 packages/decap-cms-backend-git/package.json create mode 100644 packages/decap-cms-backend-git/src/implementation.ts create mode 100644 packages/decap-cms-backend-git/src/index.ts create mode 100644 packages/decap-cms-backend-git/webpack.config.js diff --git a/package-lock.json b/package-lock.json index f19ad567ebe2..1f69c25f9b3a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3271,6 +3271,25 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/@isomorphic-git/idb-keyval": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@isomorphic-git/idb-keyval/-/idb-keyval-3.3.2.tgz", + "integrity": "sha512-r8/AdpiS0/WJCNR/t/gsgL+M8NMVj/ek7s60uz3LmpCaTF2mEVlZJlB01ZzalgYzRLXwSPC92o+pdzjM7PN/pA==" + }, + "node_modules/@isomorphic-git/lightning-fs": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@isomorphic-git/lightning-fs/-/lightning-fs-4.6.0.tgz", + "integrity": "sha512-tfon8f1h6LawjFI/d8lZPWRPTxmdvyTMbkT/j5yo6dB0hALhKw5D9JsdCcUu/D1pAcMMiU7GZFDsDGqylerr7g==", + "dependencies": { + "@isomorphic-git/idb-keyval": "3.3.2", + "isomorphic-textencoder": "1.0.1", + "just-debounce-it": "1.1.0", + "just-once": "1.1.0" + }, + "bin": { + "superblocktxt": "src/superblocktxt.js" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "dev": true, @@ -8815,6 +8834,11 @@ "version": "3.2.4", "license": "MIT" }, + "node_modules/async-lock": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.4.1.tgz", + "integrity": "sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==" + }, "node_modules/async-mutex": { "version": "0.3.2", "license": "MIT", @@ -10458,6 +10482,11 @@ "node": ">=0.10.0" } }, + "node_modules/clean-git-ref": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/clean-git-ref/-/clean-git-ref-2.0.1.tgz", + "integrity": "sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw==" + }, "node_modules/clean-regexp": { "version": "1.0.0", "dev": true, @@ -11475,6 +11504,17 @@ "typescript": ">=3" } }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/create-ecdh": { "version": "4.0.4", "license": "MIT", @@ -12464,6 +12504,10 @@ "resolved": "packages/decap-cms-backend-bitbucket", "link": true }, + "node_modules/decap-cms-backend-git": { + "resolved": "packages/decap-cms-backend-git", + "link": true + }, "node_modules/decap-cms-backend-git-gateway": { "resolved": "packages/decap-cms-backend-git-gateway", "link": true @@ -12625,6 +12669,20 @@ "node": ">=0.10" } }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/dedent": { "version": "0.7.0", "license": "MIT" @@ -12944,6 +13002,11 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/diff3": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/diff3/-/diff3-0.0.3.tgz", + "integrity": "sha512-iSq8ngPOt0K53A6eVr4d5Kn6GNrM2nQZtC740pzIriHtn4pOQ2lyzEXQMBeVcWERN0ye7fhBsk9PbLLQOnUx/g==" + }, "node_modules/diffie-hellman": { "version": "5.0.3", "license": "MIT", @@ -14472,6 +14535,11 @@ "version": "2.1.1", "license": "MIT" }, + "node_modules/fast-text-encoding": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.6.tgz", + "integrity": "sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==" + }, "node_modules/fastest-levenshtein": { "version": "1.0.16", "dev": true, @@ -17118,6 +17186,59 @@ "version": "1.0.2", "license": "MIT" }, + "node_modules/isomorphic-git": { + "version": "1.25.7", + "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.25.7.tgz", + "integrity": "sha512-KE10ejaIsEpQ+I/apS33qqTjyzCXgOniEaL32DwNbXtboKG8H3cu+RiBcdp3G9w4MpOOTQfGPsWp4i8UxRfDLg==", + "dependencies": { + "async-lock": "^1.1.0", + "clean-git-ref": "^2.0.1", + "crc-32": "^1.2.0", + "diff3": "0.0.3", + "ignore": "^5.1.4", + "minimisted": "^2.0.0", + "pako": "^1.0.10", + "pify": "^4.0.1", + "readable-stream": "^3.4.0", + "sha.js": "^2.4.9", + "simple-get": "^4.0.1" + }, + "bin": { + "isogit": "cli.cjs" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/isomorphic-git/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/isomorphic-git/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/isomorphic-textencoder": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-textencoder/-/isomorphic-textencoder-1.0.1.tgz", + "integrity": "sha512-676hESgHullDdHDsj469hr+7t3i/neBKU9J7q1T4RHaWwLAsaQnywC0D1dIUId0YZ+JtVrShzuBk1soo0+GVcQ==", + "dependencies": { + "fast-text-encoding": "^1.0.0" + } + }, "node_modules/isstream": { "version": "0.1.2", "dev": true, @@ -18158,11 +18279,21 @@ "node": ">=4.0" } }, + "node_modules/just-debounce-it": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/just-debounce-it/-/just-debounce-it-1.1.0.tgz", + "integrity": "sha512-87Nnc0qZKgBZuhFZjYVjSraic0x7zwjhaTMrCKlj0QYKH6lh0KbFzVnfu6LHan03NO7J8ygjeBeD0epejn5Zcg==" + }, "node_modules/just-extend": { "version": "6.2.0", "dev": true, "license": "MIT" }, + "node_modules/just-once": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/just-once/-/just-once-1.1.0.tgz", + "integrity": "sha512-+rZVpl+6VyTilK7vB/svlMPil4pxqIJZkbnN7DKZTOzyXfun6ZiFeq2Pk4EtCEHZ0VU4EkdFzG8ZK5F3PErcDw==" + }, "node_modules/jwt-decode": { "version": "3.1.2", "license": "MIT" @@ -20129,6 +20260,17 @@ "node": ">=6" } }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/min-indent": { "version": "1.0.1", "license": "MIT", @@ -20181,6 +20323,14 @@ "node": ">= 6" } }, + "node_modules/minimisted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minimisted/-/minimisted-2.0.1.tgz", + "integrity": "sha512-1oPjfuLQa2caorJUM8HV8lGgWCc0qqAO1MNv/k05G4qslmsndV/5WdNZrqCiyqiz3wohia2Ij2B7w2Dr7/IyrA==", + "dependencies": { + "minimist": "^1.2.5" + } + }, "node_modules/minipass": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", @@ -28978,6 +29128,30 @@ ], "license": "MIT" }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, "node_modules/simple-git": { "version": "3.20.0", "license": "MIT", @@ -33231,6 +33405,7 @@ "decap-cms-backend-aws-cognito-github-proxy": "^3.1.2", "decap-cms-backend-azure": "^3.1.1", "decap-cms-backend-bitbucket": "^3.1.2", + "decap-cms-backend-git": "^3.1.1", "decap-cms-backend-git-gateway": "^3.1.1", "decap-cms-backend-github": "^3.1.2", "decap-cms-backend-gitlab": "^3.1.3", @@ -33335,6 +33510,31 @@ "react": "^18.2.0" } }, + "packages/decap-cms-backend-git": { + "version": "3.1.3", + "license": "MIT", + "dependencies": { + "@isomorphic-git/lightning-fs": "^4.6.0", + "apollo-cache-inmemory": "^1.6.2", + "apollo-client": "^2.6.3", + "apollo-link-context": "^1.0.18", + "apollo-link-http": "^1.5.15", + "isomorphic-git": "^1.25.7", + "js-base64": "^3.0.0", + "semaphore": "^1.1.0" + }, + "peerDependencies": { + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "decap-cms-lib-auth": "^3.0.0", + "decap-cms-lib-util": "^3.0.0", + "decap-cms-ui-default": "^3.0.0", + "immutable": "^3.7.6", + "lodash": "^4.17.11", + "prop-types": "^15.7.2", + "react": "^18.2.0" + } + }, "packages/decap-cms-backend-git-gateway": { "version": "3.1.1", "license": "MIT", diff --git a/packages/decap-cms-app/package.json b/packages/decap-cms-app/package.json index 2160fda489d8..ff8f61eabaef 100644 --- a/packages/decap-cms-app/package.json +++ b/packages/decap-cms-app/package.json @@ -33,6 +33,7 @@ "decap-cms-backend-aws-cognito-github-proxy": "^3.1.2", "decap-cms-backend-azure": "^3.1.1", "decap-cms-backend-bitbucket": "^3.1.2", + "decap-cms-backend-git": "^3.1.1", "decap-cms-backend-git-gateway": "^3.1.1", "decap-cms-backend-github": "^3.1.2", "decap-cms-backend-gitlab": "^3.1.3", diff --git a/packages/decap-cms-app/src/extensions.js b/packages/decap-cms-app/src/extensions.js index eef9ebd77063..429819159b42 100644 --- a/packages/decap-cms-app/src/extensions.js +++ b/packages/decap-cms-app/src/extensions.js @@ -3,6 +3,7 @@ import { DecapCmsCore as CMS } from 'decap-cms-core'; // Backends import { AzureBackend } from 'decap-cms-backend-azure'; import { AwsCognitoGitHubProxyBackend } from 'decap-cms-backend-aws-cognito-github-proxy'; +import { GitProxyBackendGenerator } from 'decap-cms-backend-git'; import { GitHubBackend } from 'decap-cms-backend-github'; import { GitLabBackend } from 'decap-cms-backend-gitlab'; import { GiteaBackend } from 'decap-cms-backend-gitea'; @@ -33,8 +34,10 @@ import * as locales from 'decap-cms-locales'; // Register all the things CMS.registerBackend('git-gateway', GitGatewayBackend); +CMS.registerBackend('git-gateway-large', GitProxyBackendGenerator(GitGatewayBackend)); CMS.registerBackend('azure', AzureBackend); CMS.registerBackend('aws-cognito-github-proxy', AwsCognitoGitHubProxyBackend); +CMS.registerBackend('github-large', GitProxyBackendGenerator(GitHubBackend)); CMS.registerBackend('github', GitHubBackend); CMS.registerBackend('gitlab', GitLabBackend); CMS.registerBackend('gitea', GiteaBackend); diff --git a/packages/decap-cms-backend-git/README.md b/packages/decap-cms-backend-git/README.md new file mode 100644 index 000000000000..6989d5d2093e --- /dev/null +++ b/packages/decap-cms-backend-git/README.md @@ -0,0 +1,7 @@ +# Git backend with fast read access + +## Code structure + +`Implementation` for [File Management System API](https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-lib-util/README.md). + +Look at tests or types for more info. diff --git a/packages/decap-cms-backend-git/package.json b/packages/decap-cms-backend-git/package.json new file mode 100644 index 000000000000..fda5acfd3acb --- /dev/null +++ b/packages/decap-cms-backend-git/package.json @@ -0,0 +1,42 @@ +{ + "name": "decap-cms-backend-git", + "description": "Git backend for Decap CMS with fast read access", + "version": "3.1.3", + "repository": "https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-git", + "bugs": "https://github.com/decaporg/decap-cms/issues", + "license": "MIT", + "module": "dist/esm/index.js", + "main": "dist/decap-cms-backend-git.js", + "keywords": [ + "decap-cms", + "backend", + "gitlab" + ], + "sideEffects": false, + "scripts": { + "develop": "npm run build:esm -- --watch", + "build": "cross-env NODE_ENV=production webpack", + "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward --extensions \".js,.jsx,.ts,.tsx\"" + }, + "dependencies": { + "@isomorphic-git/lightning-fs": "^4.6.0", + "apollo-cache-inmemory": "^1.6.2", + "apollo-client": "^2.6.3", + "apollo-link-context": "^1.0.18", + "apollo-link-http": "^1.5.15", + "isomorphic-git": "^1.25.7", + "js-base64": "^3.0.0", + "semaphore": "^1.1.0" + }, + "peerDependencies": { + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "decap-cms-lib-auth": "^3.0.0", + "decap-cms-lib-util": "^3.0.0", + "decap-cms-ui-default": "^3.0.0", + "immutable": "^3.7.6", + "lodash": "^4.17.11", + "prop-types": "^15.7.2", + "react": "^18.2.0" + } +} diff --git a/packages/decap-cms-backend-git/src/implementation.ts b/packages/decap-cms-backend-git/src/implementation.ts new file mode 100644 index 000000000000..68d79470515f --- /dev/null +++ b/packages/decap-cms-backend-git/src/implementation.ts @@ -0,0 +1,160 @@ +import git from 'isomorphic-git'; +import http from 'isomorphic-git/http/web'; +import FS from '@isomorphic-git/lightning-fs'; + +import type { Implementation, Config } from 'decap-cms-lib-util'; + +const corsProxy = 'https://cors.isomorphic-git.org'; +const dir = '/repo'; +let singleton; + +export default function GitProxyBackEndGenerator(T) { + class GitProxyBackend implements Implementation { + backend: Implementation; + config: Config; + constructor(config: Config, options = {}) { + this.backend = new T(config, options); + this.config = config; + this.fs = new FS('decapfs'); + this.pfs = this.fs.promises; + if (!singleton) { + singleton = this.getRepository(); + } + this.repository = singleton; + } + + async getRepository() { + try { + await this.pfs.stat(dir); + } catch (e) { + await this.pfs.mkdir(dir); + await git.init({ + fs: this.fs, + dir, + defaultBranch: 'main', + }); + } + const fetchResult = await git.fetch({ + fs: this.fs, + http, + dir, + corsProxy, + url: 'https://github.com/betagouv/aides-jeunes', + ref: 'main', + singleBranch: true, + depth: 1, + }); + await git.checkout({ + fs: this.fs, + http, + dir, + ref: fetchResult.fetchHead, + force: true, + track: false, + }); + return this.pfs.readdir(dir); + } + + isGitBackend() { + return true; + } + + async entriesByFolder(folder: string, extension: string, depth: number) { + try { + const files = await this.pfs.readdir(`${dir}/${folder}`); + const relevantFiles = files.filter(name => name.endsWith(extension)); + return Promise.all( + relevantFiles.map(async filename => { + const path = `${folder}/${filename}`; + const fullPath = `${dir}/${path}`; + const data = await this.pfs.readFile(fullPath, 'utf8'); + return { + data, + file: { path, id: path }, + }; + }), + ); + } catch { + return []; + } + } + async getEntry(path: string) { + const data = await this.pfs.readFile(`${dir}/${path}`, 'utf8'); + return { + file: { path, id: null }, + data, + }; + } + + status(...args) { + return this.backend.status(...args); + } + authComponent(...args) { + return this.backend.authComponent(...args); + } + restoreUser(...args) { + return this.backend.restoreUser(...args); + } + authenticate(...args) { + return this.backend.authenticate(...args); + } + logout() { + return this.backend.logout(...args); + } + getToken(...args) { + return this.backend.getToken(...args); + } + traverseCursor(...args) { + return this.backend.traverseCursor(...args); + } + entriesByFiles(...args) { + return this.backend.entriesByFiles(...args); + } + unpublishedEntries(...args) { + return this.backend.unpublishedEntries(...args); + } + unpublishedEntry(...args) { + return this.backend.unpublishedEntry(...args); + } + unpublishedEntryDataFile(...args) { + return this.backend.unpublishedEntryDataFile(...args); + } + unpublishedEntryMediaFile(...args) { + return this.backend.unpublishedEntryMediaFile(...args); + } + deleteUnpublishedEntry(collection: string, slug: string) { + return this.backend.deleteUnpublishedEntry(collection, slug); + } + addOrUpdateUnpublishedEntry(...args) { + return this.backend.addOrUpdateUnpublishedEntry(...args); + } + persistEntry(...args) { + return this.backend.persistEntry(...args); + } + updateUnpublishedEntryStatus(...args) { + return this.backend.updateUnpublishedEntryStatus(...args); + } + publishUnpublishedEntry(...args) { + return this.backend.publishUnpublishedEntry(...args); + } + getMedia(...args) { + return this.backend.getMedia(...args); + } + getMediaFile(...args) { + return this.backend.getMediaFile(...args); + } + normalizeAsset(...args) { + return this.backend.normalizeAsset(...args); + } + persistMedia(...args) { + return this.backend.persistMedia(...args); + } + deleteFiles(...args) { + return this.backend.deleteFiles(...args); + } + getDeployPreview(...args) { + return this.backend.getDeployPreview(...args); + } + } + return GitProxyBackend; +} diff --git a/packages/decap-cms-backend-git/src/index.ts b/packages/decap-cms-backend-git/src/index.ts new file mode 100644 index 000000000000..d7af953d4c25 --- /dev/null +++ b/packages/decap-cms-backend-git/src/index.ts @@ -0,0 +1,6 @@ +import GitProxyBackendGenerator from './implementation'; + +export const DecapCmsBackendGitlab = { + GitProxyBackendGenerator, +}; +export { GitProxyBackendGenerator }; diff --git a/packages/decap-cms-backend-git/webpack.config.js b/packages/decap-cms-backend-git/webpack.config.js new file mode 100644 index 000000000000..42edd361d4a7 --- /dev/null +++ b/packages/decap-cms-backend-git/webpack.config.js @@ -0,0 +1,3 @@ +const { getConfig } = require('../../scripts/webpack.js'); + +module.exports = getConfig(); From 2ced270360cb4bc35816997481ea52b80d976182 Mon Sep 17 00:00:00 2001 From: Thomas Guillet Date: Fri, 19 Apr 2024 12:34:31 +0200 Subject: [PATCH 3/6] Revert "test: test content" This reverts commit 3f0363fe9c7423d8f967e93c328fecd322cfbd5a. --- dev-test/config.yml | 1251 +++++++++---------------------------------- dev-test/index.html | 252 ++++++++- 2 files changed, 503 insertions(+), 1000 deletions(-) diff --git a/dev-test/config.yml b/dev-test/config.yml index 088744f146a7..31c7f12ae97a 100644 --- a/dev-test/config.yml +++ b/dev-test/config.yml @@ -1,1006 +1,281 @@ -locale: fr backend: - name: github-large - repo: betagouv/aides-jeunes - branch: main - commit_messages: - create: Crée {{slug}} - update: Met à jour {{slug}} - delete: Supprime {{slug}} - uploadMedia: Nouvelle image {{path}} - deleteMedia: Suppression de l'image {{path}} + name: test-repo -media_folder: public/img/institutions -public_folder: img/institutions +site_url: https://example.com -slug: - encoding: ascii - clean_accents: true - -# local_backend: true publish_mode: editorial_workflow +media_folder: assets/uploads -root: ../../.. +collections: # A list of collections the CMS should be able to edit + - name: 'posts' # Used in routes, ie.: /admin/collections/:slug/edit + label: 'Posts' # Used in the UI + label_singular: 'Post' # Used in the UI, ie: "New Post" + description: > + The description is a great place for tone setting, high level information, and editing + guidelines that are specific to a collection. + folder: '_posts' + slug: '{{year}}-{{month}}-{{day}}-{{slug}}' + summary: '{{title}} -- {{year}}/{{month}}/{{day}}' + create: true # Allow users to create new documents in this collection + view_filters: + - label: Posts With Index + field: title + pattern: 'This is post #' + - label: Posts Without Index + field: title + pattern: front matter post + - label: Drafts + field: draft + pattern: true + view_groups: + - label: Year + field: date + pattern: \d{4} + - label: Drafts + field: draft + fields: # The fields each document in this collection have + - { label: 'Title', name: 'title', widget: 'string', tagname: 'h1' } + - { label: 'Draft', name: 'draft', widget: 'boolean', default: false } + - { + label: 'Publish Date', + name: 'date', + widget: 'datetime', + date_format: 'YYYY-MM-DD', + time_format: 'HH:mm', + format: 'YYYY-MM-DD HH:mm', + } + - label: 'Cover Image' + name: 'image' + widget: 'image' + required: false + tagname: '' -patterns: - pattern_url: &pattern_url - - "^(https?:\/\/)" - - 'Le champ doit contenir une url valide' + - { label: 'Body', name: 'body', widget: 'markdown', hint: 'Main content goes here.' } -fields: - field_empty: &field_empty - widget: object - fields: - - label: empty - widget: hidden - name: empty - field_numeric_value: &field_numeric_value - label: Valeur - name: value - widget: number - step: -1 - field_numeric_operator: &field_numeric_operator - label: Opérateur - name: operator - widget: select - options: - - label: Supérieur à - value: '>' - - label: Supérieur ou égal à - value: '>=' - - label: Égal à - value: '=' - - label: Inférieur à - value: '<' - - label: Inférieur ou égal à - value: '<=' - field_number: &field_number - widget: object - fields: - - *field_numeric_operator - - *field_numeric_value - field_age: &field_age - <<: *field_number - label: Age - name: age - field_regions: &field_regions - label: Condition géographique régionale - name: regions - widget: object - fields: - - label: Régions - name: values - widget: select - multiple: true - options: - - label: Auvergne-Rhône-Alpes - value: '84' - - label: Bourgogne-Franche-Comté - value: '27' - - label: Bretagne - value: '53' - - label: Centre-Val de Loire - value: '24' - - label: Corse - value: '94' - - label: Grand Est - value: '44' - - label: Guadeloupe - value: '01' - - label: Guyane - value: '03' - - label: Hauts-de-France - value: '32' - - label: Île-de-France - value: '11' - - label: La Réunion - value: '04' - - label: Martinique - value: '02' - - label: Mayotte - value: '06' - - label: Normandie - value: '28' - - label: Nouvelle-Aquitaine - value: '75' - - label: Occitanie - value: '76' - - label: Pays de la Loire - value: '52' - - label: Provence-Alpes-Côte d'Azur - value: '93' - field_departements: &field_departements - label: Condition géographique départementale - name: departements - widget: object - fields: - - label: Code des départements - name: values - widget: list - hint: Pour saisir plusieurs département, séparez les codes des départements par une virgule. - field_epcis: &field_epcis - label: Condition géographique d'EPCI - name: epcis - widget: object - fields: - - label: Code SIREN des EPCI - name: values - widget: list - hint: Pour saisir plusieurs EPCI, séparez les codes SIREN par une virgule. - field_excluded_epcis: &field_excluded_epcis - label: Condition d'exclusion géographique d'EPCI - name: excluded_epcis - widget: object - fields: - - label: Code SIREN des EPCI exclues - name: values - widget: list - hint: Pour saisir plusieurs EPCI, séparez les codes SIREN par une virgule. - field_communes: &field_communes - label: Condition géographique communale - name: communes - widget: object - fields: - - label: Code INSEE des communes - name: values + - name: 'restaurants' # Used in routes, ie.: /admin/collections/:slug/edit + label: 'Restaurants' # Used in the UI + label_singular: 'Restaurant' # Used in the UI, ie: "New Post" + description: > + Restaurants is an entry type used for testing galleries, relations and other widgets. + The tests must be written in such way that adding new fields does not affect previous flows. + folder: '_restaurants' + slug: '{{year}}-{{month}}-{{day}}-{{slug}}' + summary: '{{title}} -- {{year}}/{{month}}/{{day}}' + create: true # Allow users to create new documents in this collection + fields: # The fields each document in this collection have + - { label: 'Title', name: 'title', widget: 'string', tagname: 'h1' } + - { label: 'Body', name: 'body', widget: 'markdown', hint: 'Main content goes here.' } + - { name: 'gallery', widget: 'image', choose_url: true, media_library: {config: {multiple: true, max_files: 999}}} + - { name: 'post', widget: relation, collection: posts, multiple: true, search_fields: [ "title" ], display_fields: [ "title" ], value_field: "{{slug}}", filters: [ {field: "draft", values: [false]} ] } + - name: authors + label: Authors + label_singular: 'Author' widget: list - hint: Pour saisir plusieurs communes, séparez les codes INSEE des communes par une virgule. - field_boursier: &field_boursier - <<: *field_empty - label: Boursier - name: boursier - field_mention_baccalaureat: &field_mention_baccalaureat - label: Mention au bac - name: mention_baccalaureat - widget: object - fields: - - label: Valeurs - name: values - widget: select - multiple: true - options: - - label: Mention assez bien - value: mention_assez_bien - - label: Mention bien - value: mention_bien - - label: Mention très bien - value: mention_tres_bien - - label: Mention très bien avec félicitations du jury - value: mention_tres_bien_felicitations_jury - - label: Autre - value: non_renseignee - field_select_regime_securite_sociale: &field_select_regime_securite_sociale - widget: select - multiple: true - required: false - options: - - label: Régime général - value: regime_general - - label: Régime agricole - value: regime_agricole - - label: Autres régimes - value: autres_regimes - field_regime_securite_sociale: &field_regime_securite_sociale - label: Régime de sécurité sociale - name: regime_securite_sociale - widget: object - fields: - - <<: *field_select_regime_securite_sociale - label: Inclus - name: includes - - <<: *field_select_regime_securite_sociale - label: Exclus - name: excludes - field_quotient_familial: &field_quotient_familial - label: Quotient familial - name: quotient_familial - widget: object - fields: - - *field_numeric_operator - - <<: *field_numeric_value - label: Montant - - label: Période - name: period - widget: select - options: - - label: Par mois - value: month - - label: Par an - value: year - field_taux_incapacite: &field_taux_incapacite - label: Taux d'incapacité - name: taux_incapacite - fields: - - *field_numeric_operator - - <<: *field_numeric_value - label: Taux - value_type: float - min: 0 - max: 1 - hint: Le taux est exprimé par un nombre entre 0 et 1. Exemple 0.8 pour 80%. - field_formation_sanitaire_social: &field_formation_sanitaire_social - <<: *field_empty - label: En formation sanitaire et sociale - name: formation_sanitaire_social - field_beneficiaire_rsa: &field_beneficiaire_rsa - <<: *field_empty - label: Bénéficiaire RSA - name: beneficiaire_rsa - field_attached_to_institution: &field_attached_to_institution - <<: *field_empty - label: Habite dans le périmètre géographique l'institution (uniquement commune, epci, département ou région) - name: attached_to_institution - field_exclude_epcis: &field_exclude_epcis - <<: *field_empty - label: Exclure les EPCI - name: exclude_epcis - field_select_statut_occupation_logement: &field_select_statut_occupation_logement - widget: select - multiple: true - required: false - options: - - label: Propriétaire primo-accédant - value: primo_accedant - - label: Propriétaire - value: proprietaire - - label: Locataire - value: locataire_vide - - label: Locataire de meublé ou hotel - value: locataire_meuble - - label: 'Logé gratuitement' - value: loge_gratuitement - - label: 'Locataire foyer' - value: locataire_foyer - - label: 'Sans domicile stable' - value: sans_domicile - field_statut_occupation_logement: &field_statut_occupation_logement - label: Statut d'occupation du logement - name: statut_occupation_logement - widget: object - fields: - - <<: *field_select_statut_occupation_logement - label: Inclus - name: includes - - <<: *field_select_statut_occupation_logement - label: Exclus - name: excludes - field_difficultes_acces_ou_frais_logement: &field_difficultes_acces_ou_frais_logement - <<: *field_empty - label: Difficultés importantes pour accéder à un logement ou pour payer les frais liés à un logement - name: difficultes_acces_ou_frais_logement - field_agence_travail_temporaire: &field_agence_travail_temporaire - <<: *field_empty - name: agence_travail_temporaire - label: Intérimaire d'une agence de travail temporaire - # common fields - field_benefit_image: &field_benefit_image - label: Logo - name: imgSrc - widget: hidden - allow_multiple: false - required: false - public_folder: 'img/benefits' - media_folder: '/public/img/benefits' - hint: Utile si vous voulez afficher le logo de l'aide à la place de l'image de l'institution. - field_benefit_name: &field_benefit_name - label: Nom de l'aide - name: label - widget: string - field_institution: &field_institution - label: Institution - name: institution - widget: relation - collection: institutions - value_field: '{{slug}}' - display_fields: ['{{name}}'] - search_fields: [slug, name] - allow_multiple: false - options_length: -1 - filter: - label: 'Type :' - target: 'type' - hint: Si votre institution n'apparaît pas dans la liste, vous pouvez [l'ajouter ici](https://contribuer-aides-jeunes.netlify.app/admin/#/collections/institutions/new). - field_description: &field_description - label: Courte description - name: description - widget: description - field_unmodeled_conditions: &field_unmodeled_conditions - label: Conditions non prises en compte par le simulateur - label_singular: Condition non prise en compte par le simulateur - hint: | - Certains critères d'éligibilité ne peuvent pas être demandés (trop précis) - ni pris en compte (trop complexe) dans le cadre d'un simulateur grand public. - Cette liste permet d'informer les usagers sur ces critères supplémentaires. - Par exemple : Signer un contrat d’engagement réciproque (CER) avec votre département - ou un Projet Personnalisé d’Accès à l’Emploi (PPAE) avec France travail. - name: conditions - widget: list - collapsed: false - field: - label: Texte - name: text - widget: string - pattern: - [ - '\.$', - "La condition doit commencer par un verbe à l'infinitif et se terminer par un point", - ] - field_link_information: &field_link_information - label: Lien vers la page d'informations de référence - hint: Vers un site institutionnel de préférence (par exemple, pour les aides nationales il s'agit souvent de service-public.fr) - name: link - widget: string - pattern: *pattern_url - field_link_instructions: &field_link_instructions - label: Lien vers des instructions à suivre - name: instructions - widget: string - pattern: *pattern_url - required: false - required_group: cta - field_link_form: &field_link_form - label: Lien vers un formulaire à imprimer - name: form - widget: string - pattern: *pattern_url - required: false - required_group: cta - field_link_teleservice: &field_link_teleservice - label: Lien vers un téléservice - hint: Lorsqu'il y a la possibilité de faire la démarche en ligne. - name: teleservice - widget: string - pattern: *pattern_url - required: false - required_group: cta - field_definite_article: &field_definite_article - label: Article défini - name: prefix - hint: | - L'ajout d'un article défini permet la formation de phrase grammaticalement correcte. - Par exemple, dans la phrase « Comment obtenir l'aide exceptionnelle ? », on choisit le préfixe « l' ». Pour « Comment obtenir les aides au logement ? », on choisit le préfixe « les ». - widget: select - required: true - options: [le, la, les, l’, une, un, l’aide] - field_result_type: &field_result_type - label: Type du résultat - name: type - default: 'float' - widget: select - options: - - label: Valeur numérique - value: float - - label: Éligibilité (Oui / Non) - value: bool - - label: Autre - value: mixed - field_result_unit: &field_result_unit - label: Unité lorsque le type de résultat est une valeur numérique - hint: Il s'agit de spécifier l'unité du montant. - name: unit - widget: select - default: € - required: false - options: - - label: € - value: € - - label: '%' - value: '%' - - label: séances - value: séances - field_amount_legend: &field_amount_legend - label: Légende associée à la valeur numérique - hint: Cette légende permet d'ajouter des informations complémentaires sur le montant. Par exemple, si vous écrivez "maximum" dans ce champ, et que vous avez indiqué "200 €" en montant, cela affichera "200 € maximum". - name: legend - widget: string - required: false - field_amount_reliability: &field_amount_reliability - label: Niveau de fiabilité lorsque le résultat est un montant - name: floorAt - widget: select - required: false - options: - - label: 10 (pour arrondir à la dizaine inférieure) - value: 10 - - label: 1 (pour l'euro inférieur) - value: 1 - - label: 0.01 (pour éviter l'arrondi) - value: 0.01 - field_specific_interest: &field_specific_interest - label: Faut-il limiter l'affichage de l'aide en fonction d'un intérêt particulier ? - name: interestFlag - hint: | - En fin de parcours, des questions sont posées pour connaitre certains intérêts des usagers. - Cela permet d'éviter d'afficher certaines aides qui ne seraient pas pertinentes pour les usagers. - widget: select - required: false - options: - - label: Oui, l'afficher en cas d'intérêt pour le BAFA ou le BAFD. - value: _interetBafa - - label: Oui, l'afficher en cas d'intérêt pour passer le permis de conduire. - value: _interetPermisDeConduire - - label: Oui, l'afficher en cas d'intérêt pour faire des études à l'étranger. - value: _interetEtudesEtranger - - label: Oui, l'afficher en cas d'intérêt pour faire une formation dans le sanitaire et social. - value: _interetAidesSanitaireSocial - field_openfisca_linked_entity: &field_openfisca_linked_entity - label: Entité de rattachement de la variable dans OpenFisca - name: entity - widget: select - hint: Cette variable fait le lien avec le moteur de calculs. Tant que vous ne savez pas quoi y indiquer, nous recommandons de laisser Ménage. - options: - - label: Famille - value: familles - - label: Foyer Fiscal - value: foyers_fiscaux - - label: Individu - value: individus - - label: Ménage - value: menages - field_openfisca_period: &field_openfisca_period - label: Période de la variable dans OpenFisca - name: openfiscaPeriod - widget: select - hint: Cette variable fait le lien avec le moteur de calculs. Tant que vous ne savez pas quoi y indiquer, nous recommandons de laisser Mois. - options: - - label: Mois - value: thisMonth - - label: Année - value: thisYear - field_benefit_max_amount: &field_benefit_max_amount - label: Montant maximal de l'aide - name: montant - widget: number - required: false - step: -1 - field_benefit_amount_periodicity: &field_benefit_amount_periodicity - label: "Périodicité de l'aide" - name: periodicite - widget: select - hint: Cette variable permet de définir la fréquence de versement de l'aide. - required: true - default: autre - options: - - label: Ponctuelle - value: ponctuelle - - label: Mensuelle (/ mois) - value: mensuelle - - label: Annuelle (/ an) - value: annuelle - - label: Autre - value: autre - field_eligibility_profile: &field_eligibility_profile - label: profil d'éligibilité - label_singular: profils d'éligibilité - hint: Cette aide est-elle destinée à des publics spécifiques ? (lycéen(ne)s, apprenti(e)s, en recherche d'emploi, etc.) - name: profils - widget: list - collapsed: false - default: [] - types: - - label: Lycéen ou lycéenne - name: lyceen - widget: object fields: - - label: Conditions à satisfaire simultanément - label_singular: Condition à satisfaire - name: conditions - default: [] - widget: list - collapsed: false - types: - - *field_age - - *field_boursier - - *field_formation_sanitaire_social - - label: Année d'étude - name: annee_etude - widget: object - fields: - - label: Valeurs - name: values - widget: select - multiple: true - options: - - label: CAP - 1ère année - value: cap_1 - - label: CAP - 2ème année - value: cap_2 - - label: Seconde - value: seconde - - label: Première - value: premiere - - label: Terminale - value: terminale - - label: Autre - value: autre - - label: Dans l'enseignement supérieur - name: enseignement_superieur - widget: object - fields: - - label: Conditions à satisfaire simultanément - label_singular: Condition à satisfaire - name: conditions - default: [] - widget: list - collapsed: false - types: - - *field_age - - *field_boursier - - *field_mention_baccalaureat - - *field_formation_sanitaire_social - - label: Année d'étude - name: annee_etude - widget: object - fields: - - label: Valeurs - name: values - widget: select - multiple: true - options: - - label: BTS - value: bts_1 - - label: BUT - value: but_1 - - label: CPGE - value: cpge_1 - - label: Licence - 1ère année - value: licence_1 - - label: Licence - 2ème année - value: licence_2 - - label: Licence - 3ème année - value: licence_3 - - label: Master - 1ère année - value: master_1 - - label: Master - 2ème année - value: master_2 - - label: Doctorat - 1ère année - value: doctorat_1 - - label: Doctorat - 2ème année - value: doctorat_2 - - label: Doctorat - 3ème année - value: doctorat_3 - - label: Autre - value: autre - - label: Scolarisé ou scolarisée - name: etudiant - widget: object - fields: - - label: Conditions à satisfaire simultanément - label_singular: Condition à satisfaire - name: conditions - default: [] - widget: list - collapsed: false - types: - - *field_age - - *field_formation_sanitaire_social - - *field_boursier - - label: Année d'étude - name: annee_etude - widget: object - fields: - - label: Valeurs - name: values - widget: select - multiple: true - options: - - label: CAP - 1ère année - value: cap_1 - - label: CAP - 2ème année - value: cap_2 - - label: Seconde - value: seconde - - label: Première - value: premiere - - label: Terminale - value: terminale - - label: BTS - value: bts_1 - - label: BUT - value: but_1 - - label: CPGE - value: cpge_1 - - label: Licence - 1ère année - value: licence_1 - - label: Licence - 2ème année - value: licence_2 - - label: Licence - 3ème année - value: licence_3 - - label: Master - 1ère année - value: master_1 - - label: Master - 2ème année - value: master_2 - - label: Doctorat - 1ère année - value: doctorat_1 - - label: Doctorat - 2ème année - value: doctorat_2 - - label: Doctorat - 3ème année - value: doctorat_3 - - label: Autre - value: autre - - label: Stagiaire - name: stagiaire - widget: object - fields: - - label: Conditions à satisfaire simultanément - label_singular: Condition à satisfaire - name: conditions - default: [] - widget: list - collapsed: false - types: - - *field_formation_sanitaire_social - - *field_age - - *field_boursier - - label: Apprenti ou apprentie - name: apprenti - widget: object - fields: - - label: Conditions à satisfaire simultanément - label_singular: Condition à satisfaire - name: conditions - default: [] - widget: list - collapsed: false - types: - - *field_formation_sanitaire_social - - *field_age - - *field_boursier - - label: En contrat de professionnalisation - name: professionnalisation - widget: object - fields: - - label: Conditions à satisfaire simultanément - label_singular: Condition à satisfaire - name: conditions - default: [] - widget: list - collapsed: false - types: - - *field_formation_sanitaire_social - - *field_age - - label: En recherche d'emploi - name: chomeur - widget: object - fields: - - label: Conditions à satisfaire simultanément - label_singular: Condition à satisfaire - name: conditions - default: [] - widget: list - collapsed: false - types: - - *field_age - - label: Salarié ou salariée - name: salarie - widget: object - fields: - - label: Conditions à satisfaire simultanément - label_singular: Condition à satisfaire - name: conditions - default: [] - widget: list - collapsed: false - types: - - *field_age - - label: Travailleur indépendant ou travailleuse indépendante - name: independant - widget: object - fields: - - label: Conditions à satisfaire simultanément - label_singular: Condition à satisfaire - name: conditions - default: [] - widget: list - collapsed: false - types: - - *field_age - - label: En service civique - name: service_civique - widget: object - fields: - - label: Conditions à satisfaire simultanément - label_singular: Condition à satisfaire - name: conditions - default: [] - widget: list - collapsed: false - types: - - *field_age - - label: Bénéficiaire RSA - name: beneficiaire_rsa - widget: object - fields: - - label: Conditions à satisfaire simultanément - label_singular: Condition à satisfaire - name: conditions - default: [] - widget: list - collapsed: false - types: - - *field_age - - label: En situation de handicap - name: situation_handicap - widget: object + - { label: 'Name', name: 'name', widget: 'string', hint: 'First and Last' } + - { label: 'Description', name: 'description', widget: 'markdown' } + + - name: 'faq' # Used in routes, ie.: /admin/collections/:slug/edit + label: 'FAQ' # Used in the UI + folder: '_faqs' + create: true # Allow users to create new documents in this collection + fields: # The fields each document in this collection have + - { label: 'Question', name: 'title', widget: 'string', tagname: 'h1' } + - { label: 'Answer', name: 'body', widget: 'markdown' } + + - name: 'settings' + label: 'Settings' + delete: false # Prevent users from deleting documents in this collection + editor: + preview: false + files: + - name: 'general' + label: 'Site Settings' + file: '_data/settings.json' + description: 'General Site Settings' fields: - - label: Conditions à satisfaire simultanément - label_singular: Condition à satisfaire - name: conditions - default: [] - widget: list - collapsed: false - types: - - *field_taux_incapacite - - label: Inactif ou inactive - name: inactif - widget: object + - { label: 'Global title', name: 'site_title', widget: 'string' } + - label: 'Post Settings' + name: posts + widget: 'object' + fields: + - { + label: 'Number of posts on frontpage', + name: front_limit, + widget: number, + min: 1, + max: 10, + } + - { label: 'Default Author', name: author, widget: string } + - { + label: 'Default Thumbnail', + name: thumb, + widget: image, + class: 'thumb', + required: false, + } + + - name: 'authors' + label: 'Authors' + file: '_data/authors.yml' + description: 'Author descriptions' fields: - - label: Conditions à satisfaire simultanément - label_singular: Condition à satisfaire - name: conditions - default: [] + - name: authors + label: Authors + label_singular: 'Author' widget: list - collapsed: false - types: - - *field_age - field_private_benefit: &field_private_benefit - label: Masquer l'aide - name: private - required: false - widget: hidden - field_benefit_partial_support: &field_benefit_partial_support - label: L'aide ne couvre qu'une partie des frais - name: participation - widget: hidden - field_benefit_id: &field_benefit_id - name: id - widget: hidden - field_benefit_source: &field_benefit_source - name: source - widget: hidden - field_not_operator: &field_not_operator - name: not - widget: hidden - field_voluntary_conditions: &field_voluntary_conditions - label: Conditions bénévoles à satisfaire - name: voluntary_conditions - hint: Un lien dynamique vers la plateforme jeveuxaider.gouv.fr s'ajoutera à la suite de la dernière condition pour orienter l'utilisateur vers des organismes de bénévolat à proximité - required: false - widget: list - collapsed: false - field: - label: Texte - name: text - widget: string - pattern: - [ - '\.$', - "La condition doit commencer par un verbe à l'infinitif et se terminer par un point", - ] - field_teleservice_prefill: &field_teleservice_prefill - name: teleservicePrefill - widget: hidden - # champs propre aux aides javascript - field_general_conditions: &field_general_conditions - label: Conditions générales à satisfaire simultanément - label_singular: Condition générale à satisfaire - name: conditions_generales - default: [] - widget: list - collapsed: false - types: - - *field_age - - *field_regions - - *field_departements - - *field_epcis - - *field_excluded_epcis - - *field_communes - - *field_regime_securite_sociale - - *field_quotient_familial - - *field_formation_sanitaire_social - - *field_beneficiaire_rsa - - *field_attached_to_institution - - *field_statut_occupation_logement - - *field_not_operator - - *field_difficultes_acces_ou_frais_logement - - *field_agence_travail_temporaire - # champs propre aux aides openfisca - field_benefit_position: &field_benefit_position - label: Pondération de l'aide sur la page de résultat - name: top - widget: hidden - field_benefit_warning_message: &field_benefit_warning_message - label: Affiche un message d'avertissement spécifique - name: warning - widget: hidden - field_openfisca_eligibility_source: &openfisca_eligibility_source - label: Référence à la règle de calcul OpenFisca - name: openfisca_eligibility_source - widget: hidden - field_benefit_teleservices: &field_benefit_teleservices - label: Liens vers plusieurs téléservices - name: teleservices - widget: hidden - field_benefit_ressources_year_minus_two: &field_benefit_ressources_year_minus_two - label: Aide calculée en fonction des revenus N-2 - name: isBaseRessourcesYearMinusTwo - widget: hidden - field_benefit_msa_specific: &field_benefit_msa_specific - label: Aide restreinte aux usagers de la MSA - name: msa - widget: hidden - field_benefit_institution: &field_benefit_institution - label: Référence aux types de lieux à proximité supervisant l'aide - name: lieuxTypes - widget: hidden - field_benefit_set_to_zero_recently: &field_benefit_set_to_zero_recently - label: L'aide OpenFisca a été remise à zéro récemment - name: setToZeroRecently - widget: hidden - field_benefit_capital_dependant: &field_benefit_capital_dependant - label: L'attribution de l'aide est dépendante du capital personnel - name: isBaseRessourcesPatrimoine - widget: hidden - field_benefit_openfisca_mapping: &field_benefit_openfisca_mapping - label: Identifiant OpenFisca de l'aide - name: openfisca_eligibility_source - widget: hidden + fields: + - { label: 'Name', name: 'name', widget: 'string', hint: 'First and Last' } + - { label: 'Description', name: 'description', widget: 'markdown' } -collections: - - name: benefits_javascript - label: Aides avec critères d'éligibilités - label_singular: Aide avec critères d'éligibilités - identifier_field: label - folder: 'data/benefits/javascript' - create: true - delete: false - editor: - preview: true - slug: '{{fields.institution}}-{{label}}' - summary: '{{label}} ({{fields.institution}})' - extension: yml - fields: - - *field_benefit_name - - *field_benefit_image - - *field_institution - - *field_description - - *field_definite_article - - *field_general_conditions - - *field_voluntary_conditions - - *field_eligibility_profile - - *field_unmodeled_conditions - - *field_specific_interest - - *field_result_type - - *field_result_unit - - *field_benefit_amount_periodicity - - *field_amount_legend - - *field_benefit_max_amount - - *field_link_information - - *field_link_teleservice - - *field_link_form - - *field_link_instructions - - *field_amount_reliability - # hidden fields - - *field_benefit_position - - *field_private_benefit - - *field_benefit_partial_support - - *field_benefit_id - - *field_benefit_source - - *field_teleservice_prefill - - name: benefits_openfisca - label: Aides complexes - label_singular: Aide complexe - identifier_field: label - folder: 'data/benefits/openfisca' - create: true - delete: false - editor: - preview: true - slug: '{{label}}' - extension: yml - fields: - - *field_benefit_name - - *field_benefit_image - - *field_institution - - *field_description - - *field_definite_article - - *field_unmodeled_conditions - - *field_voluntary_conditions - - *field_specific_interest - - *field_result_type - - *field_result_unit - - *field_benefit_amount_periodicity - - *field_amount_legend - - *field_link_information - - *field_link_teleservice - - *field_link_form - - *field_link_instructions - - *field_amount_reliability - - *field_openfisca_linked_entity - - *field_openfisca_period - - *field_private_benefit - # hidden fields - - *field_benefit_position - - *field_benefit_warning_message - - *field_benefit_teleservices - - *field_benefit_ressources_year_minus_two - - *field_benefit_msa_specific - - *field_benefit_partial_support - - *field_benefit_institution - - *field_benefit_set_to_zero_recently - - *field_benefit_capital_dependant - - *field_benefit_openfisca_mapping - - *field_teleservice_prefill - - name: institutions - label: Institutions - label_singular: institution - identifier_field: name - folder: 'data/institutions' + - name: 'kitchenSink' # all the things in one entry, for documentation and quick testing + label: 'Kitchen Sink' + folder: '_sink' create: true - delete: false - editor: - preview: false - slug: '{{name}}' - extension: yml fields: - - label: Nom de votre institution - hint: Département de la Gironde, Ville de Canéjan, Mauges Communauté, etc. - name: name - widget: string - - label: Logo - name: imgSrc - widget: image - allow_multiple: false - pattern: ['(\.png|\.jpg|\.jpeg)', 'Seul les images au format JPG et PNG sont supportées'] - - label: Type d'institution - name: type - widget: relation - collection: institution_types - value_field: '{{slug}}' - display_fields: [name] - search_fields: [slug, name] - - label: Code INSEE - hint: Pour les communes, départements, régions - name: code_insee - widget: string - required: false - required_group: identifier - - label: Code SIREN - hint: En cas de doute, il est possible de rechercher sur https://annuaire-entreprises.data.gouv.fr - name: code_siren - widget: string - required: false - required_group: identifier - - label: Article défini - name: prefix - widget: hidden - required: false - - label: Types de lieux à proximité - name: lieuxTypes - widget: hidden - required: false - - label: repository - name: repository - widget: hidden - required: false - - label: Départements - name: departments - widget: hidden - required: false - - *field_benefit_position - - name: institution_types - label: Types d'institution - label_singular: Type d'institution - identifier_field: name - folder: 'data/institution_types' + - label: 'Related Post' + name: 'post' + widget: 'relationKitchenSinkPost' + collection: 'posts' + display_fields: ['title', 'datetime'] + search_fields: ['title', 'body'] + value_field: 'title' + - { label: 'Title', name: 'title', widget: 'string' } + - { label: 'Boolean', name: 'boolean', widget: 'boolean', default: true } + - { label: 'Map', name: 'map', widget: 'map' } + - { label: 'Text', name: 'text', widget: 'text', hint: 'Plain text, not markdown' } + - { label: 'Number', name: 'number', widget: 'number', hint: 'To infinity and beyond!' } + - { label: 'Markdown', name: 'markdown', widget: 'markdown' } + - { label: 'Datetime', name: 'datetime', widget: 'datetime' } + - { label: 'Image', name: 'image', widget: 'image' } + - { label: 'File', name: 'file', widget: 'file' } + - { label: 'Select', name: 'select', widget: 'select', options: ['a', 'b', 'c'] } + - { + label: 'Select multiple', + name: 'select_multiple', + widget: 'select', + options: ['a', 'b', 'c'], + multiple: true, + } + - { label: 'Hidden', name: 'hidden', widget: 'hidden', default: 'hidden' } + - { label: 'Color', name: 'color', widget: 'color' } + - label: 'Object' + name: 'object' + widget: 'object' + collapsed: true + fields: + - label: 'Related Post' + name: 'post' + widget: 'relationKitchenSinkPost' + collection: 'posts' + search_fields: ['title', 'body'] + value_field: 'title' + - { label: 'String', name: 'string', widget: 'string' } + - { label: 'Boolean', name: 'boolean', widget: 'boolean', default: false } + - { label: 'Text', name: 'text', widget: 'text' } + - { label: 'Number', name: 'number', widget: 'number' } + - { label: 'Markdown', name: 'markdown', widget: 'markdown' } + - { label: 'Datetime', name: 'datetime', widget: 'datetime' } + - { label: 'Image', name: 'image', widget: 'image' } + - { label: 'File', name: 'file', widget: 'file' } + - { label: 'Select', name: 'select', widget: 'select', options: ['a', 'b', 'c'] } + - label: 'List' + name: 'list' + widget: 'list' + fields: + - { label: 'String', name: 'string', widget: 'string' } + - { label: 'Boolean', name: 'boolean', widget: 'boolean' } + - { label: 'Text', name: 'text', widget: 'text' } + - { label: 'Number', name: 'number', widget: 'number' } + - { label: 'Markdown', name: 'markdown', widget: 'markdown' } + - { label: 'Datetime', name: 'datetime', widget: 'datetime' } + - { label: 'Image', name: 'image', widget: 'image' } + - { label: 'File', name: 'file', widget: 'file' } + - { label: 'Select', name: 'select', widget: 'select', options: ['a', 'b', 'c'] } + - label: 'Object' + name: 'object' + widget: 'object' + fields: + - { label: 'String', name: 'string', widget: 'string' } + - { label: 'Boolean', name: 'boolean', widget: 'boolean' } + - { label: 'Text', name: 'text', widget: 'text' } + - { label: 'Number', name: 'number', widget: 'number' } + - { label: 'Markdown', name: 'markdown', widget: 'markdown' } + - { label: 'Datetime', name: 'datetime', widget: 'datetime' } + - { label: 'Image', name: 'image', widget: 'image' } + - { label: 'File', name: 'file', widget: 'file' } + - { label: 'Select', name: 'select', widget: 'select', options: ['a', 'b', 'c'] } + - label: 'List' + name: 'list' + widget: 'list' + fields: + - label: 'Related Post' + name: 'post' + widget: 'relationKitchenSinkPost' + collection: 'posts' + search_fields: ['title', 'body'] + value_field: 'title' + - { label: 'String', name: 'string', widget: 'string' } + - { label: 'Boolean', name: 'boolean', widget: 'boolean' } + - { label: 'Text', name: 'text', widget: 'text' } + - { label: 'Number', name: 'number', widget: 'number' } + - { label: 'Markdown', name: 'markdown', widget: 'markdown' } + - { label: 'Datetime', name: 'datetime', widget: 'datetime' } + - { label: 'Image', name: 'image', widget: 'image' } + - { label: 'File', name: 'file', widget: 'file' } + - { label: 'Select', name: 'select', widget: 'select', options: ['a', 'b', 'c'] } + - { label: 'Hidden', name: 'hidden', widget: 'hidden', default: 'hidden' } + - label: 'Object' + name: 'object' + widget: 'object' + fields: + - { label: 'String', name: 'string', widget: 'string' } + - { label: 'Boolean', name: 'boolean', widget: 'boolean' } + - { label: 'Text', name: 'text', widget: 'text' } + - { label: 'Number', name: 'number', widget: 'number' } + - { label: 'Markdown', name: 'markdown', widget: 'markdown' } + - { label: 'Datetime', name: 'datetime', widget: 'datetime' } + - { label: 'Image', name: 'image', widget: 'image' } + - { label: 'File', name: 'file', widget: 'file' } + - { + label: 'Select', + name: 'select', + widget: 'select', + options: ['a', 'b', 'c'], + } + - label: 'Typed List' + name: 'typed_list' + widget: 'list' + types: + - label: 'Type 1 Object' + name: 'type_1_object' + widget: 'object' + fields: + - { label: 'String', name: 'string', widget: 'string' } + - { label: 'Boolean', name: 'boolean', widget: 'boolean' } + - { label: 'Text', name: 'text', widget: 'text' } + - label: 'Type 2 Object' + name: 'type_2_object' + widget: 'object' + fields: + - { label: 'Number', name: 'number', widget: 'number' } + - { label: 'Select', name: 'select', widget: 'select', options: ['a', 'b', 'c'] } + - { label: 'Datetime', name: 'datetime', widget: 'datetime' } + - { label: 'Markdown', name: 'markdown', widget: 'markdown' } + - label: 'Type 3 Object' + name: 'type_3_object' + widget: 'object' + fields: + - { label: 'Image', name: 'image', widget: 'image' } + - { label: 'File', name: 'file', widget: 'file' } + - name: pages # a nested collection + label: Pages + label_singular: 'Page' + folder: _pages create: true - delete: false - editor: - preview: false - slug: '{{name}}' - extension: yml + nested: { depth: 100 } fields: - - label: Nom de votre type d'institution - hint: Commune, EPCI, CAF, MSA, autres, etc. - name: name + - label: Title + name: title widget: string + meta: { path: { widget: string, label: 'Path', index_file: 'index' } } diff --git a/dev-test/index.html b/dev-test/index.html index a0f5acc64e77..8147bcc0118d 100644 --- a/dev-test/index.html +++ b/dev-test/index.html @@ -1,14 +1,242 @@ - + - - - Decap CMS - - - - - + + + + Decap CMS Development Test + + + + + + + From a35722e635070cfc0dc166e82ff426381bca4d75 Mon Sep 17 00:00:00 2001 From: Thomas Guillet Date: Fri, 19 Apr 2024 14:21:41 +0200 Subject: [PATCH 4/6] refactor: successfully run npm run type-check --- .../src/implementation.ts | 114 ++++++++++-------- 1 file changed, 61 insertions(+), 53 deletions(-) diff --git a/packages/decap-cms-backend-git/src/implementation.ts b/packages/decap-cms-backend-git/src/implementation.ts index 68d79470515f..a413b1b03bcc 100644 --- a/packages/decap-cms-backend-git/src/implementation.ts +++ b/packages/decap-cms-backend-git/src/implementation.ts @@ -2,16 +2,29 @@ import git from 'isomorphic-git'; import http from 'isomorphic-git/http/web'; import FS from '@isomorphic-git/lightning-fs'; -import type { Implementation, Config } from 'decap-cms-lib-util'; +import type { + AssetProxy, + Config, + Credentials, + Cursor, + Entry, + Implementation, + ImplementationFile, + PersistOptions, + User, +} from 'decap-cms-lib-util'; const corsProxy = 'https://cors.isomorphic-git.org'; const dir = '/repo'; -let singleton; +let singleton: Promise; -export default function GitProxyBackEndGenerator(T) { +export default function GitProxyBackEndGenerator(T: any) { class GitProxyBackend implements Implementation { backend: Implementation; config: Config; + fs: any; + pfs: any; + repository: Promise; constructor(config: Config, options = {}) { this.backend = new T(config, options); this.config = config; @@ -46,9 +59,8 @@ export default function GitProxyBackEndGenerator(T) { }); await git.checkout({ fs: this.fs, - http, dir, - ref: fetchResult.fetchHead, + ref: fetchResult.fetchHead!, force: true, track: false, }); @@ -59,12 +71,13 @@ export default function GitProxyBackEndGenerator(T) { return true; } - async entriesByFolder(folder: string, extension: string, depth: number) { + async entriesByFolder(folder: string, extension: string) { try { + await this.repository; const files = await this.pfs.readdir(`${dir}/${folder}`); - const relevantFiles = files.filter(name => name.endsWith(extension)); + const relevantFiles = files.filter((name: string) => name.endsWith(extension)); return Promise.all( - relevantFiles.map(async filename => { + relevantFiles.map(async (filename: string) => { const path = `${folder}/${filename}`; const fullPath = `${dir}/${path}`; const data = await this.pfs.readFile(fullPath, 'utf8'); @@ -79,6 +92,7 @@ export default function GitProxyBackEndGenerator(T) { } } async getEntry(path: string) { + await this.repository; const data = await this.pfs.readFile(`${dir}/${path}`, 'utf8'); return { file: { path, id: null }, @@ -86,74 +100,68 @@ export default function GitProxyBackEndGenerator(T) { }; } - status(...args) { - return this.backend.status(...args); + status() { + return this.backend.status(); } - authComponent(...args) { - return this.backend.authComponent(...args); + authComponent() { + return this.backend.authComponent(); } - restoreUser(...args) { - return this.backend.restoreUser(...args); + restoreUser(user: User) { + return this.backend.restoreUser(user); } - authenticate(...args) { - return this.backend.authenticate(...args); + authenticate(credentials: Credentials) { + return this.backend.authenticate(credentials); } logout() { - return this.backend.logout(...args); + return this.backend.logout(); } - getToken(...args) { - return this.backend.getToken(...args); + getToken() { + return this.backend.getToken(); } - traverseCursor(...args) { - return this.backend.traverseCursor(...args); + traverseCursor(cursor: Cursor, action: string) { + return this.backend.traverseCursor!(cursor, action); } - entriesByFiles(...args) { - return this.backend.entriesByFiles(...args); + entriesByFiles(files: ImplementationFile[]) { + return this.backend.entriesByFiles(files); } - unpublishedEntries(...args) { - return this.backend.unpublishedEntries(...args); + unpublishedEntries() { + return this.backend.unpublishedEntries(); } - unpublishedEntry(...args) { - return this.backend.unpublishedEntry(...args); + unpublishedEntry(args: { id?: string; collection?: string; slug?: string }) { + return this.backend.unpublishedEntry(args); } - unpublishedEntryDataFile(...args) { - return this.backend.unpublishedEntryDataFile(...args); + unpublishedEntryDataFile(collection: string, slug: string, path: string, id: string) { + return this.backend.unpublishedEntryDataFile(collection, slug, path, id); } - unpublishedEntryMediaFile(...args) { - return this.backend.unpublishedEntryMediaFile(...args); + unpublishedEntryMediaFile(collection: string, slug: string, path: string, id: string) { + return this.backend.unpublishedEntryMediaFile(collection, slug, path, id); } deleteUnpublishedEntry(collection: string, slug: string) { return this.backend.deleteUnpublishedEntry(collection, slug); } - addOrUpdateUnpublishedEntry(...args) { - return this.backend.addOrUpdateUnpublishedEntry(...args); - } - persistEntry(...args) { - return this.backend.persistEntry(...args); - } - updateUnpublishedEntryStatus(...args) { - return this.backend.updateUnpublishedEntryStatus(...args); + persistEntry(entry: Entry, opts: PersistOptions) { + return this.backend.persistEntry(entry, opts); } - publishUnpublishedEntry(...args) { - return this.backend.publishUnpublishedEntry(...args); + updateUnpublishedEntryStatus(collection: string, slug: string, newStatus: string) { + return this.backend.updateUnpublishedEntryStatus(collection, slug, newStatus); } - getMedia(...args) { - return this.backend.getMedia(...args); + publishUnpublishedEntry(collection: string, slug: string) { + return this.backend.publishUnpublishedEntry(collection, slug); } - getMediaFile(...args) { - return this.backend.getMediaFile(...args); + getMedia(folder?: string) { + return this.backend.getMedia(folder); } - normalizeAsset(...args) { - return this.backend.normalizeAsset(...args); + getMediaFile(path: string) { + return this.backend.getMediaFile(path); } - persistMedia(...args) { - return this.backend.persistMedia(...args); + persistMedia(file: AssetProxy, opts: PersistOptions) { + return this.backend.persistMedia(file, opts); } - deleteFiles(...args) { - return this.backend.deleteFiles(...args); + deleteFiles(paths: string[], commitMessage: string) { + return this.backend.deleteFiles(paths, commitMessage); } - getDeployPreview(...args) { - return this.backend.getDeployPreview(...args); + getDeployPreview(collectionName: string, slug: string) { + return this.backend.getDeployPreview(collectionName, slug); } } return GitProxyBackend; From 383cd75b22514741e72a42be564f302b39b0af80 Mon Sep 17 00:00:00 2001 From: Thomas Guillet Date: Fri, 19 Apr 2024 18:42:30 +0200 Subject: [PATCH 5/6] refactor: remove hardcoded links and values --- .../src/implementation.ts | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/packages/decap-cms-backend-git/src/implementation.ts b/packages/decap-cms-backend-git/src/implementation.ts index a413b1b03bcc..1d701ee94452 100644 --- a/packages/decap-cms-backend-git/src/implementation.ts +++ b/packages/decap-cms-backend-git/src/implementation.ts @@ -18,18 +18,32 @@ const corsProxy = 'https://cors.isomorphic-git.org'; const dir = '/repo'; let singleton: Promise; +function determineRepositoryURL(backend: any): string { + const name = backend.name as string; // TOOD consolidate CmsConfig and Config + if (name.startsWith('github')) { + return `https://github.com/${backend.repo}.git`; + } else if (name.startsWith('gitlab')) { + return `https://gitlab.com/${backend.repo}.git`; + } else if (name.startsWith('git-gateway')) { + return backend.repo!; + } + throw new Error("Can't determine repository URL"); +} + export default function GitProxyBackEndGenerator(T: any) { class GitProxyBackend implements Implementation { backend: Implementation; config: Config; fs: any; pfs: any; + repositoryUrl: string; repository: Promise; constructor(config: Config, options = {}) { this.backend = new T(config, options); this.config = config; this.fs = new FS('decapfs'); this.pfs = this.fs.promises; + this.repositoryUrl = determineRepositoryURL(config.backend); if (!singleton) { singleton = this.getRepository(); } @@ -37,6 +51,7 @@ export default function GitProxyBackEndGenerator(T: any) { } async getRepository() { + const branch = this.config.backend.branch || 'main'; try { await this.pfs.stat(dir); } catch (e) { @@ -44,23 +59,30 @@ export default function GitProxyBackEndGenerator(T: any) { await git.init({ fs: this.fs, dir, - defaultBranch: 'main', + defaultBranch: branch, }); } - const fetchResult = await git.fetch({ + await git.addRemote({ + fs: this.fs, + dir, + url: this.repositoryUrl, + remote: 'origin', + force: true, + }); + await git.fetch({ fs: this.fs, http, dir, corsProxy, - url: 'https://github.com/betagouv/aides-jeunes', - ref: 'main', + remote: 'origin', + ref: branch, singleBranch: true, depth: 1, }); await git.checkout({ fs: this.fs, dir, - ref: fetchResult.fetchHead!, + ref: branch, force: true, track: false, }); From 4e6e1e59b4dbe73cb854c1ce0576b63ee314be15 Mon Sep 17 00:00:00 2001 From: Thomas Guillet Date: Mon, 22 Apr 2024 10:56:52 +0200 Subject: [PATCH 6/6] refactor: add error message with guidance for git-gateway config --- packages/decap-cms-backend-git/src/implementation.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/decap-cms-backend-git/src/implementation.ts b/packages/decap-cms-backend-git/src/implementation.ts index 1d701ee94452..cf7a1af56025 100644 --- a/packages/decap-cms-backend-git/src/implementation.ts +++ b/packages/decap-cms-backend-git/src/implementation.ts @@ -25,6 +25,11 @@ function determineRepositoryURL(backend: any): string { } else if (name.startsWith('gitlab')) { return `https://gitlab.com/${backend.repo}.git`; } else if (name.startsWith('git-gateway')) { + if (!backend.repo) { + throw new Error( + "Repository URL mandatory for 'git-gateway' configuration (https://[...]/repoName.git)", + ); + } return backend.repo!; } throw new Error("Can't determine repository URL");