├── .buildkite ├── certs │ ├── README.md │ ├── ca.crt │ ├── ca.key │ ├── testnode.crt │ ├── testnode.key │ ├── testnode_no_san.crt │ └── testnode_no_san.key ├── functions │ ├── cleanup.sh │ ├── imports.sh │ └── wait-for-container.sh ├── pipeline.yaml ├── run-elasticsearch.sh ├── run-enterprise-search.sh ├── run-local.sh ├── run-repository.sh └── run-tests ├── .ci ├── .gitignore ├── Dockerfile ├── make.mjs └── make.sh ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE.md ├── ISSUE_TEMPLATE │ ├── bug.md │ ├── feature.md │ ├── question.md │ ├── regression.md │ └── security.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── backport.yml │ ├── comment-on-asciidoc-changes.yml │ ├── nodejs.yml │ └── universal.yml ├── .gitignore ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── NOTICE.txt ├── README.md ├── catalog-info.yaml ├── lerna.json ├── package.json └── packages ├── enterprise-search-universal ├── .airtap.yml ├── .npmignore ├── LICENSE ├── NOTICE.txt ├── README.md ├── docs │ ├── app-api.asciidoc │ ├── changelog.asciidoc │ ├── connecting.asciidoc │ ├── index.asciidoc │ ├── installation.asciidoc │ ├── overview.asciidoc │ └── workplace-api.asciidoc ├── package.json ├── src │ ├── app-types.ts │ ├── client.ts │ └── workplace-types.ts ├── test │ ├── browser │ │ └── basic.test.js │ ├── node │ │ └── basic.test.ts │ └── utils │ │ └── server.js └── tsconfig.json └── enterprise-search ├── .npmignore ├── LICENSE ├── NOTICE.txt ├── README.md ├── docs ├── app-search-api.asciidoc ├── enterprise-search-api.asciidoc ├── index.asciidoc ├── installation.asciidoc ├── overview.asciidoc ├── release-notes │ ├── 8-6-0.asciidoc │ ├── 8-6-1.asciidoc │ └── index.asciidoc └── workplace-search-api.asciidoc ├── index.d.ts ├── index.js ├── package.json ├── src ├── AppSearchClient.ts ├── EnterpriseSearchClient.ts ├── Serializer.ts ├── WorkplaceSearchClient.ts ├── api │ ├── app │ │ ├── api.ts │ │ └── types.ts │ ├── enterprise │ │ ├── api.ts │ │ └── types.ts │ └── workplace │ │ ├── api.ts │ │ └── types.ts ├── index.ts ├── symbols.ts └── utils.ts ├── test ├── fixtures │ ├── elastic-enterprise-search-logo.png │ └── icon.png ├── integration │ ├── app │ │ ├── api-key.test.ts │ │ ├── api-logs.test.ts │ │ ├── count-analytics.test.ts │ │ ├── crawl-request.test.ts │ │ ├── crawl-rule.test.ts │ │ ├── crawler-domain.test.ts │ │ ├── crawler-entry-point.test.ts │ │ ├── crawler-metrics.test.ts │ │ ├── crawler-overview.test.ts │ │ ├── crawler-process-crawl-denied-urls.test.ts │ │ ├── crawler-process-crawl.test.ts │ │ ├── crawler-scheduling.test.ts │ │ ├── crawler-sitemap.test.ts │ │ ├── crawler-urls.test.ts │ │ ├── crawler-user-agent.test.ts │ │ ├── curations.test.ts │ │ ├── documents.test.ts │ │ ├── engines.test.ts │ │ ├── log-clickthrough.test.ts │ │ ├── meta-engines.test.ts │ │ ├── query-suggestion.test.ts │ │ ├── schema.test.ts │ │ ├── search-settings.test.ts │ │ ├── synonyms.test.ts │ │ ├── top-clicks-analytics.test.ts │ │ └── top-queries-analytics.test.ts │ ├── enterprise │ │ └── index.test.ts │ ├── helper.ts │ └── workplace │ │ ├── content-sources.test.ts │ │ ├── documents.test.ts │ │ ├── external-identities.test.ts │ │ ├── synonym.sets.test.ts │ │ ├── triggers.test.ts │ │ └── users.test.ts └── unit │ └── serializer.test.ts └── tsconfig.json /.buildkite/certs/README.md: -------------------------------------------------------------------------------- 1 | # CI certificates 2 | 3 | This directory contains certificates that can be used to test against Elasticsearch in CI 4 | 5 | ## Generating new certificates using the Certificate Authority cert and key 6 | 7 | The `ca.crt` and `ca.key` can be used to generate any other certificates that may be needed 8 | for CI. Perhaps the easiest way to do so is using 9 | [`elasticsearch-certutil`](https://www.elastic.co/guide/en/elasticsearch/reference/current/certutil.html) 10 | 11 | Using the elasticsearch docker container, run the following from the `.ci/certs` directory 12 | 13 | ```sh 14 | docker run \ 15 | -v "$PWD:/var/tmp" \ 16 | --rm docker.elastic.co/elasticsearch/elasticsearch:7.6.1 \ 17 | ./bin/elasticsearch-certutil cert \ 18 | --ca-cert /var/tmp/ca.crt --ca-key /var/tmp/ca.key --pem \ 19 | --out /var/tmp/bundle.zip 20 | ``` 21 | 22 | This will output a `bundle.zip` file containing a directory named `instance` containing 23 | `instance.crt` and `instance.key` in PEM format. 24 | 25 | The CN Subject name can be changed using 26 | 27 | ```sh 28 | docker run \ 29 | -v "$PWD:/var/tmp" \ 30 | --rm docker.elastic.co/elasticsearch/elasticsearch:7.6.1 \ 31 | ./bin/elasticsearch-certutil cert \ 32 | --ca-cert /var/tmp/ca.crt --ca-key /var/tmp/ca.key --pem \ 33 | --out /var/tmp/bundle.zip \ 34 | --name foo 35 | ``` 36 | 37 | The directory in `bundle.zip` will now be named `foo` and contain 38 | `foo.crt` and `foo.key` in PEM format. 39 | 40 | Additional DNS and IP SAN entries can be added with `--dns` and `--ip`, respectively. 41 | 42 | ```sh 43 | docker run \ 44 | -v "$PWD:/var/tmp" \ 45 | --rm docker.elastic.co/elasticsearch/elasticsearch:7.6.1 \ 46 | ./bin/elasticsearch-certutil cert \ 47 | --ca-cert /var/tmp/ca.crt --ca-key /var/tmp/ca.key --pem \ 48 | --out /var/tmp/bundle.zip \ 49 | --dns instance --dns localhost --dns es1 --ip 127.0.0.1 --ip ::1 50 | ``` 51 | -------------------------------------------------------------------------------- /.buildkite/certs/ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDSjCCAjKgAwIBAgIVAJQLm8V2LcaCTHUcoIfO+KL63nG3MA0GCSqGSIb3DQEB 3 | CwUAMDQxMjAwBgNVBAMTKUVsYXN0aWMgQ2VydGlmaWNhdGUgVG9vbCBBdXRvZ2Vu 4 | ZXJhdGVkIENBMB4XDTIwMDIyNjA1NTA1N1oXDTIzMDIyNTA1NTA1N1owNDEyMDAG 5 | A1UEAxMpRWxhc3RpYyBDZXJ0aWZpY2F0ZSBUb29sIEF1dG9nZW5lcmF0ZWQgQ0Ew 6 | ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDYyajkPvGtUOE5M1OowQfB 7 | kWVrWjo1+LIxzgCeRHp0YztLtdVJ0sk2xoSrt2uZpxcPepdyOseLTjFJex1D2yCR 8 | AEniIqcFif4G72nDih2LlbhpUe/+/MTryj8ZTkFTzI+eMmbQi5FFMaH+kwufmdt/ 9 | 5/w8YazO18SxxJUlzMqzfNUrhM8vvvVdxgboU7PWhk28wZHCMHQovomHmzclhRpF 10 | N0FMktA98vHHeRjH19P7rNhifSd7hZzoH3H148HVAKoPgqnZ6vW2O2YfAWOP6ulq 11 | cyszr57p8fS9B2wSdlWW7nVHU1JuKcYD67CxbBS23BeGFgCj4tiNrmxO8S5Yf85v 12 | AgMBAAGjUzBRMB0GA1UdDgQWBBSWAlip9eoPmnG4p4OFZeOUBlAbNDAfBgNVHSME 13 | GDAWgBSWAlip9eoPmnG4p4OFZeOUBlAbNDAPBgNVHRMBAf8EBTADAQH/MA0GCSqG 14 | SIb3DQEBCwUAA4IBAQA19qqrMTWl7YyId+LR/QIHDrP4jfxmrEELrAL58q5Epc1k 15 | XxZLzOBSXoBfBrPdv+3XklWqXrZjKWfdkux0Xmjnl4qul+srrZDLJVZG3I7IrITh 16 | AmQUmL9MuPiMnAcxoGZp1xpijtW8Qmd2qnambbljWfkuVaa4hcVRfrAX6TciIQ21 17 | bS5aeLGrPqR14h30YzDp0RMmTujEa1o6ExN0+RSTkE9m89Q6WdM69az8JW7YkWqm 18 | I+UCG3TcLd3TXmN1zNQkq4y2ObDK4Sxy/2p6yFPI1Fds5w/zLfBOvvPQY61vEqs8 19 | SCCcQIe7f6NDpIRIBlty1C9IaEHj7edyHjF6rtYb 20 | -----END CERTIFICATE----- 21 | -------------------------------------------------------------------------------- /.buildkite/certs/ca.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEpgIBAAKCAQEA2Mmo5D7xrVDhOTNTqMEHwZFla1o6NfiyMc4AnkR6dGM7S7XV 3 | SdLJNsaEq7drmacXD3qXcjrHi04xSXsdQ9sgkQBJ4iKnBYn+Bu9pw4odi5W4aVHv 4 | /vzE68o/GU5BU8yPnjJm0IuRRTGh/pMLn5nbf+f8PGGsztfEscSVJczKs3zVK4TP 5 | L771XcYG6FOz1oZNvMGRwjB0KL6Jh5s3JYUaRTdBTJLQPfLxx3kYx9fT+6zYYn0n 6 | e4Wc6B9x9ePB1QCqD4Kp2er1tjtmHwFjj+rpanMrM6+e6fH0vQdsEnZVlu51R1NS 7 | binGA+uwsWwUttwXhhYAo+LYja5sTvEuWH/ObwIDAQABAoIBAQC8QDGnMnmPdWJ+ 8 | 13FYY3cmwel+FXXjFDk5QpgK15A2rUz6a8XxO1d7d1wR+U84uH4v9Na6XQyWjaoD 9 | EyPQnuJiyAtgkZLUHoY244PGR5NsePEQlBSCKmGeF5w/j1LvP/2e9EmP4wKdQYJY 10 | nLxFNcgEBCFnFbKIU5n8fKa/klybCrwlBokenyBro02tqH4LL7h1YMRRrl97fv1V 11 | e/y/0WcMN+KnMglfz6haimBRV2yamCCHHmBImC+wzOgT/quqlxPfI+a3ScHxuA65 12 | 3QyCavaqlPh+T3lXnN/Na4UWqFtzMmwgJX2x1zM5qiln46/JoDiXtagvV43L3rNs 13 | LhPRFeIRAoGBAPhEB7nNpEDNjIRUL6WpebWS9brKAVY7gYn7YQrKGhhCyftyaiBZ 14 | zYgxPaJdqYXf+DmkWlANGoYiwEs40QwkR/FZrvO4+Xh3n3dgtl59ZmieuoQvDsG+ 15 | RYIj+TfBaqhewhZNMMl7dxz7DeyQhyRCdsvl3VqJM0RuOsIrzrhCIEItAoGBAN+K 16 | lgWI7swDpOEaLmu+IWMkGImh1LswXoZqIgi/ywZ7htZjPzidOIeUsMi+lrYsKojG 17 | uU3sBxASsf9kYXDnuUuUbGT5M/N2ipXERt7klUAA/f5sg1IKlTrabaN/HGs/uNtf 18 | Efa8v/h2VyTurdPCJ17TNpbOMDwX1qGM62tyt2CLAoGBAIHCnP8iWq18QeuQTO8b 19 | a3/Z9hHRL22w4H4MI6aOB6GSlxuTq6CJD4IVqo9IwSg17fnCy2l3z9s4IqWuZqUf 20 | +XJOW8ELd2jdrT2qEOfGR1Z7UCVyqxXcq1vgDYx0zZh/HpalddB5dcJx/c8do2Ty 21 | UEE2PcHqYB9uNcvzNbLc7RtpAoGBALbuU0yePUTI6qGnajuTcQEPpeDjhRHWSFRZ 22 | ABcG1N8uMS66Mx9iUcNp462zgeP8iqY5caUZtMHreqxT+gWKK7F0+as7386pwElF 23 | QPXgO18QMMqHBIQb0vlBjJ1SRPBjSiSDTVEML1DljvTTOX7kEJHh6HdKrmBO5b54 24 | cqMQUo53AoGBAPVWRPUXCqlBz914xKna0ZUh2aesRBg5BvOoq9ey9c52EIU5PXL5 25 | 0Isk8sWSsvhl3tjDPBH5WuL5piKgnCTqkVbEHmWu9s1T57Mw6NuxlPMLBWvyv4c6 26 | tB9brOxv0ui3qGMuBsBoDKbkNnwXyOXLyFg7O+H4l016A3mLQzJM+NGV 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /.buildkite/certs/testnode.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDYjCCAkqgAwIBAgIVAIZQH0fe5U+bGQ6m1JUBO/AQkQ/9MA0GCSqGSIb3DQEB 3 | CwUAMDQxMjAwBgNVBAMTKUVsYXN0aWMgQ2VydGlmaWNhdGUgVG9vbCBBdXRvZ2Vu 4 | ZXJhdGVkIENBMB4XDTIwMDMyNzE5MTcxMVoXDTIzMDMyNzE5MTcxMVowEzERMA8G 5 | A1UEAxMIaW5zdGFuY2UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDB 6 | fco1t1+sE1gTwTVGcXKZqJTP2GjMHM0cfJE5KKfwC5B+pHADRT6FZxvepgKjEBDt 7 | CK+2Rmotyeb15XXMSKguNhyT+2PuKvT5r05L7P91XRYXrwxG2swJPtct7A87xdFa 8 | Ek+YRpqGGmTaux2jOELMiAmqEzoj6w/xFq+LF4SolTW4wOL2eLFkEFHBX2oCwU5T 9 | Q+B+7E9zL45nFWlkeRGJ+ZQTnRNZ/1r4N9A9Gtj4x/H1/y4inWndikdxAb5QiEYJ 10 | T+vbQWzHYWjz13ttHJsz+6T8rvA1jK+buHgVh4K8lV13X9k54soBqHB8va7/KIJP 11 | g8gvd6vusEI7Bmfl1as7AgMBAAGjgYswgYgwHQYDVR0OBBYEFKnnpvuVYwtFSUis 12 | WwN9OHLyExzJMB8GA1UdIwQYMBaAFJYCWKn16g+acbing4Vl45QGUBs0MDsGA1Ud 13 | EQQ0MDKCCWxvY2FsaG9zdIIIaW5zdGFuY2WHBH8AAAGHEAAAAAAAAAAAAAAAAAAA 14 | AAGCA2VzMTAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQAPNsIoD4GBrTgR 15 | jfvBuHS6eU16P95m16O8Mdpr4SMQgWLQUhs8aoVgfwpg2TkbCWxOe6khJOyNm7bf 16 | fW4aFQ/OHcQV4Czz3c7eOHTWSyMlCOv+nRXd4giJZ5TOHw1zKGmKXOIvhvE6RfdF 17 | uBBfrusk164H4iykm0Bbr/wo4d6wuebp3ZYLPw5zV0D08rsaR+3VJ9VxWuFpdm/r 18 | 2onYOohyuX9DRjAczasC+CRRQN4eHJlRfSQB8WfTKw3EloRJJDAg6SJyGiAJ++BF 19 | hnqfNcEyKes2AWagFF9aTbEJMrzMhH+YB5F+S/PWvMUlFzcoocVKqc4pIrjKUNWO 20 | 6nbTxeAB 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /.buildkite/certs/testnode.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEAwX3KNbdfrBNYE8E1RnFymaiUz9hozBzNHHyROSin8AuQfqRw 3 | A0U+hWcb3qYCoxAQ7QivtkZqLcnm9eV1zEioLjYck/tj7ir0+a9OS+z/dV0WF68M 4 | RtrMCT7XLewPO8XRWhJPmEaahhpk2rsdozhCzIgJqhM6I+sP8RavixeEqJU1uMDi 5 | 9nixZBBRwV9qAsFOU0PgfuxPcy+OZxVpZHkRifmUE50TWf9a+DfQPRrY+Mfx9f8u 6 | Ip1p3YpHcQG+UIhGCU/r20Fsx2Fo89d7bRybM/uk/K7wNYyvm7h4FYeCvJVdd1/Z 7 | OeLKAahwfL2u/yiCT4PIL3er7rBCOwZn5dWrOwIDAQABAoIBAFcm4ICnculf4Sks 8 | umFbUiISA81GjZV6V4zAMu1K+bGuk8vnJyjh9JJD6hK0NbXa07TgV7zDJKoxKd2S 9 | GCgGhfIin2asMcuh/6vDIYIjYsErR3stdlsnzAVSD7v4ergSlwR6AO32xz0mAE1h 10 | QK029yeHEstPU72/7/NIo5MD6dXAbut1MzgijZD8RQo1z21D6qmLcPTVTfkn7a3W 11 | MY3y7XUIkA1TOyIRsH3k6F6NBWkvtXbwOUeLCJ14EvS8T9BqhIhPDZv8mQTRLDOD 12 | tQRyC4Cnw+UhYmnMFJhj6N2jpTBv/AdoKcRC56uBJyPW+dxj6i4e7n3pQuxqRvpI 13 | LLJJsskCgYEA4QQxzuJizLKV75rE+Qxg0Ej0Gid1aj3H5eeTZOUhm9KC8KDfPdpk 14 | msKaNzJq/VDcqHPluGS1jYZVgZlal1nk5xKBcbQ4n297VPVd+sLtlf0bj4atlDUO 15 | +iOVo0H7k5yWvj+TzVRlc5zjDLcnQh8i+22o3+65hIrb2zpzg/cCZJ8CgYEA3CJX 16 | bjmWPQ0uZVIa8Wz8cJFtKT9uVl7Z3/f6HjN9I0b/9MmVlNxQVAilVwhDkzR/UawG 17 | QeRFBJ6XWRwX0aoMq+O9VSNu/R2rtEMpIYt3LwbI3yw6GRoCdB5qeL820O+KX5Fl 18 | /z+ZNgrHgA1yKPVf+8ke2ZtLEqPHMN+BMuq8t+UCgYEAy0MfvzQPbbuw55WWcyb0 19 | WZJdNzcHwKX4ajzrj4vP9VOPRtD7eINMt+QsrMnVjei6u0yeahhHTIXZvc2K4Qeq 20 | V/YGinDzaUqqTU+synXFauUOPXO6XxQi6GC2rphPKsOcBFWoLSYc0vgYvgbA5uD7 21 | l8Yyc77RROKuwfWmHcJHHh8CgYBurGFSjGdJWHgr/oSHPqkIG0VLiJV7nQJjBPRd 22 | /Lr8YnTK6BJpHf7Q0Ov3frMirjEYqakXtaExel5TMbmT8q+eN8h3pnHlleY+oclr 23 | EQghv4J8GWs4NYhoQuZ6wH/ZuaTS+XHTS3FG51J3wcrUZtET8ICvHNE4lNjPbH8z 24 | TysENQKBgHER1RtDFdz+O7mlWibrHk8JDgcVdZV/pBF+9cb7r/orkH9RLAHDlsAO 25 | tuSVaQmm5eqgaAxMamBXSyw1lir07byemyuEDg0mJ1rNUGsAY8P+LWr579gvKMme 26 | 5gvrJr99JkBTV3z+TiL7dZa52eW00Ijqg2qcbHGpq3kXWWkbd8Tn 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /.buildkite/certs/testnode_no_san.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDIzCCAgugAwIBAgIVAMTO6uVx9dLox2t0lY4IcBKZXb5WMA0GCSqGSIb3DQEB 3 | CwUAMDQxMjAwBgNVBAMTKUVsYXN0aWMgQ2VydGlmaWNhdGUgVG9vbCBBdXRvZ2Vu 4 | ZXJhdGVkIENBMB4XDTIwMDIyNjA1NTA1OVoXDTIzMDIyNTA1NTA1OVowEzERMA8G 5 | A1UEAxMIaW5zdGFuY2UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDK 6 | YLTOikVENiN/qYupOsoXd7VYYnryyfCC/dK4FC2aozkbqjFzBdvPGAasoc4yEiH5 7 | CGeXMgJuOjk1maqetmdIsw00j4oHJviYsnGXzxxS5swhD7spcW4Uk4V4tAUzrbfT 8 | vW/2WW/yYCLe5phVb2chz0jL+WYb4bBmdfs/t6RtP9RqsplYAmVp3gZ6lt2YNtvE 9 | k9gz0TVk3DuO1TquIClfRYUjuywS6xDSvxJ8Jl91EfDWM8QU+9F+YAtiv74xl2U3 10 | P0wwMqNvMxf9/3ak3lTQGsgO4L6cwbKpVLMMzxSVunZz/sgl19xy3qHHz1Qr2MjJ 11 | /2c2J7vahUL4NPRkjJClAgMBAAGjTTBLMB0GA1UdDgQWBBS2Wn8E2VZv4oenY+pR 12 | O8G3zfQXhzAfBgNVHSMEGDAWgBSWAlip9eoPmnG4p4OFZeOUBlAbNDAJBgNVHRME 13 | AjAAMA0GCSqGSIb3DQEBCwUAA4IBAQAvwPvCiJJ6v9jYcyvYY8I3gP0oCwrylpRL 14 | n91UlgRSHUmuAObyOoVN5518gSV/bTU2SDrstcLkLFxHvnfpoGJoxsQEHuGxwDRI 15 | nhYNd62EKLerehNM/F9ILKmvTh8f6QPCzjUuExTXv+63l2Sr6dBS7FHsGs6UKUYO 16 | llM/y9wMZ1LCuZuBg9RhtgpFXRSgDM9Z7Begu0d/BPX9od/qAeZg9Arz4rwUiCN4 17 | IJOMEBEPi5q1tgeS0Fb1Grpqd0Uz5tZKtEHNKzLG+zSMmkneL62Nk2HsmEFZKwzg 18 | u2pU42UaUE596G6o78s1aLn9ICcElPHTjiuZNSiyuu9IzvFDjGQw 19 | -----END CERTIFICATE----- 20 | -------------------------------------------------------------------------------- /.buildkite/certs/testnode_no_san.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEogIBAAKCAQEAymC0zopFRDYjf6mLqTrKF3e1WGJ68snwgv3SuBQtmqM5G6ox 3 | cwXbzxgGrKHOMhIh+QhnlzICbjo5NZmqnrZnSLMNNI+KByb4mLJxl88cUubMIQ+7 4 | KXFuFJOFeLQFM623071v9llv8mAi3uaYVW9nIc9Iy/lmG+GwZnX7P7ekbT/UarKZ 5 | WAJlad4GepbdmDbbxJPYM9E1ZNw7jtU6riApX0WFI7ssEusQ0r8SfCZfdRHw1jPE 6 | FPvRfmALYr++MZdlNz9MMDKjbzMX/f92pN5U0BrIDuC+nMGyqVSzDM8Ulbp2c/7I 7 | Jdfcct6hx89UK9jIyf9nNie72oVC+DT0ZIyQpQIDAQABAoIBADAh7f7NjgnaInlD 8 | ds8KB3SraPsbeQhzlPtiqRJU4j/MIFH/GYG03AGWQkget67a9y+GmzSvlTpoKKEh 9 | 6h2TXl9BDpv4o6ht0WRn1HJ5tM/Wyqf2WNpTew3zxCPgFPikkXsPrChYPzLTQJfp 10 | GkP/mfTFmxfAOlPZSp4j41zVLYs53eDkAegFPVfKSr1XNNJ3QODLPcIBfxBYsiC9 11 | oU+jRW8xYuj31cEl5k5UqrChJ1rm3mt6cguqXKbISuoSvi13gXI6DccqhuLAU+Kr 12 | ib2XYrRP+pWocZo/pM9WUVoNGtFxfY88sAQtvG6gDKo2AURtFyq84Ow0h9mdixV/ 13 | gRIDPcECgYEA5nEqE3OKuG9WuUFGXvjtn4C0F6JjflYWh7AbX51S4F6LKrW6/XHL 14 | Rg4BtF+XReT7OQ6llsV8kZeUxsUckkgDLzSaA8lysNDV5KkhAWHfRqH//QKFbqZi 15 | JL9t3x63Qt81US8s2hQk3khPYTRM8ZB3xHiXvZYSGC/0x/DxfEO3QJECgYEA4NK5 16 | sxtrat8sFz6SK9nWEKimPjDVzxJ0hxdX4tRq/JdOO5RncawVqt6TNP9gTuxfBvhW 17 | MhJYEsQj8iUoL1dxo9d1eP8HEANNV0iX5OBvJNmgBp+2OyRSyr+PA55+wAxYuAE7 18 | QKaitOjW57fpArNRt2hQyiSzTuqUFRWTWJHCWNUCgYAEurPTXF6vdFGCUc2g61jt 19 | GhYYGhQSpq+lrz6Qksj9o9MVWE9zHh++21C7o+6V16I0RJGva3QoBMVf4vG4KtQt 20 | 5tV2WG8LI+4P2Ey+G4UajP6U8bVNVQrUmD0oBBhcvfn5JY+1Fg6/pRpD82/U0VMz 21 | 7AmpMWhDqNBMPiymkTk0kQKBgCuWb05cSI0ly4SOKwS5bRk5uVFhYnKNH255hh6C 22 | FGP4acB/WzbcqC7CjEPAJ0nl5d6SExQOHmk1AcsWjR3wlCWxxiK5PwNJwJrlhh1n 23 | reS1FKN0H36D4lFQpkeLWQOe4Sx7gKNeKzlr0w6Fx3Uwku0+Gju2tdTdAey8jB6l 24 | 08opAoGAEe1AuR/OFp2xw6V8TH9UHkkpGxy+OrXI6PX6tgk29PgB+uiMu4RwbjVz 25 | 1di1KKq2XecAilVbnyqY+edADxYGbSnci9x5wQRIebfMi3VXKtV8NQBv2as6qwtW 26 | JDcQUWotOHjpdvmfJWWkcBhbAKrgX8ukww00ZI/lC3/rmkGnBBg= 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /.buildkite/functions/cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Shared cleanup routines between different steps 4 | # 5 | # Please source .buildkite/functions/imports.sh as a whole not just this file 6 | # 7 | # Version 1.0.0 8 | # - Initial version after refactor 9 | 10 | function cleanup_volume { 11 | if [[ "$(docker volume ls -q -f name=$1)" ]]; then 12 | echo -e "\033[34;1mINFO:\033[0m Removing volume $1\033[0m" 13 | (docker volume rm "$1") || true 14 | fi 15 | } 16 | function container_running { 17 | if [[ "$(docker ps -q -f name=$1)" ]]; then 18 | return 0; 19 | else return 1; 20 | fi 21 | } 22 | function cleanup_node { 23 | if container_running "$1"; then 24 | echo -e "\033[34;1mINFO:\033[0m Removing container $1\033[0m" 25 | (docker container rm --force --volumes "$1") || true 26 | fi 27 | if [[ -n "$1" ]]; then 28 | echo -e "\033[34;1mINFO:\033[0m Removing volume $1-${suffix}-data\033[0m" 29 | cleanup_volume "$1-${suffix}-data" 30 | fi 31 | } 32 | function cleanup_network { 33 | if [[ "$(docker network ls -q -f name=$1)" ]]; then 34 | echo -e "\033[34;1mINFO:\033[0m Removing network $1\033[0m" 35 | (docker network rm "$1") || true 36 | fi 37 | } 38 | 39 | function cleanup_trap { 40 | status=$? 41 | set +x 42 | if [[ "$DETACH" != "true" ]]; then 43 | echo -e "\033[34;1mINFO:\033[0m clean the network if not detached (start and exit)\033[0m" 44 | cleanup_all_in_network "$1" 45 | fi 46 | # status is 0 or SIGINT 47 | if [[ "$status" == "0" || "$status" == "130" ]]; then 48 | echo -e "\n\033[32;1mSUCCESS run-tests\033[0m" 49 | exit 0 50 | else 51 | echo -e "\n\033[31;1mFAILURE during run-tests\033[0m" 52 | exit ${status} 53 | fi 54 | }; 55 | function cleanup_all_in_network { 56 | 57 | if [[ -z "$(docker network ls -q -f name="^$1\$")" ]]; then 58 | echo -e "\033[34;1mINFO:\033[0m $1 is already deleted\033[0m" 59 | return 0 60 | fi 61 | containers=$(docker network inspect -f '{{ range $key, $value := .Containers }}{{ printf "%s\n" .Name}}{{ end }}' $1) 62 | while read -r container; do 63 | cleanup_node "$container" 64 | done <<< "$containers" 65 | cleanup_network $1 66 | echo -e "\033[32;1mSUCCESS:\033[0m Cleaned up and exiting\033[0m" 67 | }; 68 | -------------------------------------------------------------------------------- /.buildkite/functions/imports.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Sets up all the common variables and imports relevant functions 4 | # 5 | # Version 1.0.1 6 | # - Initial version after refactor 7 | # - Validate STACK_VERSION asap 8 | 9 | function require_stack_version() { 10 | if [[ -z $STACK_VERSION ]]; then 11 | echo -e "\033[31;1mERROR:\033[0m Required environment variable [STACK_VERSION] not set\033[0m" 12 | exit 1 13 | fi 14 | } 15 | 16 | require_stack_version 17 | 18 | if [[ -z $es_node_name ]]; then 19 | # only set these once 20 | set -euo pipefail 21 | export TEST_SUITE=${TEST_SUITE-free} 22 | export SERVICE=${SERVICE-} 23 | export RUNSCRIPTS=${RUNSCRIPTS-} 24 | export DETACH=${DETACH-false} 25 | export CLEANUP=${CLEANUP-false} 26 | 27 | export es_node_name=instance 28 | export elastic_password=changeme 29 | export elasticsearch_image=elasticsearch 30 | export elasticsearch_url=https://elastic:${elastic_password}@${es_node_name}:9200 31 | if [[ $TEST_SUITE != "platinum" ]]; then 32 | export elasticsearch_url=http://${es_node_name}:9200 33 | fi 34 | export external_elasticsearch_url=${elasticsearch_url/$es_node_name/localhost} 35 | export elasticsearch_container="${elasticsearch_image}:${STACK_VERSION}" 36 | 37 | export suffix=rest-test 38 | export moniker=$(echo "$elasticsearch_container" | tr -C "[:alnum:]" '-') 39 | export network_name=${moniker}${suffix} 40 | 41 | export ssl_cert="${script_path}/certs/testnode.crt" 42 | export ssl_key="${script_path}/certs/testnode.key" 43 | export ssl_ca="${script_path}/certs/ca.crt" 44 | 45 | fi 46 | 47 | export script_path=$(dirname $(realpath -s $0)) 48 | source $script_path/functions/cleanup.sh 49 | source $script_path/functions/wait-for-container.sh 50 | trap "cleanup_trap ${network_name}" EXIT 51 | 52 | 53 | if [[ "$CLEANUP" == "true" ]]; then 54 | cleanup_all_in_network $network_name 55 | exit 0 56 | fi 57 | 58 | echo -e "\033[34;1mINFO:\033[0m Creating network $network_name if it does not exist already \033[0m" 59 | docker network inspect "$network_name" > /dev/null 2>&1 || docker network create "$network_name" 60 | 61 | -------------------------------------------------------------------------------- /.buildkite/functions/wait-for-container.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Exposes a routine scripts can call to wait for a container if that container set up a health command 4 | # 5 | # Please source .buildkite/functions/imports.sh as a whole not just this file 6 | # 7 | # Version 1.0.1 8 | # - Initial version after refactor 9 | # - Make sure wait_for_contiainer is silent 10 | 11 | function wait_for_container { 12 | set +x 13 | until ! container_running "$1" || (container_running "$1" && [[ "$(docker inspect -f "{{.State.Health.Status}}" ${1})" != "starting" ]]); do 14 | echo "" 15 | docker inspect -f "{{range .State.Health.Log}}{{.Output}}{{end}}" ${1} 16 | echo -e "\033[34;1mINFO:\033[0m waiting for node $1 to be up\033[0m" 17 | sleep 30; 18 | done; 19 | 20 | # Always show logs if the container is running, this is very useful both on CI as well as while developing 21 | if container_running $1; then 22 | docker logs $1 23 | fi 24 | 25 | if ! container_running $1 || [[ "$(docker inspect -f "{{.State.Health.Status}}" ${1})" != "healthy" ]]; then 26 | cleanup_all_in_network $2 27 | echo 28 | echo -e "\033[31;1mERROR:\033[0m Failed to start $1 in detached mode beyond health checks\033[0m" 29 | echo -e "\033[31;1mERROR:\033[0m dumped the docker log before shutting the node down\033[0m" 30 | return 1 31 | else 32 | echo 33 | echo -e "\033[32;1mSUCCESS:\033[0m Detached and healthy: ${1} on docker network: ${network_name}\033[0m" 34 | return 0 35 | fi 36 | } 37 | -------------------------------------------------------------------------------- /.buildkite/pipeline.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | steps: 3 | - label: ":js: :elastic-enterprise-search:" 4 | agents: 5 | provider: gcp 6 | matrix: 7 | setup: 8 | nodejs: 9 | - "18" 10 | - "20" 11 | stack_version: 12 | - "8.14.0-SNAPSHOT" 13 | env: 14 | NODE_JS_VERSION: "{{ matrix.nodejs }}" 15 | STACK_VERSION: "{{ matrix.stack_version }}" 16 | command: ./.buildkite/run-tests 17 | artifact_paths: "*-junit.xml" 18 | -------------------------------------------------------------------------------- /.buildkite/run-enterprise-search.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Launch one App Search node via the Docker image, 4 | # to form a cluster suitable for running the REST API tests. 5 | # 6 | # Export the STACK_VERSION variable, eg. '8.0.0-SNAPSHOT'. 7 | 8 | # Version 1.1.0 9 | # - Initial version of the run-app-search.sh script 10 | # - Refactored .buildkite version 11 | 12 | script_path=$(dirname $(realpath -s $0)) 13 | source $script_path/functions/imports.sh 14 | set -euo pipefail 15 | 16 | CONTAINER_NAME=${CONTAINER_NAME-app-search} 17 | APP_SEARCH_SECRET_SESSION_KEY=${APP_SEARCH_SECRET_SESSION_KEY-int_test_secret} 18 | 19 | echo -e "\033[34;1mINFO:\033[0m Take down node if called twice with the same arguments (DETACH=true) or on seperate terminals \033[0m" 20 | cleanup_node $CONTAINER_NAME 21 | 22 | http_port=3002 23 | url=http://127.0.0.1:${http_port} 24 | 25 | # Pull the container, retry on failures up to 5 times with 26 | # short delays between each attempt. Fixes most transient network errors. 27 | docker_pull_attempts=0 28 | until [ "$docker_pull_attempts" -ge 5 ] 29 | do 30 | docker pull docker.elastic.co/enterprise-search/enterprise-search:"$STACK_VERSION" && break 31 | docker_pull_attempts=$((docker_pull_attempts+1)) 32 | echo "Failed to pull image, retrying in 10 seconds (retry $docker_pull_attempts/5)..." 33 | sleep 10 34 | done 35 | 36 | echo -e "\033[34;1mINFO:\033[0m Starting container $CONTAINER_NAME \033[0m" 37 | set -x 38 | docker run \ 39 | --name "$CONTAINER_NAME" \ 40 | --network "$network_name" \ 41 | --env "elasticsearch.host=$elasticsearch_url" \ 42 | --env "elasticsearch.username=elastic" \ 43 | --env "elasticsearch.password=$elastic_password" \ 44 | --env "ENT_SEARCH_DEFAULT_PASSWORD=$elastic_password" \ 45 | --env "secret_management.encryption_keys=[$APP_SEARCH_SECRET_SESSION_KEY]" \ 46 | --env "enterprise_search.listen_port=$http_port" \ 47 | --env "log_level=info" \ 48 | --env "hide_version_info=false" \ 49 | --env "worker.threads=2" \ 50 | --env "allow_es_settings_modification=true" \ 51 | --env "JAVA_OPTS=-Xms1g -Xmx2g" \ 52 | --env "elasticsearch.ssl.enabled=true" \ 53 | --env "elasticsearch.ssl.verify=true" \ 54 | --env "elasticsearch.ssl.certificate=/usr/share/app-search/config/certs/testnode.crt" \ 55 | --env "elasticsearch.ssl.certificate_authority=/usr/share/app-search/config/certs/ca.crt" \ 56 | --env "elasticsearch.ssl.key=/usr/share/app-search/config/certs/testnode.key" \ 57 | --volume $ssl_cert:/usr/share/app-search/config/certs/testnode.crt \ 58 | --volume $ssl_key:/usr/share/app-search/config/certs/testnode.key \ 59 | --volume $ssl_ca:/usr/share/app-search/config/certs/ca.crt \ 60 | --publish "$http_port":3002 \ 61 | --detach="$DETACH" \ 62 | --health-cmd="curl --insecure --fail ${url} || exit 1" \ 63 | --health-interval=30s \ 64 | --health-retries=50 \ 65 | --health-timeout=10s \ 66 | --rm \ 67 | docker.elastic.co/enterprise-search/enterprise-search:"$STACK_VERSION"; 68 | 69 | if wait_for_container "$CONTAINER_NAME" "$network_name"; then 70 | echo -e "\033[32;1mSUCCESS:\033[0m Running on: ${url}\033[0m" 71 | fi 72 | -------------------------------------------------------------------------------- /.buildkite/run-local.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | export TEST_SUITE=platinum 4 | export CONTAINER_NAME=enterprise-search 5 | 6 | script_path=$(dirname $(realpath -s $0)) 7 | source $script_path/functions/imports.sh 8 | set -euo pipefail 9 | 10 | echo -e "--- :elasticsearch: Start $STACK_VERSION container" 11 | DETACH=true bash .buildkite/run-elasticsearch.sh 12 | 13 | echo -e "--- Run run-enterprise-search.sh" 14 | bash .buildkite/run-enterprise-search.sh 15 | -------------------------------------------------------------------------------- /.buildkite/run-repository.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Called by entry point `run-test` use this script to add your repository specific test commands 4 | # 5 | # Once called Elasticsearch is up and running 6 | # 7 | # Its recommended to call `imports.sh` as defined here so that you get access to all variables defined there 8 | # 9 | # Any parameters that test-matrix.yml defines should be declared here with appropiate defaults 10 | 11 | script_path=$(dirname $(realpath -s $0)) 12 | source $script_path/functions/imports.sh 13 | set -euo pipefail 14 | 15 | echo -e "\033[34;1mINFO:\033[0m VERSION: ${STACK_VERSION}\033[0m" 16 | echo -e "\033[34;1mINFO:\033[0m TEST_SUITE: ${TEST_SUITE}\033[0m" 17 | echo -e "\033[34;1mINFO:\033[0m NODE_JS_VERSION: ${NODE_JS_VERSION}\033[0m" 18 | echo -e "\033[34;1mINFO:\033[0m RUNSCRIPTS: ${RUNSCRIPTS}\033[0m" 19 | echo -e "\033[34;1mINFO:\033[0m URL: ${elasticsearch_url}\033[0m" 20 | echo -e "\033[34;1mINFO:\033[0m SERVICE: ${SERVICE}\033[0m" 21 | 22 | echo -e "\033[34;1mINFO:\033[0m pinging Elasticsearch ..\033[0m" 23 | curl --insecure --fail $external_elasticsearch_url/_cluster/health?pretty 24 | 25 | if [[ "$RUNSCRIPTS" = *"enterprise-search"* ]]; then 26 | enterprise_search_url="http://localhost:3002" 27 | echo -e "\033[34;1mINFO:\033[0m pinging Enterprise Search ..\033[0m" 28 | curl -I --fail $enterprise_search_url 29 | fi 30 | 31 | echo -e "\033[32;1mSUCCESS:\033[0m successfully started the ${STACK_VERSION} stack.\033[0m" 32 | 33 | echo -e "\033[32;1mBUILD: \033[31mJS \e[0m container.\033[0m" 34 | 35 | docker build \ 36 | --file .ci/Dockerfile \ 37 | --tag elastic/enterprise-search-js \ 38 | --build-arg NODE_JS_VERSION=${NODE_JS_VERSION} \ 39 | . 40 | 41 | echo -e "\033[32;1mRUN: \033[31mJS \e[0m container.\033[0m" 42 | 43 | docker run \ 44 | --network ${network_name} \ 45 | --name enterprise-search-js \ 46 | --env "ENTERPRISE_SEARCH_URL=http://${CONTAINER_NAME}:3002" \ 47 | --rm \ 48 | --volume `pwd`:/code/enterprise-search-js \ 49 | elastic/enterprise-search-js \ 50 | npm run test:integration --prefix packages/enterprise-search 51 | -------------------------------------------------------------------------------- /.buildkite/run-tests: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Version 1.1 4 | # - Moved to .buildkite folder and separated out `run-repository.sh` 5 | # - Add `$RUNSCRIPTS` env var for running Elasticsearch dependent products 6 | export TEST_SUITE=platinum 7 | export CONTAINER_NAME=enterprise-search 8 | export RUNSCRIPTS=enterprise-search 9 | 10 | script_path="$(dirname "$(realpath -s "$0")")" 11 | source "$script_path/functions/imports.sh" 12 | set -euo pipefail 13 | 14 | echo "--- :elasticsearch: starting Elasticsearch $STACK_VERSION" 15 | DETACH=true bash .buildkite/run-elasticsearch.sh 16 | 17 | if [[ -n "$RUNSCRIPTS" ]]; then 18 | for RUNSCRIPT in ${RUNSCRIPTS//,/ } ; do 19 | echo "--- Running run-$RUNSCRIPT.sh" 20 | CONTAINER_NAME=${RUNSCRIPT} \ 21 | DETACH=true \ 22 | bash ".buildkite/run-${RUNSCRIPT}.sh" 23 | done 24 | fi 25 | 26 | echo -e ":javascript: Run tests" 27 | bash .buildkite/run-repository.sh 28 | -------------------------------------------------------------------------------- /.ci/.gitignore: -------------------------------------------------------------------------------- 1 | tmp/ 2 | -------------------------------------------------------------------------------- /.ci/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG NODE_JS_VERSION=16 2 | FROM node:${NODE_JS_VERSION} 3 | 4 | # Create app directory 5 | WORKDIR /usr/src/app 6 | 7 | RUN apt-get clean -y 8 | RUN apt-get update -y 9 | RUN apt-get install -y zip 10 | 11 | # Install app dependencies 12 | COPY package*.json ./ 13 | COPY packages/enterprise-search/package*.json ./packages/enterprise-search/ 14 | COPY packages/enterprise-search-universal/package*.json ./packages/enterprise-search-universal/ 15 | RUN npm install 16 | RUN npm install --prefix packages/enterprise-search 17 | RUN npm install --prefix packages/enterprise-search-universal 18 | 19 | COPY . . 20 | -------------------------------------------------------------------------------- /.ci/make.mjs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | /* global $ argv, cd */ 21 | 22 | 'use strict' 23 | 24 | import 'zx/globals' 25 | 26 | import { readFile, writeFile } from 'fs/promises' 27 | import assert from 'assert' 28 | import { join } from 'desm' 29 | import semver from 'semver' 30 | 31 | assert(typeof argv.task === 'string', 'Missing task parameter') 32 | 33 | switch (argv.task) { 34 | case 'release': 35 | release(argv._).catch(onError) 36 | break 37 | case 'bump': 38 | bump(argv._).catch(onError) 39 | break 40 | default: 41 | console.log(`Unknown task: ${argv.task}`) 42 | process.exit(1) 43 | } 44 | 45 | async function release (args) { 46 | assert(args.length === 2, 'Release task expects two parameters') 47 | const rootPath = join(import.meta.url, '..') 48 | const enterpriseSearchPath = join(import.meta.url, '..', 'packages', 'enterprise-search') 49 | const enterpriseSearchUniversalPath = join(import.meta.url, '..', 'packages', 'enterprise-search-universal') 50 | let [version, outputFolder] = args 51 | 52 | if (process.env.WORKFLOW === 'snapshot' && !version.endsWith('SNAPSHOT')) { 53 | version = `${version}-SNAPSHOT` 54 | } 55 | 56 | await bump([version]) 57 | 58 | // nodejs 59 | let packageJson = JSON.parse(await readFile( 60 | join(import.meta.url, '..', 'packages', 'enterprise-search', 'package.json'), 61 | 'utf8' 62 | )) 63 | 64 | cd(enterpriseSearchPath) 65 | await $`npm run build` 66 | await $`npm pack` 67 | cd(rootPath) 68 | await $`zip enterprise-search-js-${version}.zip ${join(import.meta.url, '..', 'packages', 'enterprise-search', `elastic-enterprise-search-${packageJson.version}.tgz`)}` 69 | await $`rm ${join(import.meta.url, '..', 'packages', 'enterprise-search', `elastic-enterprise-search-${packageJson.version}.tgz`)}` 70 | await $`mv ${join(import.meta.url, '..', `enterprise-search-js-${version}.zip`)} ${join(import.meta.url, '..', outputFolder, `enterprise-search-js-${version}.zip`)}` 71 | 72 | // universal 73 | packageJson = JSON.parse(await readFile( 74 | join(import.meta.url, '..', 'packages', 'enterprise-search-universal', 'package.json'), 75 | 'utf8' 76 | )) 77 | 78 | cd(enterpriseSearchUniversalPath) 79 | await $`npm pack` 80 | cd(rootPath) 81 | await $`zip enterprise-search-universal-js-${version}.zip ${join(import.meta.url, '..', 'packages', 'enterprise-search-universal', `elastic-enterprise-search-universal-${packageJson.version}.tgz`)}` 82 | await $`rm ${join(import.meta.url, '..', 'packages', 'enterprise-search-universal', `elastic-enterprise-search-universal-${packageJson.version}.tgz`)}` 83 | await $`mv ${join(import.meta.url, '..', `enterprise-search-universal-js-${version}.zip`)} ${join(import.meta.url, '..', outputFolder, `enterprise-search-universal-js-${version}.zip`)}` 84 | } 85 | 86 | async function bump (args) { 87 | assert(args.length === 1, 'Bump task expects one parameter') 88 | const [version] = args 89 | let packageJson = JSON.parse(await readFile( 90 | join(import.meta.url, '..', 'packages', 'enterprise-search', 'package.json'), 91 | 'utf8' 92 | )) 93 | 94 | const cleanVersion = semver.clean(version.includes('SNAPSHOT') ? version.split('-')[0] : version) 95 | assert(semver.valid(cleanVersion)) 96 | packageJson.version = cleanVersion 97 | 98 | await writeFile( 99 | join(import.meta.url, '..', 'packages', 'enterprise-search', 'package.json'), 100 | JSON.stringify(packageJson, null, 2), 101 | 'utf8' 102 | ) 103 | 104 | packageJson = JSON.parse(await readFile( 105 | join(import.meta.url, '..', 'packages', 'enterprise-search-universal', 'package.json'), 106 | 'utf8' 107 | )) 108 | 109 | packageJson.version = cleanVersion 110 | 111 | await writeFile( 112 | join(import.meta.url, '..', 'packages', 'enterprise-search-universal', 'package.json'), 113 | JSON.stringify(packageJson, null, 2), 114 | 'utf8' 115 | ) 116 | 117 | const testMatrix = await readFile(join(import.meta.url, 'test-matrix.yml'), 'utf8') 118 | await writeFile( 119 | join(import.meta.url, 'test-matrix.yml'), 120 | testMatrix.replace(/STACK_VERSION:\s+\- "[0-9]+[0-9\.]*[0-9](?:\-SNAPSHOT)?"/, `STACK_VERSION:\n - "${cleanVersion}-SNAPSHOT"`), // eslint-disable-line 121 | 'utf8' 122 | ) 123 | } 124 | 125 | function onError (err) { 126 | console.log(err) 127 | process.exit(1) 128 | } 129 | -------------------------------------------------------------------------------- /.ci/make.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # ------------------------------------------------------- # 4 | # 5 | # Skeleton for common build entry script for all elastic 6 | # clients. Needs to be adapted to individual client usage. 7 | # 8 | # Must be called: ./.ci/make.sh 9 | # 10 | # Version: 1.1.0 11 | # 12 | # Targets: 13 | # --------------------------- 14 | # assemble : build client artefacts with version 15 | # bump : bump client internals to version 16 | # codegen : generate endpoints 17 | # docsgen : generate documentation 18 | # examplegen : generate the doc examples 19 | # clean : clean workspace 20 | # 21 | # ------------------------------------------------------- # 22 | 23 | # ------------------------------------------------------- # 24 | # Bootstrap 25 | # ------------------------------------------------------- # 26 | 27 | script_path=$(dirname "$(realpath -s "$0")") 28 | repo=$(realpath "$script_path/../") 29 | 30 | # shellcheck disable=SC1090 31 | CMD=$1 32 | TASK=$1 33 | TASK_ARGS=() 34 | VERSION=$2 35 | STACK_VERSION=$VERSION 36 | NODE_JS_VERSION=16 37 | WORKFLOW=${WORKFLOW-staging} 38 | set -euo pipefail 39 | 40 | product="elastic/enterprise-search-js" 41 | output_folder=".ci/output" 42 | OUTPUT_DIR="$repo/${output_folder}" 43 | REPO_BINDING="${OUTPUT_DIR}:/sln/${output_folder}" 44 | mkdir -p "$OUTPUT_DIR" 45 | 46 | echo -e "\033[34;1mINFO:\033[0m PRODUCT ${product}\033[0m" 47 | echo -e "\033[34;1mINFO:\033[0m VERSION ${STACK_VERSION}\033[0m" 48 | echo -e "\033[34;1mINFO:\033[0m OUTPUT_DIR ${OUTPUT_DIR}\033[0m" 49 | 50 | # ------------------------------------------------------- # 51 | # Parse Command 52 | # ------------------------------------------------------- # 53 | 54 | case $CMD in 55 | clean) 56 | echo -e "\033[36;1mTARGET: clean workspace $output_folder\033[0m" 57 | rm -rf "$output_folder" 58 | echo -e "\033[32;1mdone.\033[0m" 59 | exit 0 60 | ;; 61 | assemble) 62 | if [ -v $VERSION ]; then 63 | echo -e "\033[31;1mTARGET: assemble -> missing version parameter\033[0m" 64 | exit 1 65 | fi 66 | echo -e "\033[36;1mTARGET: assemble artefact $VERSION\033[0m" 67 | TASK=release 68 | TASK_ARGS=("$VERSION" "$output_folder") 69 | ;; 70 | codegen) 71 | if [ -v $VERSION ]; then 72 | echo -e "\033[31;1mTARGET: codegen -> missing version parameter\033[0m" 73 | exit 1 74 | fi 75 | echo -e "\033[36;1mTARGET: codegen API v$VERSION\033[0m" 76 | TASK=codegen 77 | # VERSION is BRANCH here for now 78 | TASK_ARGS=("$VERSION") 79 | ;; 80 | docsgen) 81 | if [ -v $VERSION ]; then 82 | echo -e "\033[31;1mTARGET: docsgen -> missing version parameter\033[0m" 83 | exit 1 84 | fi 85 | echo -e "\033[36;1mTARGET: generate docs for $VERSION\033[0m" 86 | TASK=codegen 87 | # VERSION is BRANCH here for now 88 | TASK_ARGS=("$VERSION" "$codegen_folder") 89 | ;; 90 | examplesgen) 91 | echo -e "\033[36;1mTARGET: generate examples\033[0m" 92 | TASK=codegen 93 | # VERSION is BRANCH here for now 94 | TASK_ARGS=("$VERSION" "$codegen_folder") 95 | ;; 96 | bump) 97 | if [ -v $VERSION ]; then 98 | echo -e "\033[31;1mTARGET: bump -> missing version parameter\033[0m" 99 | exit 1 100 | fi 101 | echo -e "\033[36;1mTARGET: bump to version $VERSION\033[0m" 102 | TASK=bump 103 | # VERSION is BRANCH here for now 104 | TASK_ARGS=("$VERSION") 105 | ;; 106 | *) 107 | echo -e "\nUsage:\n\t $CMD is not supported right now\n" 108 | exit 1 109 | esac 110 | 111 | 112 | # ------------------------------------------------------- # 113 | # Build Container 114 | # ------------------------------------------------------- # 115 | 116 | echo -e "\033[34;1mINFO: building $product container\033[0m" 117 | 118 | docker build \ 119 | --file .ci/Dockerfile \ 120 | --tag ${product} \ 121 | --build-arg NODE_JS_VERSION=${NODE_JS_VERSION} \ 122 | --build-arg USER_ID="$(id -u)" \ 123 | --build-arg GROUP_ID="$(id -g)" \ 124 | . 125 | 126 | # ------------------------------------------------------- # 127 | # Run the Container 128 | # ------------------------------------------------------- # 129 | 130 | echo -e "\033[34;1mINFO: running $product container\033[0m" 131 | 132 | docker run \ 133 | --volume $repo:/usr/src/app \ 134 | --volume /usr/src/app/node_modules \ 135 | --env "WORKFLOW=${WORKFLOW}" \ 136 | --name make-enterprise-search-js \ 137 | --rm \ 138 | $product \ 139 | node .ci/make.mjs --task $TASK ${TASK_ARGS[*]} 140 | 141 | # ------------------------------------------------------- # 142 | # Post Command tasks & checks 143 | # ------------------------------------------------------- # 144 | 145 | if [[ "$CMD" == "assemble" ]]; then 146 | if compgen -G ".ci/output/*" > /dev/null; then 147 | echo -e "\033[32;1mTARGET: successfully assembled client v$VERSION\033[0m" 148 | else 149 | echo -e "\033[31;1mTARGET: assemble failed, empty workspace!\033[0m" 150 | exit 1 151 | fi 152 | fi 153 | 154 | if [[ "$CMD" == "bump" ]]; then 155 | if [ -n "$(git status --porcelain)" ]; then 156 | echo -e "\033[32;1mTARGET: successfully bumped client v$VERSION\033[0m" 157 | else 158 | echo -e "\033[31;1mTARGET: failed bumped client v$VERSION\033[0m" 159 | exit 1 160 | fi 161 | fi 162 | 163 | if [[ "$CMD" == "codegen" ]]; then 164 | echo "TODO" 165 | fi 166 | 167 | if [[ "$CMD" == "docsgen" ]]; then 168 | echo "TODO" 169 | fi 170 | 171 | if [[ "$CMD" == "examplesgen" ]]; then 172 | echo "TODO" 173 | fi 174 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # GitHub CODEOWNERS definition 2 | # Identify which groups will be pinged by changes to different parts of the codebase. 3 | # For more info, see https://help.github.com/articles/about-codeowners/ 4 | 5 | * @elastic/devtools-team 6 | * @elastic/search-kibana 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## 👉 [Please follow one of these issue templates](https://github.com/elastic/enterprise-search-js/issues/new/choose) 👈 2 | 3 | #### You have already researched for similar issues? 4 | It's not uncommon that somebody already opened an issue or in the best case it's already fixed but not merged. That's the reason why you should [search](https://github.com/elastic/enterprise-search-js/issues) at first before submitting a new one. 5 | 6 | #### Are you sure this is an issue with `@elastic/enterprise-search` or are you just looking for some help? 7 | 8 | Issues should only be posted in this repository after you have been able to reproduce them and confirm that they are a bug or incorrect/missing information in the docs. 9 | 10 | If you have a question related to Enterprise Search itself, please consider open a question on [discuss.elastic.co](https://discuss.elastic.co/). 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🐛 Bug report 3 | about: Create a report to help us improve 4 | --- 5 | 6 | It's not uncommon that somebody already opened an issue or in the best case it's already fixed but not merged. That's the reason why you should [search](https://github.com/elastic/enterprise-search-js/issues) at first before submitting a new one. 7 | 8 | **Please read this entire template before posting any issue. If you ignore these instructions 9 | and post an issue here that does not follow the instructions, your issue might be closed, 10 | locked, and assigned the `not reproducible` label.** 11 | 12 | ## 🐛 Bug Report 13 | 14 | A clear and concise description of what the bug is. 15 | 16 | ## To Reproduce 17 | 18 | Steps to reproduce the behavior: 19 | 20 | Paste your code here: 21 | 22 | ```js 23 | 24 | ``` 25 | 26 | ## Expected behavior 27 | 28 | A clear and concise description of what you expected to happen. 29 | 30 | Paste the results here: 31 | 32 | ```js 33 | 34 | ``` 35 | 36 | ## Your Environment 37 | 38 | - *node version*: 6,8,10 39 | - `@elastic/enterprise-search` *version*: >=7.0.0 40 | - *os*: Mac, Windows, Linux 41 | - *any other relevant information* 42 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🚀 Feature Proposal 3 | about: Submit a proposal for a new feature 4 | --- 5 | 6 | It's not uncommon that somebody already opened an issue or in the best case it's already fixed but not merged. That's the reason why you should [search](https://github.com/elastic/enterprise-search-js/issues) at first before submitting a new one. 7 | 8 | **Please read this entire template before posting any issue. If you ignore these instructions 9 | and post an issue here that does not follow the instructions, your issue might be closed, 10 | locked, and assigned the `invalid` label.** 11 | 12 | ## 🚀 Feature Proposal 13 | 14 | A clear and concise description of what the feature is. 15 | 16 | ## Motivation 17 | 18 | Please outline the motivation for the proposal. 19 | 20 | ## Example 21 | 22 | Please provide an example for how this feature would be used. 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 💬 Questions / Help 3 | about: If you have questions, please check our Gitter or Help repo 4 | --- 5 | 6 | ## 💬 Questions and Help 7 | 8 | ### Please note that this issue tracker is not a help forum and this issue may be closed. 9 | 10 | It's not uncommon that somebody already opened an issue or in the best case it's already fixed but not merged. That's the reason why you should [search](https://github.com/elastic/enterprise-search-js/issues) at first before submitting a new one. 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/regression.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 💥 Regression Report 3 | about: Report unexpected behavior that worked in previous versions 4 | --- 5 | 6 | It's not uncommon that somebody already opened an issue or in the best case it's already fixed but not merged. That's the reason why you should [search](https://github.com/elastic/enterprise-search-js/issues) at first before submitting a new one. 7 | 8 | **Please read this entire template before posting any issue. If you ignore these instructions 9 | and post an issue here that does not follow the instructions, your issue might be closed, 10 | locked, and assigned the `invalid` label.** 11 | 12 | ## 💥 Regression Report 13 | 14 | A clear and concise description of what the regression is. 15 | 16 | ## Last working version 17 | 18 | Worked up to version: 19 | 20 | Stopped working in version: 21 | 22 | ## To Reproduce 23 | 24 | Steps to reproduce the behavior: 25 | 26 | Paste your code here: 27 | 28 | ```js 29 | 30 | ``` 31 | 32 | ## Expected behavior 33 | 34 | A clear and concise description of what you expected to happen. 35 | 36 | Paste the results here: 37 | 38 | ```js 39 | 40 | ``` 41 | 42 | ## Your Environment 43 | 44 | - *node version*: 6,8,10 45 | - `@elastic/enterprise-search` *version*: >=7.0.0 46 | - *os*: Mac, Windows, Linux 47 | - *any other relevant information* 48 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/security.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 👮 Security Issue 3 | about: Responsible Disclosure 4 | --- 5 | 6 | If you want to report a security issue, please take a look at [elastic/security](https://www.elastic.co/community/security). 7 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 18 | -------------------------------------------------------------------------------- /.github/workflows/backport.yml: -------------------------------------------------------------------------------- 1 | name: Backport 2 | on: 3 | pull_request: 4 | types: 5 | - closed 6 | - labeled 7 | 8 | jobs: 9 | backport: 10 | runs-on: ubuntu-latest 11 | name: Backport 12 | steps: 13 | - name: Backport 14 | uses: tibdex/backport@v1 15 | with: 16 | github_token: ${{ secrets.GITHUB_TOKEN }} 17 | -------------------------------------------------------------------------------- /.github/workflows/comment-on-asciidoc-changes.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Comment on PR for .asciidoc changes 3 | 4 | on: 5 | # We need to use pull_request_target to be able to comment on PRs from forks 6 | pull_request_target: 7 | types: 8 | - synchronize 9 | - opened 10 | - reopened 11 | branches: 12 | - main 13 | - master 14 | - "9.0" 15 | 16 | jobs: 17 | comment-on-asciidoc-change: 18 | permissions: 19 | contents: read 20 | pull-requests: write 21 | uses: elastic/docs-builder/.github/workflows/comment-on-asciidoc-changes.yml@main 22 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: Node CI 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - "packages/enterprise-search/**" 7 | push: 8 | paths: 9 | - "packages/enterprise-search/**" 10 | 11 | jobs: 12 | test: 13 | name: Test 14 | runs-on: ${{ matrix.os }} 15 | 16 | strategy: 17 | matrix: 18 | node-version: [18.x, 20.x] 19 | os: [ubuntu-latest, windows-latest, macOS-latest] 20 | 21 | steps: 22 | - uses: actions/checkout@v2 23 | 24 | - name: Use Node.js ${{ matrix.node-version }} 25 | uses: actions/setup-node@v1 26 | with: 27 | node-version: ${{ matrix.node-version }} 28 | 29 | - name: Install 30 | working-directory: ./packages/enterprise-search 31 | run: | 32 | npm install 33 | 34 | - name: Lint 35 | working-directory: ./packages/enterprise-search 36 | run: | 37 | npm run lint 38 | 39 | - name: Unit test 40 | working-directory: ./packages/enterprise-search 41 | run: | 42 | npm run test 43 | 44 | license: 45 | name: License check 46 | runs-on: ubuntu-latest 47 | 48 | strategy: 49 | matrix: 50 | node-version: [18.x] 51 | 52 | steps: 53 | - uses: actions/checkout@v2 54 | 55 | - name: Use Node.js ${{ matrix.node-version }} 56 | uses: actions/setup-node@v1 57 | with: 58 | node-version: ${{ matrix.node-version }} 59 | 60 | - name: Install 61 | working-directory: ./packages/enterprise-search 62 | run: | 63 | npm install 64 | 65 | - name: License checker 66 | working-directory: ./packages/enterprise-search 67 | run: | 68 | npm run license-checker 69 | -------------------------------------------------------------------------------- /.github/workflows/universal.yml: -------------------------------------------------------------------------------- 1 | name: Universal CI 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - "packages/enterprise-search-universal/**" 7 | push: 8 | paths: 9 | - "packages/enterprise-search-universal/**" 10 | 11 | jobs: 12 | test-node: 13 | name: Test Node.js 14 | runs-on: ${{ matrix.os }} 15 | 16 | strategy: 17 | matrix: 18 | node-version: [18.x, 20.x] 19 | os: [ubuntu-latest, windows-latest, macOS-latest] 20 | 21 | steps: 22 | - uses: actions/checkout@v2 23 | 24 | - name: Use Node.js ${{ matrix.node-version }} 25 | uses: actions/setup-node@v1 26 | with: 27 | node-version: ${{ matrix.node-version }} 28 | 29 | - name: Install 30 | working-directory: ./packages/enterprise-search-universal 31 | run: | 32 | npm install 33 | 34 | - name: Lint 35 | working-directory: ./packages/enterprise-search-universal 36 | run: | 37 | npm run lint 38 | 39 | - name: Unit test 40 | working-directory: ./packages/enterprise-search-universal 41 | run: | 42 | npm run test:node 43 | 44 | test-browser: 45 | name: Test Browser 46 | runs-on: ${{ matrix.os }} 47 | 48 | strategy: 49 | matrix: 50 | node-version: [18.x] 51 | os: [ubuntu-latest] 52 | 53 | steps: 54 | - uses: actions/checkout@v2 55 | 56 | - name: Use Node.js ${{ matrix.node-version }} 57 | uses: actions/setup-node@v1 58 | with: 59 | node-version: ${{ matrix.node-version }} 60 | 61 | - name: Install 62 | working-directory: ./packages/enterprise-search-universal 63 | run: | 64 | npm install 65 | 66 | - name: Playwright configuration 67 | working-directory: ./packages/enterprise-search-universal 68 | run: | 69 | npx playwright install-deps 70 | 71 | - name: Playwright browser install 72 | working-directory: ./packages/enterprise-search-universal 73 | run: | 74 | npx playwright install 75 | 76 | - name: Lint 77 | working-directory: ./packages/enterprise-search-universal 78 | run: | 79 | npm run lint 80 | 81 | - name: Unit test 82 | working-directory: ./packages/enterprise-search-universal 83 | run: | 84 | npm run test:browser 85 | 86 | license: 87 | name: License check 88 | runs-on: ubuntu-latest 89 | 90 | strategy: 91 | matrix: 92 | node-version: [16.x] 93 | 94 | steps: 95 | - uses: actions/checkout@v2 96 | 97 | - name: Use Node.js ${{ matrix.node-version }} 98 | uses: actions/setup-node@v1 99 | with: 100 | node-version: ${{ matrix.node-version }} 101 | 102 | - name: Install 103 | working-directory: ./packages/enterprise-search 104 | run: | 105 | npm install 106 | 107 | - name: License checker 108 | working-directory: ./packages/enterprise-search 109 | run: | 110 | npm run license-checker 111 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | 106 | package-lock.json 107 | 108 | lib 109 | 110 | .DS_Store 111 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Please see [the release notes](https://www.elastic.co/guide/en/enterprise-search-clients/enterprise-search-node/current/release-notes.html) in the official Enterprise Search Node.js documentation. 2 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 303 See Other 2 | 3 | Location: https://www.elastic.co/community/codeofconduct 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to the Enterprise Search Node.js and browser clients 2 | 3 | The Enterprise Search Node.js and browser clients are open source and we love to receive contributions from our community — you! 4 | 5 | There are many ways to contribute, 6 | from writing tutorials or blog posts, 7 | improving the documentation, 8 | submitting bug reports and feature requests or writing code. 9 | 10 | ## Code contributions 11 | 12 | If you have a bugfix or new feature that you would like to contribute, 13 | please find or open an issue about it first. 14 | Talk about what you would like to do. 15 | It may be that somebody is already working on it, 16 | or that there are particular issues that you should know about before implementing the change. 17 | 18 | Note that we strictly follow the [Elastic EOL schedule](https://www.elastic.co/support/eol). 19 | 20 | ### Submitting your changes 21 | 22 | Generally, we require that you test any code you are adding or modifying. 23 | Once your changes are ready to submit for review: 24 | 25 | 1. Test your changes 26 | 27 | Run the test suite to make sure that nothing is broken. 28 | Usually run `npm test` is enough, our CI will take care of running the integration test. If you want to run the integration test yourself, see the *Testing* section below. 29 | 30 | 2. Submit a pull request 31 | 32 | Push your local changes to your forked copy of the repository and [submit a pull request](https://help.github.com/articles/using-pull-requests). 33 | In the pull request, 34 | choose a title which sums up the changes that you have made, 35 | and in the body provide more details about what your changes do. 36 | Also mention the number of the issue where discussion has taken place, 37 | eg "Closes #123". 38 | 39 | 3. Sign the Contributor License Agreement 40 | 41 | Please make sure you have signed our [Contributor License Agreement](https://www.elastic.co/contributor-agreement/). 42 | We are not asking you to assign copyright to us, 43 | but to give us the right to distribute your code without restriction. 44 | We ask this of all contributors in order to assure our users of the origin and continuing existence of the code. 45 | You only need to sign the CLA once. 46 | 47 | 4. Be patient 48 | 49 | We might not be able to review your code as fast as we would like to, 50 | but we'll do our best to dedicate it the attention it deserves. 51 | Your effort is much appreciated! 52 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | Enterprise Search JavaScript Client 2 | Copyright 2022 Elasticsearch B.V. 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # :warning: App Search and Workplace Search will be discontinued in 9.0 2 | 3 | Starting with Elastic version 9.0, the standalone Enterprise Search products, will no longer be included in our offering. 4 | They remain supported in their current form in version 8.x and will only receive security upgrades and fixes. 5 | Enterprise Search clients will continue to be supported in their current form throughout 8.x versions, according to our [EOL policy](https://www.elastic.co/support/eol). 6 | We recommend transitioning to our actively developed [Elastic Stack](https://www.elastic.co/elastic-stack) tools for your search use cases. However, if you're still using any Enterprise Search products, we recommend using the latest stable release of the clients. 7 | 8 | Here are some useful links with more information: 9 | 10 | - [Enterprise Search FAQ](https://www.elastic.co/resources/enterprise-search/enterprise-search-faq) 11 | - [One stop shop for Upgrading to Elastic Search 9](https://www.elastic.co/guide/en/enterprise-search/8.18/upgrading-to-9-x.html) 12 | 13 |

14 | 15 | Elastic Enterprise Search 16 | 17 |

18 | 19 | [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](http://standardjs.com/) [![Build Status](https://clients-ci.elastic.co/buildStatus/icon?job=elastic%2Benterprise-search-js%2Bmain)](https://clients-ci.elastic.co/job/elastic+enterprise-search-js+main/). [![Node CI](https://github.com/elastic/enterprise-search-js/actions/workflows/nodejs.yml/badge.svg)](https://github.com/elastic/enterprise-search-js/actions/workflows/nodejs.yml) 20 | 21 | Official Node.js and universal clients for Elastic Enterprise Search, App Search, and Workplace Search. 22 | 23 | - [Node.js client](./packages/enterprise-search) - All Enterprise Search APIs supported in Node.js 24 | - Read the [documentation](https://www.elastic.co/guide/en/enterprise-search-clients/enterprise-search-node/current/index.html) 25 | - [Universal client](./packages/enterprise-search-universal) - Node.js and browser support for a lower API surface (search and analytics) 26 | 27 | ## License 28 | 29 | This software is licensed under the [Apache 2 license](./LICENSE). 30 | -------------------------------------------------------------------------------- /catalog-info.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # yaml-language-server: $schema=https://json.schemastore.org/catalog-info.json 3 | apiVersion: backstage.io/v1alpha1 4 | kind: Component 5 | metadata: 6 | name: enterprise-search-js 7 | spec: 8 | type: library 9 | owner: group:devtools-team 10 | lifecycle: production 11 | 12 | --- 13 | # yaml-language-server: $schema=https://gist.githubusercontent.com/elasticmachine/988b80dae436cafea07d9a4a460a011d/raw/e57ee3bed7a6f73077a3f55a38e76e40ec87a7cf/rre.schema.json 14 | apiVersion: backstage.io/v1alpha1 15 | kind: Resource 16 | metadata: 17 | name: enterprise-search-js-test 18 | description: Test enterprise-search-js client 19 | spec: 20 | type: buildkite-pipeline 21 | owner: group:devtools-team 22 | system: buildkite 23 | implementation: 24 | apiVersion: buildkite.elastic.dev/v1 25 | kind: Pipeline 26 | metadata: 27 | name: enterprise-search-js-test 28 | spec: 29 | repository: elastic/enterprise-search-js 30 | pipeline_file: .buildkite/pipeline.yaml 31 | teams: 32 | devtools-team: 33 | access_level: MANAGE_BUILD_AND_READ 34 | everyone: 35 | access_level: READ_ONLY 36 | provider_settings: 37 | build_pull_requests: true 38 | build_branches: true 39 | cancel_intermediate_builds: true 40 | cancel_intermediate_builds_branch_filter: '!main' 41 | schedules: 42 | main_semi_daily: 43 | branch: 'main' 44 | cronline: '0 5,17 * * *' 45 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "packages/*" 4 | ], 5 | "npmClient": "npm", 6 | "version": "8.14.0" 7 | } 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "root", 3 | "private": true, 4 | "license": "Apache-2.0", 5 | "devDependencies": { 6 | "desm": "^1.2.0", 7 | "lerna": "^4.0.0", 8 | "semver": "^7.3.7", 9 | "zx": "^6.1.0" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/enterprise-search-universal/.airtap.yml: -------------------------------------------------------------------------------- 1 | providers: 2 | - airtap-playwright 3 | 4 | server: ./test/utils/server.js 5 | 6 | browsers: 7 | - name: chromium 8 | title: Playwright Chromium 9 | options: 10 | headless: true 11 | supports: 12 | headless: true 13 | devtools: true 14 | provider: airtap-playwright 15 | 16 | - name: webkit 17 | title: Playwright Webkit 18 | options: 19 | headless: true 20 | supports: 21 | headless: true 22 | provider: airtap-playwright 23 | 24 | - name: firefox 25 | title: Playwright Firefox 26 | options: 27 | headless: true 28 | supports: 29 | headless: true 30 | provider: airtap-playwright 31 | -------------------------------------------------------------------------------- /packages/enterprise-search-universal/.npmignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # coverage output 18 | coverage.lcov 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # node-waf configuration 27 | .lock-wscript 28 | 29 | # Compiled binary addons (http://nodejs.org/api/addons.html) 30 | build/Release 31 | 32 | # Dependency directories 33 | node_modules 34 | jspm_packages 35 | 36 | # Optional npm cache directory 37 | .npm 38 | 39 | # Optional REPL history 40 | .node_repl_history 41 | 42 | # mac files 43 | .DS_Store 44 | 45 | # vim swap files 46 | *.swp 47 | 48 | package-lock.json 49 | 50 | # elasticsearch repo or binary files 51 | elasticsearch* 52 | 53 | # Generated typings, we don't commit them 54 | # because we should copy them in the main .d.ts file 55 | api/generated.d.ts 56 | 57 | # Ignore doc folder 58 | docs 59 | 60 | # Ignore test folder 61 | test 62 | 63 | # Ignore scripts folder 64 | scripts 65 | 66 | # ci configuration 67 | .ci 68 | .travis.yml 69 | certs 70 | .github 71 | CODE_OF_CONDUCT.md 72 | CONTRIBUTING.md 73 | 74 | src 75 | 76 | .airtap.yml 77 | -------------------------------------------------------------------------------- /packages/enterprise-search-universal/NOTICE.txt: -------------------------------------------------------------------------------- 1 | Enterprise Search JavaScript Client 2 | Copyright 2022 Elasticsearch B.V. 3 | -------------------------------------------------------------------------------- /packages/enterprise-search-universal/README.md: -------------------------------------------------------------------------------- 1 | # :warning: App Search and Workplace Search will be discontinued in 9.0 2 | 3 | Starting with Elastic version 9.0, the standalone Enterprise Search products, will no longer be included in our offering. 4 | They remain supported in their current form in version 8.x and will only receive security upgrades and fixes. 5 | Enterprise Search clients will continue to be supported in their current form throughout 8.x versions, according to our [EOL policy](https://www.elastic.co/support/eol). 6 | We recommend transitioning to our actively developed [Elastic Stack](https://www.elastic.co/elastic-stack) tools for your search use cases. However, if you're still using any Enterprise Search products, we recommend using the latest stable release of the clients. 7 | 8 | Here are some useful links with more information: 9 | 10 | - [Enterprise Search FAQ](https://www.elastic.co/resources/enterprise-search/enterprise-search-faq) 11 | - [One stop shop for Upgrading to Elastic Search 9](https://www.elastic.co/guide/en/enterprise-search/8.18/upgrading-to-9-x.html) 12 | 13 |

14 | 15 | Elastic Enterprise Search 16 | 17 |

18 | 19 | [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](http://standardjs.com/) [![Build Status](https://clients-ci.elastic.co/buildStatus/icon?job=elastic%2Benterprise-search-js%2Bmain)](https://clients-ci.elastic.co/job/elastic+enterprise-search-js+main/). [![Universal CI](https://github.com/elastic/enterprise-search-js/actions/workflows/universal.yml/badge.svg)](https://github.com/elastic/enterprise-search-js/actions/workflows/universal.yml) 20 | 21 | Official universal JavaScript client for Elastic App Search and Workplace Search. 22 | 23 | ℹ️ **_This client is not yet released (not yet in beta phase)_** 24 | 25 | ## Install 26 | 27 | ``` 28 | npm install @elastic/enterprise-search-universal 29 | ``` 30 | 31 | ## Quick start 32 | 33 | This module expects to find the `fetch` API in the global environment, if you need to use it in Node.js 34 | as well, you can add it with [`cross-fetch`](https://github.com/lquixada/cross-fetch). 35 | 36 | ```js 37 | const { Client } = require('@elastic/enterprise-search-universal') 38 | const client = new Client({ 39 | url: 'http://localhost:3002', 40 | token: 'my-token' 41 | }) 42 | 43 | // App Search API 44 | const response = await client.app.search({ 45 | engine_name: 'games', 46 | body: { 47 | query: 'Pack-Man' 48 | } 49 | }) 50 | console.log(response) 51 | 52 | // Workplace Search API 53 | const response = await client.workplace.getDocument({ 54 | content_source_id: 'test', 55 | document_id: 'id' 56 | }) 57 | console.log(response) 58 | ``` 59 | 60 | ## License 61 | 62 | This software is licensed under the [Apache 2 license](./LICENSE). 63 | -------------------------------------------------------------------------------- /packages/enterprise-search-universal/docs/app-api.asciidoc: -------------------------------------------------------------------------------- 1 | [[app-search-api]] 2 | App Search APIs 3 | 4 | app-search-click-api 5 | === Click API 6 | 7 | ==== Tracks results that were clicked after a query 8 | 9 | Tracks results that were clicked after a query 10 | https://www.elastic.co/guide/en/app-search/current/clickthrough.html[Documentation] 11 | 12 | [source,js] 13 | ---- 14 | client.app.logClickthrough() 15 | ---- 16 | 17 | app-search-query-suggestion-api 18 | === Query Suggestion API 19 | 20 | ==== Retrieve query suggestions 21 | 22 | Provide relevant query suggestions for incomplete queries 23 | https://www.elastic.co/guide/en/app-search/current/query-suggestion.html[Documentation] 24 | 25 | [source,js] 26 | ---- 27 | client.app.querySuggestion() 28 | ---- 29 | 30 | app-search-search-api 31 | === Search API 32 | 33 | ==== Submit a search 34 | 35 | Submit a search and receive a set of results with meta data 36 | https://www.elastic.co/guide/en/app-search/current/search.html[Documentation] 37 | 38 | [source,js] 39 | ---- 40 | client.app.search() 41 | ---- 42 | 43 | -------------------------------------------------------------------------------- /packages/enterprise-search-universal/docs/changelog.asciidoc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/enterprise-search-js/9baa1af4bb3d8f382273a4209b8b2ed884d6d8b6/packages/enterprise-search-universal/docs/changelog.asciidoc -------------------------------------------------------------------------------- /packages/enterprise-search-universal/docs/connecting.asciidoc: -------------------------------------------------------------------------------- 1 | [[connecting]] 2 | == Connecting 3 | 4 | This page contains the information you need to connect and use the Client with Elastic Enterprise Search. 5 | 6 | NOTE: The universal client only support Bearer authentication. 7 | 8 | You should configure the Bearer token in the `token` option. 9 | 10 | [source,js] 11 | ---- 12 | // cjs 13 | const { Client } = require('@elastic/enterprise-search-universal') 14 | 15 | // mjs 16 | import { Client } from '@elastic/enterprise-search-universal' 17 | 18 | const client = new Client({ 19 | url: 'http://localhost:3002', 20 | token: 'my-token' 21 | }) 22 | ---- 23 | -------------------------------------------------------------------------------- /packages/enterprise-search-universal/docs/index.asciidoc: -------------------------------------------------------------------------------- 1 | = enterprise-search-universal 2 | 3 | :doctype: book 4 | 5 | include::{asciidoc-dir}/../../shared/attributes.asciidoc[] 6 | 7 | include::overview.asciidoc[] 8 | 9 | include::installation.asciidoc[] 10 | 11 | include::connecting.asciidoc[] 12 | 13 | include::changelog.asciidoc[] 14 | 15 | include::app-api.asciidoc[] 16 | 17 | include::workplace-api.asciidoc[] 18 | 19 | 20 | -------------------------------------------------------------------------------- /packages/enterprise-search-universal/docs/installation.asciidoc: -------------------------------------------------------------------------------- 1 | [[installation]] 2 | == Installation 3 | 4 | This page guides you through the installation process of the client. 5 | 6 | To install the latest version of the client, run the following command: 7 | 8 | [source,sh] 9 | ---- 10 | npm install @elastic/enterprise-search-universal 11 | ---- 12 | 13 | To install a specific major version of the client, run the following command: 14 | 15 | [source,sh] 16 | ---- 17 | npm install @elastic/enterprise-search-universal@ 18 | ---- 19 | 20 | To learn more about the supported major versions, please refer to the 21 | <>. 22 | 23 | [discrete] 24 | [[nodejs-support]] 25 | === Node.js support 26 | 27 | NOTE: The minimum supported version of Node.js is `v14`. 28 | 29 | The client versioning follows the {stack} versioning, this means that 30 | major, minor, and patch releases are done following a precise schedule that 31 | often does not coincide with the https://nodejs.org/en/about/releases/[Node.js release] times. 32 | 33 | To avoid support insecure and unsupported versions of Node.js, the 34 | client *will drop the support of EOL versions of Node.js between minor releases*. 35 | Typically, as soon as a Node.js version goes into EOL, the client will continue 36 | to support that version for at least another minor release. If you are using the client 37 | with a version of Node.js that will be unsupported soon, you will see a warning 38 | in your logs (the client will start logging the warning with two minors in advance). 39 | 40 | Unless you are *always* using a supported version of Node.js, 41 | we recommend defining the client dependency in your 42 | `package.json` with the `~` instead of `^`. In this way, you will lock the 43 | dependency on the minor release and not the major. (for example, `~7.10.0` instead 44 | of `^7.10.0`). 45 | 46 | [%header,cols=3*] 47 | |=== 48 | |Node.js Version 49 | |Node.js EOL date 50 | |End of support 51 | 52 | |`8.x` 53 | |December 2019 54 | |`7.11` (early 2021) 55 | 56 | |`10.x` 57 | |April 2021 58 | |`7.12` (mid 2021) 59 | 60 | |`12.x` 61 | |April 2022 62 | |`8.2` (early 2022) 63 | 64 | |`14.x` 65 | |April 2023 66 | |`8.8` (early 2023) 67 | |=== 68 | -------------------------------------------------------------------------------- /packages/enterprise-search-universal/docs/overview.asciidoc: -------------------------------------------------------------------------------- 1 | [[overview]] 2 | == Overview 3 | 4 | Official universal JavaScript client for Elastic App Search and Workplace Search. 5 | This module differs from the normal Node.js client as it can be used both in Node.js 6 | and the browser environment. 7 | Another important difference is that this client does not support every API that the 8 | normal Node.js client supports, as it's designed to work with lower permissions. 9 | 10 | IMPORTANT: This module expects to find the `fetch` API in the global environment, if you need to use it in Node.js 11 | as well, you can add it with https://github.com/lquixada/cross-fetch[`cross-fetch`]. 12 | 13 | [discrete] 14 | === Example usage 15 | 16 | [source,js] 17 | ---- 18 | // cjs 19 | const { Client } = require('@elastic/enterprise-search-universal') 20 | 21 | // mjs 22 | import { Client } from '@elastic/enterprise-search-universal' 23 | 24 | const client = new Client({ 25 | url: 'http://localhost:3002', 26 | token: 'my-token' 27 | }) 28 | 29 | // App Search API 30 | const response = await client.app.search({ 31 | engine_name: 'games', 32 | body: { 33 | query: 'Pack-Man' 34 | } 35 | }) 36 | console.log(response) 37 | 38 | // Workplace Search API 39 | const response = await client.workplace.getDocument({ 40 | content_source_id: 'test', 41 | document_id: 'id' 42 | }) 43 | console.log(response) 44 | ---- 45 | 46 | [discrete] 47 | === License 48 | 49 | This code is available under the https://github.com/elastic/enterprise-search-js/blob/main/packages/enterprise-search-universal/LICENSE[Apache-2.0 license]. 50 | -------------------------------------------------------------------------------- /packages/enterprise-search-universal/docs/workplace-api.asciidoc: -------------------------------------------------------------------------------- 1 | [[app-search-api]] 2 | Workplace Search APIs 3 | 4 | app-search-analytics-api 5 | === Analytics API 6 | 7 | ==== Capture click and feedback analytic events 8 | 9 | Capture Analytic events for click and feedback 10 | https://www.elastic.co/guide/en/workplace-search/current/workplace-search-analytics-api.html[Documentation] 11 | 12 | [source,js] 13 | ---- 14 | client.workplace.createAnalyticsEvent() 15 | ---- 16 | 17 | app-search-search-api 18 | === Search API 19 | 20 | ==== Search across available sources with various query tuning options 21 | 22 | Issue a Search Query 23 | https://www.elastic.co/guide/en/workplace-search/current/workplace-search-search-api.html[Documentation] 24 | 25 | [source,js] 26 | ---- 27 | client.workplace.search() 28 | ---- 29 | 30 | -------------------------------------------------------------------------------- /packages/enterprise-search-universal/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@elastic/enterprise-search-universal", 3 | "version": "8.18.0", 4 | "description": "Official universal client for Elastic App Search and Workplace Search.", 5 | "main": "lib/client.js", 6 | "types": "lib/client.d.ts", 7 | "scripts": { 8 | "lint": "ts-standard src", 9 | "lint:fix": "ts-standard --fix src", 10 | "license-checker": "license-checker --production --onlyAllow='MIT;Apache-2.0;Apache1.1;ISC;BSD-3-Clause;BSD-2-Clause;0BSD'", 11 | "prebuild": "npm run clean-build && npm run lint", 12 | "build": "tsc", 13 | "clean-build": "rimraf ./lib && mkdir lib", 14 | "prepublishOnly": "npm run build", 15 | "test:node": "ts-node test/node/basic.test.ts", 16 | "test:browser": "npm run build && airtap --concurrency 1 test/browser/basic.test.js" 17 | }, 18 | "repository": { 19 | "type": "git", 20 | "url": "git+https://github.com/elastic/enterprise-search-js.git" 21 | }, 22 | "keywords": [ 23 | "elastic", 24 | "enterprise", 25 | "workspace", 26 | "app", 27 | "site", 28 | "search" 29 | ], 30 | "author": { 31 | "name": "Tomas Della Vedova", 32 | "company": "Elastic BV" 33 | }, 34 | "license": "Apache-2.0", 35 | "bugs": { 36 | "url": "https://github.com/elastic/enterprise-search-js/issues" 37 | }, 38 | "homepage": "https://github.com/elastic/enterprise-search-js/blob/main/packages/enterprise-search-universal", 39 | "engines": { 40 | "node": ">=12" 41 | }, 42 | "devDependencies": { 43 | "@types/node": "*", 44 | "@types/semver": "^7.3.13", 45 | "@types/tape": "^4.13.2", 46 | "airtap": "^4.0.4", 47 | "airtap-playwright": "^1.0.1", 48 | "cross-fetch": "^3.1.5", 49 | "license-checker": "^25.0.1", 50 | "node-abort-controller": "^3.0.1", 51 | "tape": "^5.5.2", 52 | "ts-node": "^10.4.0", 53 | "ts-standard": "^11.0.0", 54 | "typescript": "^4.5.5" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /packages/enterprise-search-universal/src/app-types.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | /* eslint-disable @typescript-eslint/naming-convention */ 21 | /* eslint-disable @typescript-eslint/no-empty-interface */ 22 | 23 | // This file was automatically generated by elastic/elastic-client-generator-js 24 | // DO NOT MODIFY IT BY HAND. Instead, modify the source open api file, 25 | // and elastic/elastic-client-generator-js to regenerate this file again. 26 | 27 | export interface LogClickthroughRequest { 28 | /** 29 | * Name of the engine 30 | */ 31 | engine_name: string 32 | body?: { 33 | query: string 34 | request_id?: string 35 | document_id: string 36 | tags?: string[] 37 | } 38 | } 39 | 40 | export type LogClickthroughResponse = Record 41 | 42 | export interface QuerySuggestionRequest { 43 | /** 44 | * Name of the engine 45 | */ 46 | engine_name: string 47 | body?: { 48 | query?: string 49 | types?: { 50 | documents?: { 51 | fields?: string[] 52 | [k: string]: unknown 53 | } 54 | [k: string]: unknown 55 | } 56 | size?: number 57 | } 58 | } 59 | 60 | export interface QuerySuggestionResponse { 61 | results?: { 62 | documents?: Array<{ 63 | suggestion?: string 64 | }> 65 | [k: string]: unknown 66 | } 67 | meta?: {} 68 | } 69 | 70 | export interface SearchRequest { 71 | /** 72 | * Name of the engine 73 | */ 74 | engine_name: string 75 | body?: { 76 | query: string 77 | analytics?: {} 78 | boosts?: {} 79 | facets?: {} 80 | filters?: {} 81 | group?: {} 82 | page?: { 83 | current?: number 84 | size?: number 85 | } 86 | result_fields?: {} 87 | search_fields?: { 88 | [k: string]: { 89 | weight?: number 90 | } 91 | } 92 | sort?: Array<{ 93 | [k: string]: 94 | | ('asc' | 'desc') 95 | | { 96 | center?: 97 | | string 98 | | Array<{ 99 | [k: string]: unknown 100 | }> 101 | order?: 'asc' | 'desc' 102 | mode?: 'min' | 'max' | 'median' | 'avg' 103 | } 104 | }> 105 | } 106 | } 107 | 108 | export interface SearchResponse { 109 | meta: { 110 | page: { 111 | current: number 112 | total_pages: number 113 | total_results: number 114 | size: number 115 | } 116 | } & { 117 | alerts: string[] 118 | warnings: string[] 119 | precision?: number 120 | engine: { 121 | name?: string 122 | /** 123 | * Engine type 124 | */ 125 | type?: 'meta' | 'default' 126 | } 127 | request_id?: string 128 | } 129 | results: Array<{}> 130 | } 131 | 132 | export interface MultiSearchRequest { 133 | /** 134 | * Name of the engine 135 | */ 136 | engine_name: string 137 | body?: { 138 | queries: Array<{ 139 | query: string 140 | analytics?: {} 141 | boosts?: {} 142 | facets?: {} 143 | filters?: {} 144 | group?: {} 145 | page?: { 146 | current?: number 147 | size?: number 148 | } 149 | result_fields?: {} 150 | search_fields?: { 151 | [k: string]: { 152 | weight?: number 153 | } 154 | } 155 | sort?: Array<{ 156 | [k: string]: 157 | | ('asc' | 'desc') 158 | | { 159 | center?: 160 | | string 161 | | Array<{ 162 | [k: string]: unknown 163 | }> 164 | order?: 'asc' | 'desc' 165 | mode?: 'min' | 'max' | 'median' | 'avg' 166 | } 167 | }> 168 | }> 169 | } 170 | } 171 | 172 | export type MultiSearchResponse = Array<{ 173 | meta: { 174 | page: { 175 | current: number 176 | total_pages: number 177 | total_results: number 178 | size: number 179 | } 180 | } & { 181 | alerts: string[] 182 | warnings: string[] 183 | precision?: number 184 | engine: { 185 | name?: string 186 | /** 187 | * Engine type 188 | */ 189 | type?: 'meta' | 'default' 190 | } 191 | request_id?: string 192 | } 193 | results: Array<{}> 194 | }> 195 | -------------------------------------------------------------------------------- /packages/enterprise-search-universal/test/browser/basic.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | /* globals AbortController */ 21 | 22 | const test = require('tape') 23 | const { Client, ResponseError } = require('../../lib/client') 24 | 25 | test('Basic', async t => { 26 | t.plan(1) 27 | 28 | const client = new Client({ 29 | url: 'http://localhost:3000', 30 | token: 'token' 31 | }) 32 | 33 | const response = await client.transportRequest({ method: 'GET', path: '/' }) 34 | t.same(response, { hello: 'world' }) 35 | }) 36 | 37 | test('Querystring array', async t => { 38 | t.plan(1) 39 | 40 | const client = new Client({ 41 | url: 'http://localhost:3000', 42 | token: 'token' 43 | }) 44 | 45 | const response = await client.transportRequest({ 46 | method: 'GET', 47 | path: '/query/array', 48 | querystring: { 49 | foo: 'bar', 50 | baz: [1, 2, 3] 51 | } 52 | }) 53 | t.same(response, { valid: true }) 54 | }) 55 | 56 | test('Querystring object', async t => { 57 | t.plan(1) 58 | 59 | const client = new Client({ 60 | url: 'http://localhost:3000', 61 | token: 'token' 62 | }) 63 | 64 | const response = await client.transportRequest({ 65 | method: 'GET', 66 | path: '/query/object', 67 | querystring: { 68 | page: { 69 | size: 0, 70 | current: 1 71 | } 72 | } 73 | }) 74 | t.same(response, { valid: true }) 75 | }) 76 | 77 | test('Request body', async t => { 78 | t.plan(1) 79 | 80 | const client = new Client({ 81 | url: 'http://localhost:3000', 82 | token: 'token' 83 | }) 84 | 85 | const response = await client.transportRequest({ 86 | method: 'POST', 87 | path: '/body', 88 | body: { foo: 'bar' } 89 | }) 90 | t.same(response, { foo: 'bar' }) 91 | }) 92 | 93 | test('Disable meta header', async t => { 94 | t.plan(4) 95 | 96 | const client = new Client({ 97 | url: 'http://localhost:3000', 98 | token: 'token', 99 | enableMetaHeader: false 100 | }) 101 | 102 | try { 103 | await client.transportRequest({ method: 'GET', path: '/' }) 104 | t.fail('Should throw') 105 | } catch (err) { 106 | t.ok(err instanceof ResponseError) 107 | t.equal(err.message, 'Bad x-elastic-client-meta header') 108 | t.equal(err.statusCode, 400) 109 | t.equal(err.body, 'Bad x-elastic-client-meta header') 110 | } 111 | }) 112 | 113 | test('Abort a request', async t => { 114 | t.plan(1) 115 | 116 | const client = new Client({ 117 | url: 'http://localhost:3000', 118 | token: 'token' 119 | }) 120 | 121 | const controller = new AbortController() 122 | setTimeout(() => controller.abort(), 100) 123 | try { 124 | await client.transportRequest({ method: 'GET', path: '/slow' }, { signal: controller.signal }) 125 | t.fail('Should throw') 126 | } catch (err) { 127 | t.equal(err.name, 'AbortError') 128 | } 129 | }) 130 | -------------------------------------------------------------------------------- /packages/enterprise-search-universal/test/utils/server.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | const http = require('http') 21 | 22 | const server = http.createServer(handler) 23 | server.listen(process.env.PORT || 3000) 24 | 25 | const supportedMethods = [ 26 | 'GET', 27 | 'POST', 28 | 'PUT', 29 | 'DELETE', 30 | 'OPTIONS' 31 | ] 32 | 33 | const headers = { 34 | 'Access-Control-Allow-Origin': '*', 35 | 'Access-Control-Allow-Methods': supportedMethods.join(', '), 36 | 'Access-Control-Allow-Headers': '*', 37 | 'Access-Control-Max-Age': 2592000 38 | } 39 | 40 | function handler (req, res) { 41 | if (req.method === 'OPTIONS') { 42 | res.writeHead(204, headers) 43 | res.end() 44 | } else if (supportedMethods.includes(req.method)) { 45 | // test meta header 46 | const reg = /^[a-z]{1,}=[a-z0-9\.\-]{1,}(?:,[a-z]{1,}=[a-z0-9\.\-]+)*$/ // eslint-disable-line 47 | if (!reg.test(req.headers['x-elastic-client-meta']) || !req.headers['x-elastic-client-meta'].includes('jsu')) { 48 | res.writeHead(400, { 49 | ...headers, 50 | 'content-type': 'text/plain' 51 | }) 52 | res.end('Bad x-elastic-client-meta header') 53 | 54 | // test body (just echo it back) 55 | } else if (req.url.startsWith('/body')) { 56 | let payload = '' 57 | req.setEncoding('utf8') 58 | req.on('data', chunk => { payload += chunk }) 59 | req.on('error', () => { 60 | res.writeHead(500, { 61 | ...headers, 62 | 'content-type': 'text/plain' 63 | }) 64 | res.end('Something went wrong') 65 | }) 66 | req.on('end', () => { 67 | res.writeHead(200, { 68 | ...headers, 69 | 'content-type': 'application/json' 70 | }) 71 | res.end(payload) 72 | }) 73 | 74 | // test querystring array format 75 | } else if (req.url.startsWith('/query/array')) { 76 | const valid = decodeURIComponent(req.url) === '/query/array?foo=bar&baz[]=1&baz[]=2&baz[]=3' 77 | res.writeHead(200, { 78 | ...headers, 79 | 'content-type': 'application/json' 80 | }) 81 | res.end(JSON.stringify({ valid })) 82 | 83 | // test querystring object format 84 | } else if (req.url.startsWith('/query/object')) { 85 | const valid = decodeURIComponent(req.url) === '/query/object?page[size]=0&page[current]=1' 86 | res.writeHead(200, { 87 | ...headers, 88 | 'content-type': 'application/json' 89 | }) 90 | res.end(JSON.stringify({ valid })) 91 | 92 | // slow response 93 | } else if (req.url.startsWith('/slow')) { 94 | setTimeout(() => { 95 | res.writeHead(200, { 96 | ...headers, 97 | 'content-type': 'application/json' 98 | }) 99 | res.end(JSON.stringify({ hello: 'world' })) 100 | }, 1000) 101 | 102 | // base test 103 | } else { 104 | res.writeHead(200, { 105 | ...headers, 106 | 'content-type': 'application/json' 107 | }) 108 | res.end(JSON.stringify({ hello: 'world' })) 109 | } 110 | } else { 111 | res.writeHead(405, { 112 | ...headers, 113 | 'content-type': 'text/plain' 114 | }) 115 | res.end(`${req.method} is not supported`) 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /packages/enterprise-search-universal/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2016", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "declaration": true, 7 | "pretty": true, 8 | "noEmitOnError": true, 9 | "strict": true, 10 | "removeComments": false, 11 | "sourceMap": true, 12 | "newLine": "lf", 13 | "noUnusedLocals": true, 14 | "noFallthroughCasesInSwitch": true, 15 | "useDefineForClassFields": true, 16 | "forceConsistentCasingInFileNames": true, 17 | "skipLibCheck": false, 18 | "esModuleInterop": true, 19 | "isolatedModules": true, 20 | "outDir": "lib", 21 | "lib": [ 22 | "es2016", 23 | "dom" 24 | ] 25 | }, 26 | "formatCodeOptions": { 27 | "identSize": 2, 28 | "tabSize": 2 29 | }, 30 | "exclude": [ 31 | "node_modules" 32 | ], 33 | "include": [ 34 | "./src/**/*.ts" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /packages/enterprise-search/.npmignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # coverage output 18 | coverage.lcov 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # node-waf configuration 27 | .lock-wscript 28 | 29 | # Compiled binary addons (http://nodejs.org/api/addons.html) 30 | build/Release 31 | 32 | # Dependency directories 33 | node_modules 34 | jspm_packages 35 | 36 | # Optional npm cache directory 37 | .npm 38 | 39 | # Optional REPL history 40 | .node_repl_history 41 | 42 | # mac files 43 | .DS_Store 44 | 45 | # vim swap files 46 | *.swp 47 | 48 | package-lock.json 49 | 50 | # elasticsearch repo or binary files 51 | elasticsearch* 52 | 53 | # Generated typings, we don't commit them 54 | # because we should copy them in the main .d.ts file 55 | api/generated.d.ts 56 | 57 | # Ignore doc folder 58 | docs 59 | 60 | # Ignore test folder 61 | test 62 | 63 | # Ignore scripts folder 64 | scripts 65 | 66 | # ci configuration 67 | .ci 68 | .travis.yml 69 | certs 70 | .github 71 | CODE_OF_CONDUCT.md 72 | CONTRIBUTING.md 73 | 74 | src 75 | -------------------------------------------------------------------------------- /packages/enterprise-search/NOTICE.txt: -------------------------------------------------------------------------------- 1 | Enterprise Search JavaScript Client 2 | Copyright 2022 Elasticsearch B.V. 3 | -------------------------------------------------------------------------------- /packages/enterprise-search/README.md: -------------------------------------------------------------------------------- 1 | # :warning: App Search and Workplace Search will be discontinued in 9.0 2 | 3 | Starting with Elastic version 9.0, the standalone Enterprise Search products, will no longer be included in our offering. 4 | They remain supported in their current form in version 8.x and will only receive security upgrades and fixes. 5 | Enterprise Search clients will continue to be supported in their current form throughout 8.x versions, according to our [EOL policy](https://www.elastic.co/support/eol). 6 | We recommend transitioning to our actively developed [Elastic Stack](https://www.elastic.co/elastic-stack) tools for your search use cases. However, if you're still using any Enterprise Search products, we recommend using the latest stable release of the clients. 7 | 8 | Here are some useful links with more information: 9 | 10 | - [Enterprise Search FAQ](https://www.elastic.co/resources/enterprise-search/enterprise-search-faq) 11 | - [One stop shop for Upgrading to Elastic Search 9](https://www.elastic.co/guide/en/enterprise-search/8.18/upgrading-to-9-x.html) 12 | 13 |

14 | 15 | Elastic Enterprise Search 16 | 17 |

18 | 19 | [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](http://standardjs.com/) [![Build Status](https://clients-ci.elastic.co/buildStatus/icon?job=elastic%2Benterprise-search-js%2Bmain)](https://clients-ci.elastic.co/job/elastic+enterprise-search-js+main/). [![Node CI](https://github.com/elastic/enterprise-search-js/actions/workflows/nodejs.yml/badge.svg)](https://github.com/elastic/enterprise-search-js/actions/workflows/nodejs.yml) 20 | 21 | Official Node.js client for Elastic Enterprise Search, App Search, and Workplace Search. 22 | 23 | :information_source: Read the [full documentation](https://www.elastic.co/guide/en/enterprise-search-clients/enterprise-search-node/current/index.html) for this client at **elastic.co**. 24 | 25 | ## Install 26 | 27 | ``` 28 | npm install @elastic/enterprise-search 29 | ``` 30 | 31 | ## Quick start 32 | 33 | ```js 34 | const { Client } = require('@elastic/enterprise-search') 35 | const client = new Client({ 36 | url: 'http://localhost:3002', 37 | // basic auth 38 | auth: { 39 | username: 'elastic', 40 | password: 'changeme' 41 | } 42 | // bearer auth 43 | auth: { 44 | token: 'my-token' 45 | } 46 | }) 47 | 48 | // Enterprise Search API 49 | const response = await client.enterprise.getHealth() 50 | console.log(response) 51 | 52 | // App Search API 53 | const response = await client.app.search({ 54 | engine_name: 'games', 55 | body: { 56 | query: 'Pack-Man' 57 | } 58 | }) 59 | console.log(response) 60 | 61 | // Workplace Search API 62 | const response = await client.workplace.getDocument({ 63 | content_source_id: 'test', 64 | document_id: 'id' 65 | }) 66 | console.log(response) 67 | ``` 68 | 69 | ## License 70 | 71 | This software is licensed under the [Apache 2 license](./LICENSE). 72 | -------------------------------------------------------------------------------- /packages/enterprise-search/docs/index.asciidoc: -------------------------------------------------------------------------------- 1 | [#index] 2 | = enterprise-search-js 3 | 4 | :doctype: book 5 | include::{docs-root}/shared/versions/stack/{source_branch}.asciidoc[] 6 | include::{docs-root}/shared/attributes.asciidoc[] 7 | 8 | include::overview.asciidoc[] 9 | 10 | include::installation.asciidoc[] 11 | 12 | include::app-search-api.asciidoc[] 13 | 14 | include::workplace-search-api.asciidoc[] 15 | 16 | include::enterprise-search-api.asciidoc[] 17 | 18 | include::release-notes/index.asciidoc[] 19 | -------------------------------------------------------------------------------- /packages/enterprise-search/docs/installation.asciidoc: -------------------------------------------------------------------------------- 1 | [#installation] 2 | == Installation 3 | 4 | Install the Enterprise Search Node client using `npm`: 5 | 6 | [source,shell] 7 | ---- 8 | $ npm install @elastic/enterprise-search 9 | ---- 10 | 11 | [NOTE] 12 | ==== 13 | Be careful not to confuse this https://github.com/elastic/enterprise-search-js/tree/main/packages/enterprise-search[*Enterprise Search* Node.js^] client with the _deprecated_ App Search Node.js client or the _deprecated_ Workplace Search Node.js client. 14 | ==== 15 | 16 | [discrete#compatibility] 17 | === Compatibility 18 | 19 | Language clients are forward compatible; meaning that clients support communicating 20 | with greater or equal minor versions of Elastic Enterprise Search. -------------------------------------------------------------------------------- /packages/enterprise-search/docs/release-notes/8-6-0.asciidoc: -------------------------------------------------------------------------------- 1 | [#release-notes-8-6-0] 2 | === 8.6.0 release notes 3 | 4 | The Enterprise Search Node.js client is now *generally available*. 5 | 6 | * Added the `app.multiSearch` API method. 7 | * Added the `enterprise.getStorage` API method. 8 | * Added the `enterprise.getStaleStorage` API method. 9 | * Added the `enterprise.deleteStaleStorage` API method. 10 | -------------------------------------------------------------------------------- /packages/enterprise-search/docs/release-notes/8-6-1.asciidoc: -------------------------------------------------------------------------------- 1 | [#release-notes-8-6-1] 2 | === 8.6.1 release notes 3 | 4 | * Added APIs that were unintentionally excluded from v8.6.0. 5 | -------------------------------------------------------------------------------- /packages/enterprise-search/docs/release-notes/index.asciidoc: -------------------------------------------------------------------------------- 1 | [#release-notes] 2 | == Release Notes 3 | 4 | * <> 5 | * <> 6 | 7 | 8 | include::8-6-1.asciidoc[] 9 | include::8-6-0.asciidoc[] 10 | -------------------------------------------------------------------------------- /packages/enterprise-search/index.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import Client from './lib' 21 | 22 | export type { ClientOptions, AuthOptions } from './lib/utils' 23 | export type { AppTypes } from './lib/AppSearchClient' 24 | export type { EnterpriseTypes } from './lib/EnterpriseSearchClient' 25 | export type { WorkplaceTypes } from './lib/WorkplaceSearchClient' 26 | export * from '@elastic/transport' 27 | export { Client } 28 | -------------------------------------------------------------------------------- /packages/enterprise-search/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | 'use strict' 21 | 22 | const { 23 | errors 24 | } = require('@elastic/transport') 25 | 26 | console.warn(`Starting with Elastic version 9.0, the standalone Enterprise Search products, will no longer be included in our offering. They remain supported in their current form in version 8.x and will only receive security upgrades and fixes. Enterprise Search clients will continue to be supported in their current form throughout 8.x versions, according to our EOL policy (https://www.elastic.co/support/eol). 27 | 28 | We recommend transitioning to our actively developed Elastic Stack (https://www.elastic.co/elastic-stack) tools for your search use cases. However, if you're still using any Enterprise Search products, we recommend using the latest stable release of the clients.`) 29 | 30 | const { default: Client } = require('./lib') 31 | 32 | module.exports = { 33 | Client, 34 | errors 35 | } 36 | -------------------------------------------------------------------------------- /packages/enterprise-search/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@elastic/enterprise-search", 3 | "version": "8.18.0", 4 | "description": "Official Node.js client for Elastic Enterprise Search, App Search, and Workplace Search.", 5 | "main": "index.js", 6 | "types": "index.d.ts", 7 | "scripts": { 8 | "test": "npm run build && tap test/unit/*.test.ts", 9 | "test:integration": "npm run build && tap --jobs=1 test/integration/**/*.test.ts", 10 | "lint": "ts-standard src", 11 | "lint:fix": "ts-standard --fix src", 12 | "license-checker": "license-checker --production --onlyAllow='MIT;Apache-2.0;Apache1.1;ISC;BSD-3-Clause;BSD-2-Clause;0BSD'", 13 | "prebuild": "npm run clean-build && npm run lint", 14 | "build": "tsc", 15 | "clean-build": "rimraf ./lib && mkdir lib", 16 | "prepublishOnly": "npm run build" 17 | }, 18 | "repository": { 19 | "type": "git", 20 | "url": "git+https://github.com/elastic/enterprise-search-js.git" 21 | }, 22 | "keywords": [ 23 | "elastic", 24 | "enterprise", 25 | "workspace", 26 | "app", 27 | "site", 28 | "search" 29 | ], 30 | "author": { 31 | "name": "Tomas Della Vedova", 32 | "company": "Elastic BV" 33 | }, 34 | "license": "Apache-2.0", 35 | "bugs": { 36 | "url": "https://github.com/elastic/enterprise-search-js/issues" 37 | }, 38 | "homepage": "https://github.com/elastic/enterprise-search-js/blob/main/packages/enterprise-search", 39 | "engines": { 40 | "node": ">=18" 41 | }, 42 | "devDependencies": { 43 | "@types/node": "*", 44 | "@types/qs": "^6.9.7", 45 | "@types/tap": "^15.0.5", 46 | "dotenv": "^15.0.0", 47 | "license-checker": "^25.0.1", 48 | "nanoid": "^3.2.0", 49 | "tap": "^15.1.6", 50 | "ts-node": "^10.4.0", 51 | "ts-standard": "^11.0.0", 52 | "typescript": "^4.5.5" 53 | }, 54 | "tap": { 55 | "ts": true, 56 | "jsx": false, 57 | "flow": false, 58 | "coverage": false, 59 | "check-coverage": false 60 | }, 61 | "dependencies": { 62 | "@elastic/transport": "^8.5.1", 63 | "qs": "^6.10.3", 64 | "tslib": "^2.3.1" 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /packages/enterprise-search/src/AppSearchClient.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { Transport } from '@elastic/transport' 21 | import Serializer from './Serializer' 22 | import API from './api/app/api' 23 | import { ClientOptions, InternalOptions, isBearerAuth } from './utils' 24 | 25 | export * as AppTypes from './api/app/types' 26 | 27 | export default class AppSearchClient extends API { 28 | transport: Transport 29 | constructor (opts: ClientOptions, internal: InternalOptions) { 30 | super() 31 | const authorization = isBearerAuth(opts.auth) 32 | ? `Bearer ${opts.auth.token}` 33 | : 'Basic ' + Buffer.from(`${opts.auth.username}:${opts.auth.password}`).toString('base64') 34 | this.transport = new Transport({ 35 | serializer: new Serializer(), 36 | connectionPool: internal.connectionPool, 37 | diagnostic: internal.diagnostic, 38 | compression: false, 39 | name: 'app-search', 40 | headers: { authorization } 41 | }) 42 | } 43 | 44 | // TODO should return an utility around engines 45 | engine (name: string): AppSearchClient { 46 | return this 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /packages/enterprise-search/src/EnterpriseSearchClient.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { Transport } from '@elastic/transport' 21 | import Serializer from './Serializer' 22 | import API from './api/enterprise/api' 23 | import { ClientOptions, InternalOptions, isBearerAuth } from './utils' 24 | 25 | export * as EnterpriseTypes from './api/enterprise/types' 26 | 27 | export default class EnterpriseSearchClient extends API { 28 | transport: Transport 29 | constructor (opts: ClientOptions, internal: InternalOptions) { 30 | super() 31 | const authorization = isBearerAuth(opts.auth) 32 | ? `Bearer ${opts.auth.token}` 33 | : 'Basic ' + Buffer.from(`${opts.auth.username}:${opts.auth.password}`).toString('base64') 34 | this.transport = new Transport({ 35 | serializer: new Serializer(), 36 | connectionPool: internal.connectionPool, 37 | diagnostic: internal.diagnostic, 38 | compression: false, 39 | name: 'enterprise-search', 40 | headers: { authorization } 41 | }) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/enterprise-search/src/Serializer.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { Serializer } from '@elastic/transport' 21 | import qs from 'qs' 22 | 23 | export default class EnterpriseSerializer extends Serializer { 24 | qserialize (object?: Record | string): string { 25 | if (object == null) return '' 26 | if (typeof object === 'string') return object 27 | // { a: ['b', 'c'] } => 'a[]=b&a[]=c' 28 | return qs.stringify(object, { arrayFormat: 'brackets' }) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/enterprise-search/src/WorkplaceSearchClient.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { Transport } from '@elastic/transport' 21 | import Serializer from './Serializer' 22 | import API from './api/workplace/api' 23 | import { ClientOptions, InternalOptions, isBearerAuth } from './utils' 24 | 25 | export * as WorkplaceTypes from './api/workplace/types' 26 | 27 | export default class WorkplaceSearchClient extends API { 28 | transport: Transport 29 | constructor (opts: ClientOptions, internal: InternalOptions) { 30 | super() 31 | const authorization = isBearerAuth(opts.auth) 32 | ? `Bearer ${opts.auth.token}` 33 | : 'Basic ' + Buffer.from(`${opts.auth.username}:${opts.auth.password}`).toString('base64') 34 | this.transport = new Transport({ 35 | serializer: new Serializer(), 36 | connectionPool: internal.connectionPool, 37 | diagnostic: internal.diagnostic, 38 | compression: false, 39 | name: 'workplace-search', 40 | headers: { authorization } 41 | }) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/enterprise-search/src/api/enterprise/api.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | /* eslint-disable @typescript-eslint/naming-convention */ 21 | /* eslint-disable @typescript-eslint/no-empty-interface */ 22 | 23 | // This file was automatically generated by elastic/elastic-client-generator-js 24 | // DO NOT MODIFY IT BY HAND. Instead, modify the source open api file, 25 | // and elastic/elastic-client-generator-js to regenerate this file again. 26 | 27 | import { 28 | Transport, 29 | TransportRequestOptions 30 | } from '@elastic/transport' 31 | import * as T from './types' 32 | interface That { transport: Transport } 33 | 34 | export default class API { 35 | async getHealth (this: That, params?: T.GetHealthRequest, options?: TransportRequestOptions): Promise { 36 | return await this.transport.request({ 37 | method: 'GET', 38 | path: '/api/ent/v1/internal/health' 39 | }, options) 40 | } 41 | 42 | async getReadOnly (this: That, params?: T.GetReadOnlyRequest, options?: TransportRequestOptions): Promise { 43 | return await this.transport.request({ 44 | method: 'GET', 45 | path: '/api/ent/v1/internal/read_only_mode' 46 | }, options) 47 | } 48 | 49 | async putReadOnly (this: That, params: T.PutReadOnlyRequest, options?: TransportRequestOptions): Promise { 50 | const { 51 | body, 52 | ...querystring 53 | } = params ?? {} 54 | return await this.transport.request({ 55 | method: 'PUT', 56 | path: '/api/ent/v1/internal/read_only_mode', 57 | querystring, 58 | body: body 59 | }, options) 60 | } 61 | 62 | async getStats (this: That, params?: T.GetStatsRequest, options?: TransportRequestOptions): Promise { 63 | const { 64 | ...querystring 65 | } = params ?? {} 66 | return await this.transport.request({ 67 | method: 'GET', 68 | path: '/api/ent/v1/internal/stats', 69 | querystring 70 | }, options) 71 | } 72 | 73 | async getStorage (this: That, params?: T.GetStorageRequest, options?: TransportRequestOptions): Promise { 74 | return await this.transport.request({ 75 | method: 'GET', 76 | path: '/api/ent/v1/internal/storage' 77 | }, options) 78 | } 79 | 80 | async getStaleStorage (this: That, params?: T.GetStaleStorageRequest, options?: TransportRequestOptions): Promise { 81 | return await this.transport.request({ 82 | method: 'GET', 83 | path: '/api/ent/v1/internal/storage/stale' 84 | }, options) 85 | } 86 | 87 | async deleteStaleStorage (this: That, params?: T.DeleteStaleStorageRequest, options?: TransportRequestOptions): Promise { 88 | const { 89 | ...querystring 90 | } = params ?? {} 91 | return await this.transport.request({ 92 | method: 'DELETE', 93 | path: '/api/ent/v1/internal/storage/stale', 94 | querystring 95 | }, options) 96 | } 97 | 98 | async getVersion (this: That, params?: T.GetVersionRequest, options?: TransportRequestOptions): Promise { 99 | return await this.transport.request({ 100 | method: 'GET', 101 | path: '/api/ent/v1/internal/version' 102 | }, options) 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /packages/enterprise-search/src/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { 21 | CloudConnectionPool, 22 | Diagnostic, 23 | UndiciConnection 24 | } from '@elastic/transport' 25 | import EnterpriseSearchClient from './EnterpriseSearchClient' 26 | import AppSearchClient from './AppSearchClient' 27 | import WorkplaceSearchClient from './WorkplaceSearchClient' 28 | import { ClientOptions, InternalOptions, AuthOptions } from './utils' 29 | import { 30 | kOptions, 31 | kConnectionPool, 32 | kEnterpriseSearch, 33 | kAppSearch, 34 | kWorkplaceSearch 35 | } from './symbols' 36 | 37 | export default class Client { 38 | [kOptions]: ClientOptions 39 | [kConnectionPool]: CloudConnectionPool 40 | [kEnterpriseSearch]: EnterpriseSearchClient | null 41 | [kAppSearch]: AppSearchClient | null 42 | [kWorkplaceSearch]: WorkplaceSearchClient | null 43 | diagnostic: Diagnostic 44 | 45 | constructor (opts: ClientOptions, internal?: InternalOptions) { 46 | this[kOptions] = opts 47 | this.diagnostic = internal?.diagnostic ?? new Diagnostic() 48 | 49 | if (internal?.connectionPool != null) { 50 | this[kConnectionPool] = internal.connectionPool 51 | } else { 52 | this[kConnectionPool] = new CloudConnectionPool({ 53 | Connection: UndiciConnection, 54 | diagnostic: this.diagnostic, 55 | tls: opts.url.startsWith('https://') 56 | ? { secureProtocol: 'TLSv1_2_method' } 57 | : undefined 58 | }) 59 | this[kConnectionPool].addConnection(opts.url) 60 | } 61 | 62 | this[kEnterpriseSearch] = null 63 | this[kAppSearch] = null 64 | this[kWorkplaceSearch] = null 65 | } 66 | 67 | get enterprise (): EnterpriseSearchClient { 68 | let client = this[kEnterpriseSearch] 69 | if (client === null) { 70 | client = new EnterpriseSearchClient(this[kOptions], { 71 | connectionPool: this[kConnectionPool], 72 | diagnostic: this.diagnostic 73 | }) 74 | } 75 | return client 76 | } 77 | 78 | get app (): AppSearchClient { 79 | let client = this[kAppSearch] 80 | if (client === null) { 81 | client = new AppSearchClient(this[kOptions], { 82 | connectionPool: this[kConnectionPool], 83 | diagnostic: this.diagnostic 84 | }) 85 | } 86 | return client 87 | } 88 | 89 | get workplace (): WorkplaceSearchClient { 90 | let client = this[kWorkplaceSearch] 91 | if (client === null) { 92 | client = new WorkplaceSearchClient(this[kOptions], { 93 | connectionPool: this[kConnectionPool], 94 | diagnostic: this.diagnostic 95 | }) 96 | } 97 | return client 98 | } 99 | 100 | withAuth (opts: AuthOptions): Client { 101 | return new Client( 102 | { ...this[kOptions], ...opts }, 103 | { diagnostic: this.diagnostic, connectionPool: this[kConnectionPool] } 104 | ) 105 | } 106 | 107 | async close (): Promise { 108 | return await this[kConnectionPool].empty() 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /packages/enterprise-search/src/symbols.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | export const kOptions = Symbol('initial options') 21 | export const kConnectionPool = Symbol('connection pool') 22 | export const kEnterpriseSearch = Symbol('enterprise search') 23 | export const kAppSearch = Symbol('app search') 24 | export const kWorkplaceSearch = Symbol('workplace search') 25 | -------------------------------------------------------------------------------- /packages/enterprise-search/src/utils.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { 21 | CloudConnectionPool, 22 | Diagnostic 23 | } from '@elastic/transport' 24 | 25 | export interface BasicAuth { 26 | username: string 27 | password: string 28 | } 29 | 30 | export interface BearerAuth { 31 | token: string 32 | } 33 | 34 | export interface InternalOptions { 35 | connectionPool: CloudConnectionPool 36 | diagnostic: Diagnostic 37 | } 38 | 39 | export interface ClientOptions extends AuthOptions { 40 | url: string 41 | } 42 | 43 | export interface AuthOptions { 44 | auth: BasicAuth | BearerAuth 45 | } 46 | 47 | export function isBearerAuth (obj: any): obj is BearerAuth { 48 | return obj.token != null 49 | } 50 | -------------------------------------------------------------------------------- /packages/enterprise-search/test/fixtures/elastic-enterprise-search-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/enterprise-search-js/9baa1af4bb3d8f382273a4209b8b2ed884d6d8b6/packages/enterprise-search/test/fixtures/elastic-enterprise-search-logo.png -------------------------------------------------------------------------------- /packages/enterprise-search/test/fixtures/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/enterprise-search-js/9baa1af4bb3d8f382273a4209b8b2ed884d6d8b6/packages/enterprise-search/test/fixtures/icon.png -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/api-logs.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown } from 'tap' 21 | import { createEngine, cleanup, genName, sleep } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const DAY = 1000 * 60 * 60 * 24 25 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 26 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 27 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 28 | 29 | teardown(cleanup) 30 | 31 | test('createApiKey', async t => { 32 | const engineName = await createEngine() 33 | const client = new Client({ url, auth: { username, password } }) 34 | 35 | { 36 | const apiKey = await client.app.createApiKey({ 37 | body: { 38 | name: genName(), 39 | type: 'private', 40 | read: true, 41 | write: true, 42 | access_all_engines: true 43 | } 44 | }) 45 | 46 | // @ts-expect-error `.key` exists 47 | const privateClient = new Client({ url, auth: { token: apiKey.key }}) 48 | const response = await privateClient.app.indexDocuments({ 49 | engine_name: engineName, 50 | documents: [{ title: 'test docuemnt' }] 51 | }) 52 | await privateClient.app.deleteDocuments({ 53 | engine_name: engineName, 54 | documentIds: [response[0].id] 55 | }) 56 | } 57 | 58 | let response = await client.app.getApiLogs({ 59 | engine_name: engineName, 60 | body: { 61 | filters: { 62 | date: { 63 | from: new Date(Date.now() - DAY).toISOString(), 64 | to: new Date(Date.now() + DAY).toISOString() 65 | } 66 | } 67 | } 68 | }) 69 | let attempts = 0 70 | // @ts-expect-error 71 | while (response.results?.length < 1 && attempts < 20) { 72 | await sleep(1000) 73 | attempts += 1 74 | response = await client.app.getApiLogs({ 75 | engine_name: engineName, 76 | body: { 77 | filters: { 78 | date: { 79 | from: new Date(Date.now() - DAY).toISOString(), 80 | to: new Date(Date.now() + DAY).toISOString() 81 | } 82 | } 83 | } 84 | }) 85 | } 86 | // @ts-expect-error 87 | t.ok(response.results?.length >= 1) 88 | }) -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/count-analytics.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown } from 'tap' 21 | import { cleanup, createEngine } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | 28 | teardown(cleanup) 29 | 30 | test('getCountAnalytics', async t => { 31 | const client = new Client({ 32 | url, 33 | auth: { username, password } 34 | }) 35 | 36 | const engineName = await createEngine() 37 | 38 | const response = await client.app.getCountAnalytics({ engine_name: engineName }) 39 | t.ok(response.results.length >= 0) 40 | 41 | await client.close() 42 | }) 43 | 44 | test('getCountAnalytics with filters', async t => { 45 | const client = new Client({ 46 | url, 47 | auth: { username, password } 48 | }) 49 | 50 | const engineName = await createEngine() 51 | 52 | const response = await client.app.getCountAnalytics({ 53 | engine_name: engineName, 54 | body: { 55 | filters: { tag: 'web' } 56 | } 57 | }) 58 | t.ok(response.results.length >= 0) 59 | 60 | await client.close() 61 | }) -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/crawl-request.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown } from 'tap' 21 | import { cleanup, createEngine, sleep } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | 28 | teardown(cleanup) 29 | 30 | test('creates, gets, lists and deletes a crawl request', async t => { 31 | const client = new Client({ 32 | url, 33 | auth: { username, password } 34 | }) 35 | 36 | const engineName = await createEngine() 37 | await client.app.createCrawlerDomain({ 38 | engine_name: engineName, 39 | body: { 40 | name: 'https://www.elastic.co' 41 | } 42 | }) 43 | 44 | const response1 = await client.app.createCrawlerCrawlRequest({ engine_name: engineName }) 45 | t.type(response1.status, 'string') 46 | t.type(response1.id, 'string') 47 | 48 | const response2 = await client.app.getCrawlerCrawlRequest({ 49 | engine_name: engineName, 50 | crawl_request_id: response1.id 51 | }) 52 | t.type(response2.status, 'string') 53 | t.equal(response2.id, response1.id) 54 | 55 | 56 | let response3 = await client.app.getCrawlerActiveCrawlRequest({ engine_name: engineName }) 57 | t.type(response3.status, 'string') 58 | t.equal(response3.id, response1.id) 59 | 60 | let attempts = 0 61 | while (response3.status !== 'running' && attempts < 20) { 62 | await sleep(1000) 63 | attempts += 1 64 | response3 = await client.app.getCrawlerActiveCrawlRequest({ engine_name: engineName }) 65 | } 66 | 67 | const response4 = await client.app.listCrawlerCrawlRequests({ engine_name: engineName }) 68 | t.equal(response4.results.length, 1) 69 | 70 | const response5 = await client.app.deleteCrawlerActiveCrawlRequest({ engine_name: engineName }) 71 | t.equal(response5.id, response1.id) 72 | t.equal(response5.status, 'canceling') 73 | 74 | await client.close() 75 | }) -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/crawl-rule.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown } from 'tap' 21 | import { cleanup, createEngine } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | 28 | teardown(cleanup) 29 | 30 | test('creates, updates and deletes a rule', async t => { 31 | const client = new Client({ 32 | url, 33 | auth: { username, password } 34 | }) 35 | 36 | const engineName = await createEngine() 37 | 38 | const domain = await client.app.createCrawlerDomain({ 39 | engine_name: engineName, 40 | body: { 41 | name: 'https://www.elastic.co' 42 | } 43 | }) 44 | 45 | const response1 = await client.app.createCrawlerCrawlRule({ 46 | engine_name: engineName, 47 | domain_id: domain.id!, 48 | body: { 49 | order: 1, 50 | policy: 'allow', 51 | rule: 'contains', 52 | pattern: '/stack' 53 | } 54 | }) 55 | t.equal(response1.rule, 'contains') 56 | 57 | const response2 = await client.app.putCrawlerCrawlRule({ 58 | engine_name: engineName, 59 | domain_id: domain.id!, 60 | crawl_rule_id: response1.id!, 61 | body: { 62 | order: 1, 63 | policy: 'allow', 64 | rule: 'begins', 65 | pattern: '/stack' 66 | } 67 | }) 68 | t.equal(response2.rule, 'begins') 69 | 70 | const response3 = await client.app.deleteCrawlerCrawlRule({ 71 | engine_name: engineName, 72 | domain_id: domain.id!, 73 | crawl_rule_id: response1.id! 74 | }) 75 | t.ok(response3.deleted) 76 | 77 | await client.close() 78 | }) -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/crawler-domain.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown } from 'tap' 21 | import { cleanup, createEngine } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | 28 | teardown(cleanup) 29 | 30 | test('creates and gets a crawler domain', async t => { 31 | const client = new Client({ 32 | url, 33 | auth: { username, password } 34 | }) 35 | 36 | const engineName = await createEngine() 37 | const domain = await client.app.createCrawlerDomain({ 38 | engine_name: engineName, 39 | body: { 40 | name: 'https://www.elastic.co' 41 | } 42 | }) 43 | t.type(domain.id, 'string') 44 | 45 | const response = await client.app.getCrawlerDomain({ 46 | engine_name: engineName, 47 | domain_id: domain.id! 48 | }) 49 | t.equal(response.id, domain.id) 50 | await client.close() 51 | }) 52 | 53 | test('creates and updates a crawler domain', async t => { 54 | const client = new Client({ 55 | url, 56 | auth: { username, password } 57 | }) 58 | 59 | const engineName = await createEngine() 60 | const domain = await client.app.createCrawlerDomain({ 61 | engine_name: engineName, 62 | body: { 63 | name: 'https://www.elastic.co' 64 | } 65 | }) 66 | t.type(domain.id, 'string') 67 | 68 | const response = await client.app.putCrawlerDomain({ 69 | engine_name: engineName, 70 | domain_id: domain.id!, 71 | body: { 72 | name: 'https://www.wikipedia.org' 73 | } 74 | }) 75 | t.equal(response.name, 'https://www.wikipedia.org') 76 | await client.close() 77 | }) 78 | 79 | test('validates a domain', { skip: 'bad definition' }, async t => { 80 | const client = new Client({ 81 | url, 82 | auth: { username, password } 83 | }) 84 | 85 | const engineName = await createEngine() 86 | const domain = await client.app.createCrawlerDomain({ 87 | engine_name: engineName, 88 | body: { 89 | name: 'https://www.elastic.co' 90 | } 91 | }) 92 | t.type(domain.id, 'string') 93 | 94 | const response = await client.app.getCrawlerDomainValidationResult({ 95 | // @ts-expect-error 96 | body: { 97 | url: 'https://www.elastic.co' 98 | } 99 | }) 100 | t.ok(response.valid) 101 | await client.close() 102 | }) 103 | -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/crawler-entry-point.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown, beforeEach } from 'tap' 21 | import { cleanup, createEngine } from '../helper' 22 | import { Client, AppTypes } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | let engineName = '' 28 | let domain: AppTypes.GetCrawlerDomainResponse 29 | 30 | teardown(cleanup) 31 | 32 | beforeEach(async () => { 33 | const client = new Client({ 34 | url, 35 | auth: { username, password } 36 | }) 37 | 38 | engineName = await createEngine() 39 | domain = await client.app.createCrawlerDomain({ 40 | engine_name: engineName, 41 | body: { 42 | name: 'https://www.elastic.co' 43 | } 44 | }) 45 | 46 | await client.close() 47 | }) 48 | 49 | test('creates an entry point', async t => { 50 | const client = new Client({ 51 | url, 52 | auth: { username, password } 53 | }) 54 | 55 | const response = await client.app.createCrawlerEntryPoint({ 56 | engine_name: engineName, 57 | domain_id: domain.id!, 58 | body: { 59 | value: '/enterprise-search' 60 | } 61 | }) 62 | 63 | t.type(response.id, 'string') 64 | t.type(response.created_at, 'string') 65 | t.equal(response.value, '/enterprise-search') 66 | 67 | await client.close() 68 | }) 69 | 70 | test('updates an entry point', async t => { 71 | const client = new Client({ 72 | url, 73 | auth: { username, password } 74 | }) 75 | 76 | const entryPoint = await client.app.createCrawlerEntryPoint({ 77 | engine_name: engineName, 78 | domain_id: domain.id!, 79 | body: { 80 | value: '/enterprise-search' 81 | } 82 | }) 83 | 84 | const response = await client.app.putCrawlerEntryPoint({ 85 | engine_name: engineName, 86 | domain_id: domain.id!, 87 | entry_point_id: entryPoint.id!, 88 | body: { 89 | value: '/elastic-stack' 90 | } 91 | }) 92 | 93 | t.type(response.id, 'string') 94 | t.type(response.created_at, 'string') 95 | t.not(response.value, entryPoint.value) 96 | 97 | await client.close() 98 | }) 99 | 100 | test('deletes an entry point', async t => { 101 | const client = new Client({ 102 | url, 103 | auth: { username, password } 104 | }) 105 | 106 | const entryPoint = await client.app.createCrawlerEntryPoint({ 107 | engine_name: engineName, 108 | domain_id: domain.id!, 109 | body: { 110 | value: '/enterprise-search' 111 | } 112 | }) 113 | 114 | const response = await client.app.deleteCrawlerEntryPoint({ 115 | engine_name: engineName, 116 | domain_id: domain.id!, 117 | entry_point_id: entryPoint.id! 118 | }) 119 | 120 | t.ok(response.deleted) 121 | 122 | await client.close() 123 | }) -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/crawler-metrics.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown } from 'tap' 21 | import { cleanup, createEngine } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | 28 | teardown(cleanup) 29 | 30 | test('retrieves crawler metrics', async t => { 31 | const client = new Client({ 32 | url, 33 | auth: { username, password } 34 | }) 35 | 36 | const engineName = await createEngine() 37 | await client.app.createCrawlerDomain({ 38 | engine_name: engineName, 39 | body: { 40 | name: 'https://www.elastic.co' 41 | } 42 | }) 43 | 44 | const response = await client.app.getCrawlerMetrics() 45 | 46 | t.type(response.global, 'object') 47 | t.type(response.node, 'object') 48 | 49 | await client.close() 50 | }) -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/crawler-overview.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown } from 'tap' 21 | import { cleanup, createEngine } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | 28 | teardown(cleanup) 29 | 30 | test('retrieves crawler configuration overview', async t => { 31 | const client = new Client({ 32 | url, 33 | auth: { username, password } 34 | }) 35 | 36 | const engineName = await createEngine() 37 | await client.app.createCrawlerDomain({ 38 | engine_name: engineName, 39 | body: { 40 | name: 'https://www.elastic.co' 41 | } 42 | }) 43 | 44 | const response = await client.app.getCrawlerOverview({ 45 | engine_name: engineName 46 | }) 47 | 48 | t.equal(response.domains.length, 1) 49 | t.equal(response.domains[0].name, 'https://www.elastic.co') 50 | 51 | await client.close() 52 | }) -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/crawler-process-crawl-denied-urls.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown } from 'tap' 21 | import { cleanup, createEngine } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | 28 | teardown(cleanup) 29 | 30 | test('retrieves denied urls for process crawl', async t => { 31 | const client = new Client({ 32 | url, 33 | auth: { username, password } 34 | }) 35 | 36 | const engineName = await createEngine() 37 | await client.app.createCrawlerDomain({ 38 | engine_name: engineName, 39 | body: { 40 | name: 'https://www.elastic.co' 41 | } 42 | }) 43 | 44 | const processCrawl = await client.app.createCrawlerProcessCrawl({ 45 | engine_name: engineName, 46 | body: { 47 | dry_run: true 48 | } 49 | }) 50 | 51 | const response = await client.app.getCrawlerProcessCrawlDeniedUrls({ 52 | engine_name: engineName, 53 | process_crawl_id: processCrawl.id! 54 | }) 55 | t.type(response.total_url_count, 'number') 56 | t.type(response.denied_url_count, 'number') 57 | t.type(response.sample_size, 'number') 58 | t.type(response.denied_urls_sample, 'object') 59 | 60 | await client.close() 61 | }) -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/crawler-process-crawl.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown, beforeEach } from 'tap' 21 | import { cleanup, createEngine } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | let engineName = '' 28 | 29 | teardown(cleanup) 30 | 31 | beforeEach(async () => { 32 | const client = new Client({ 33 | url, 34 | auth: { username, password } 35 | }) 36 | 37 | engineName = await createEngine() 38 | await client.app.createCrawlerDomain({ 39 | engine_name: engineName, 40 | body: { 41 | name: 'https://www.elastic.co' 42 | } 43 | }) 44 | 45 | await client.close() 46 | }) 47 | 48 | test('creates, retrieves and shows denied for a process crawl', async t => { 49 | const client = new Client({ 50 | url, 51 | auth: { username, password } 52 | }) 53 | 54 | const crawl = await client.app.createCrawlerProcessCrawl({ 55 | engine_name: engineName, 56 | body: { 57 | dry_run: true 58 | } 59 | }) 60 | 61 | t.same(crawl.domains, ['https://www.elastic.co']) 62 | 63 | const response = await client.app.getCrawlerProcessCrawl({ 64 | engine_name: engineName, 65 | process_crawl_id: crawl.id! 66 | }) 67 | t.type(response.total_url_count, 'number') 68 | t.type(response.denied_url_count, 'number') 69 | 70 | await client.close() 71 | }) 72 | 73 | test('lists process crawl', async t => { 74 | const client = new Client({ 75 | url, 76 | auth: { username, password } 77 | }) 78 | 79 | await client.app.createCrawlerProcessCrawl({ 80 | engine_name: engineName, 81 | body: { dry_run: true } 82 | }) 83 | await client.app.createCrawlerProcessCrawl({ 84 | engine_name: engineName, 85 | body: { dry_run: true } 86 | }) 87 | 88 | 89 | const response = await client.app.listCrawlerProcessCrawls({ 90 | engine_name: engineName 91 | }) 92 | t.equal(response.results.length, 2) 93 | 94 | await client.close() 95 | }) -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/crawler-scheduling.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown, beforeEach } from 'tap' 21 | import { cleanup, createEngine } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | let engineName = '' 28 | 29 | teardown(cleanup) 30 | 31 | beforeEach(async () => { 32 | const client = new Client({ 33 | url, 34 | auth: { username, password } 35 | }) 36 | 37 | engineName = await createEngine() 38 | await client.app.createCrawlerDomain({ 39 | engine_name: engineName, 40 | body: { 41 | name: 'https://www.elastic.co' 42 | } 43 | }) 44 | 45 | await client.close() 46 | }) 47 | 48 | test('sets a crawl schedule', async t => { 49 | const client = new Client({ 50 | url, 51 | auth: { username, password } 52 | }) 53 | 54 | const response = await client.app.putCrawlerCrawlSchedule({ 55 | engine_name: engineName, 56 | body: { 57 | frequency: 1, 58 | unit: 'day' 59 | } 60 | }) 61 | 62 | t.same(response, { 63 | engine: engineName, 64 | frequency: 1, 65 | unit: 'day' 66 | }) 67 | 68 | await client.close() 69 | }) 70 | 71 | test('gets the crawl schedule', async t => { 72 | const client = new Client({ 73 | url, 74 | auth: { username, password } 75 | }) 76 | 77 | await client.app.putCrawlerCrawlSchedule({ 78 | engine_name: engineName, 79 | body: { 80 | frequency: 1, 81 | unit: 'day' 82 | } 83 | }) 84 | 85 | const response = await client.app.getCrawlerCrawlSchedule({ 86 | engine_name: engineName 87 | }) 88 | t.same(response, { 89 | engine: engineName, 90 | frequency: 1, 91 | unit: 'day' 92 | }) 93 | 94 | await client.close() 95 | }) 96 | 97 | test('deletes a crawler crawl schedule', async t => { 98 | const client = new Client({ 99 | url, 100 | auth: { username, password } 101 | }) 102 | 103 | await client.app.putCrawlerCrawlSchedule({ 104 | engine_name: engineName, 105 | body: { 106 | frequency: 1, 107 | unit: 'day' 108 | } 109 | }) 110 | 111 | const response = await client.app.deleteCrawlerCrawlSchedule({ 112 | engine_name: engineName 113 | }) 114 | t.ok(response.deleted) 115 | 116 | await client.close() 117 | }) -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/crawler-sitemap.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown, beforeEach } from 'tap' 21 | import { cleanup, createEngine } from '../helper' 22 | import { Client, AppTypes } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | let engineName = '' 28 | let domain: AppTypes.GetCrawlerDomainResponse 29 | 30 | teardown(cleanup) 31 | 32 | beforeEach(async () => { 33 | const client = new Client({ 34 | url, 35 | auth: { username, password } 36 | }) 37 | 38 | engineName = await createEngine() 39 | domain = await client.app.createCrawlerDomain({ 40 | engine_name: engineName, 41 | body: { 42 | name: 'https://www.elastic.co' 43 | } 44 | }) 45 | 46 | await client.close() 47 | }) 48 | 49 | test('creates, updates and deletes a crawler sitemap configuration', async t => { 50 | const client = new Client({ 51 | url, 52 | auth: { username, password } 53 | }) 54 | 55 | const sitemap = await client.app.createCrawlerSitemap({ 56 | engine_name: engineName, 57 | domain_id: domain.id!, 58 | body: { 59 | url: 'https://www.elastic.co/sitemap.xml' 60 | } 61 | }) 62 | 63 | t.type(sitemap.id, 'string') 64 | t.type(sitemap.created_at, 'string') 65 | t.equal(sitemap.url, 'https://www.elastic.co/sitemap.xml') 66 | 67 | const response1 = await client.app.putCrawlerSitemap({ 68 | engine_name: engineName, 69 | domain_id: domain.id!, 70 | sitemap_id: sitemap.id!, 71 | body: { 72 | url: 'https://www.elastic.co/sitemap2.xml' 73 | } 74 | }) 75 | 76 | t.type(response1.id, 'string') 77 | t.type(response1.created_at, 'string') 78 | t.equal(response1.url, 'https://www.elastic.co/sitemap2.xml') 79 | 80 | const response2 = await client.app.deleteCrawlerSitemap({ 81 | engine_name: engineName, 82 | domain_id: domain.id!, 83 | sitemap_id: sitemap.id! 84 | }) 85 | 86 | t.ok(response2.deleted) 87 | 88 | await client.close() 89 | }) -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/crawler-urls.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown, beforeEach } from 'tap' 21 | import { cleanup, createEngine } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | let engineName = '' 28 | 29 | teardown(cleanup) 30 | 31 | beforeEach(async () => { 32 | const client = new Client({ 33 | url, 34 | auth: { username, password } 35 | }) 36 | 37 | engineName = await createEngine() 38 | await client.app.createCrawlerDomain({ 39 | engine_name: engineName, 40 | body: { 41 | name: 'https://www.elastic.co' 42 | } 43 | }) 44 | 45 | await client.close() 46 | }) 47 | 48 | test('validates a URL', { skip: 'bad definition' }, async t => { 49 | const client = new Client({ 50 | url, 51 | auth: { username, password } 52 | }) 53 | 54 | const response = await client.app.getCrawlerUrlValidationResult({ 55 | engine_name: engineName, 56 | // @ts-expect-error 57 | body: { 58 | url: 'https://www.elastic.co' 59 | } 60 | }) 61 | 62 | t.ok(response.valid) 63 | 64 | await client.close() 65 | }) 66 | 67 | test('extracts content from a URL', { skip: 'bad definition' }, async t => { 68 | const client = new Client({ 69 | url, 70 | auth: { username, password } 71 | }) 72 | 73 | const response = await client.app.getCrawlerUrlExtractionResult({ 74 | engine_name: engineName, 75 | // @ts-expect-error 76 | body: { 77 | url: 'https://www.elastic.co' 78 | } 79 | }) 80 | 81 | t.type(response.url, 'string') 82 | t.type(response.normalized_url, 'string') 83 | t.type(response.results, 'object') 84 | 85 | await client.close() 86 | }) 87 | 88 | test('traces history for a crawler URL', { skip: 'bad definition' }, async t => { 89 | const client = new Client({ 90 | url, 91 | auth: { username, password } 92 | }) 93 | 94 | const response = await client.app.getCrawlerUrlTracingResult({ 95 | engine_name: engineName, 96 | // @ts-expect-error 97 | body: { 98 | url: 'https://www.elastic.co' 99 | } 100 | }) 101 | 102 | t.type(response.url, 'string') 103 | t.type(response.normalized_url, 'string') 104 | t.type(response.crawl_requests, 'object') 105 | 106 | await client.close() 107 | }) 108 | -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/crawler-user-agent.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown } from 'tap' 21 | import { cleanup } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | 28 | teardown(cleanup) 29 | 30 | test('retrieves the user-agent header value for the crawler', async t => { 31 | const client = new Client({ 32 | url, 33 | auth: { username, password } 34 | }) 35 | 36 | const response = await client.app.getCrawlerUserAgent() 37 | 38 | t.type(response.user_agent, 'string') 39 | 40 | await client.close() 41 | }) -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/curations.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown, beforeEach } from 'tap' 21 | import { cleanup, createEngine, createCuration, sleep } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | let engineName = '' 28 | let promoted: { id: string } 29 | let hidden: { id: string } 30 | 31 | teardown(cleanup) 32 | 33 | beforeEach(async () => { 34 | const client = new Client({ 35 | url, 36 | auth: { username, password } 37 | }) 38 | 39 | engineName = await createEngine() 40 | const response = await client.app.indexDocuments({ 41 | engine_name: engineName, 42 | documents: [{ 43 | title: 'Jungle Tales', author: 'Horacio Quiroga' 44 | }, { 45 | title: 'The Jungle Book', author: 'Rudyard Kipling' 46 | }] 47 | }) 48 | promoted = response[0] 49 | hidden = response[1] 50 | 51 | await client.close() 52 | }) 53 | 54 | test('creates a new curation', async t => { 55 | const client = new Client({ 56 | url, 57 | auth: { username, password } 58 | }) 59 | 60 | const curation = await client.app.createCuration({ 61 | engine_name: engineName, 62 | body: { 63 | queries: ['jungle'], 64 | promoted: [promoted.id], 65 | hidden: [hidden.id] 66 | } 67 | }) 68 | await sleep(500) 69 | t.ok(/cur-[0-9a-f]+/.test(curation.id)) 70 | 71 | const response = await client.app.search({ 72 | engine_name: engineName, 73 | body: { 74 | query: 'jungle' 75 | } 76 | }) 77 | t.equal(response.results.length, 1) 78 | // @ts-expect-error 79 | t.equal(response.results[0].title.raw, 'Jungle Tales') 80 | 81 | await client.close() 82 | }) 83 | 84 | test('retrieves a curation by id', async t => { 85 | const client = new Client({ 86 | url, 87 | auth: { username, password } 88 | }) 89 | 90 | const id = await createCuration(engineName, ['book'], [promoted.id], [hidden.id]) 91 | 92 | const response = await client.app.getCuration({ 93 | engine_name: engineName, 94 | curation_id: id 95 | }) 96 | t.ok(/cur-[0-9a-f]+/.test(response.id!)) 97 | t.same(response.queries, ['book']) 98 | t.same(response.promoted, [promoted.id]) 99 | t.same(response.hidden, [hidden.id]) 100 | 101 | await client.close() 102 | }) 103 | 104 | test('updates an existing curation', async t => { 105 | const client = new Client({ 106 | url, 107 | auth: { username, password } 108 | }) 109 | 110 | const id = await createCuration(engineName, ['jungle'], [promoted.id], [hidden.id]) 111 | 112 | await client.app.putCuration({ 113 | engine_name: engineName, 114 | curation_id: id, 115 | body: { 116 | queries: ['jungle'], 117 | promoted: [hidden.id], 118 | hidden: [promoted.id] 119 | } 120 | }) 121 | 122 | const response = await client.app.search({ 123 | engine_name: engineName, 124 | body: { 125 | query: 'jungle' 126 | } 127 | }) 128 | t.equal(response.results.length, 1) 129 | // @ts-expect-error 130 | t.equal(response.results[0].title.raw, 'The Jungle Book') 131 | 132 | await client.close() 133 | }) 134 | 135 | test('lists curations', async t => { 136 | const client = new Client({ 137 | url, 138 | auth: { username, password } 139 | }) 140 | 141 | const curations = [ 142 | await createCuration(engineName, ['jungle'], [promoted.id], [hidden.id]), 143 | await createCuration(engineName, ['book'], [promoted.id], [hidden.id]), 144 | await createCuration(engineName, ['tales'], [promoted.id], [hidden.id]) 145 | ] 146 | 147 | const response = await client.app.listCurations({ engine_name: engineName }) 148 | t.equal(response.results.length, 3) 149 | for (const result of response.results) { 150 | t.ok(curations.includes(result.id!)) 151 | } 152 | 153 | await client.close() 154 | }) 155 | 156 | test('deletes a curation', async t => { 157 | const client = new Client({ 158 | url, 159 | auth: { username, password } 160 | }) 161 | 162 | const id = await createCuration(engineName, ['jungle'], [promoted.id], [hidden.id]) 163 | 164 | const response = await client.app.deleteCuration({ 165 | engine_name: engineName, 166 | curation_id: id 167 | }) 168 | t.ok(response.deleted) 169 | 170 | await client.close() 171 | }) -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/documents.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown, beforeEach } from 'tap' 21 | import { cleanup, createEngine, sleep } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | let engineName = '' 28 | let documentIds: string[] 29 | 30 | teardown(cleanup) 31 | 32 | beforeEach(async () => { 33 | const client = new Client({ 34 | url, 35 | auth: { username, password } 36 | }) 37 | 38 | engineName = await createEngine() 39 | const response = await client.app.indexDocuments({ 40 | engine_name: engineName, 41 | documents: [ 42 | { name: 'Super Lorenzo Bros', year: '1985' }, 43 | { name: 'Pack-Man', year: '1980' }, 44 | { name: 'Galaxxian', year: '1979' }, 45 | { name: 'Audiovisual, the hedgehog', year: '1991' } 46 | ] 47 | }) 48 | documentIds = response.map(doc => doc.id) 49 | let list = await client.app.listDocuments({ engine_name: engineName }) 50 | let attempts = 0 51 | while (list.results.length < 1 && attempts < 20) { 52 | await sleep(500) 53 | attempts += 1 54 | list = await client.app.listDocuments({ engine_name: engineName }) 55 | } 56 | await client.close() 57 | }) 58 | 59 | test('indexes and lists documents', async t => { 60 | const client = new Client({ 61 | url, 62 | auth: { username, password } 63 | }) 64 | 65 | const response = await client.app.listDocuments({ engine_name: engineName }) 66 | t.equal(response.results.length, 4) 67 | 68 | await client.close() 69 | }) 70 | 71 | test('retrieves documents by ID (body)', async t => { 72 | const client = new Client({ 73 | url, 74 | auth: { username, password } 75 | }) 76 | 77 | const response = await client.app.getDocuments({ 78 | engine_name: engineName, 79 | documentIds 80 | }) 81 | t.equal(response.length, 4) 82 | 83 | await client.close() 84 | }) 85 | 86 | test('retrieves documents by ID (querystring)', async t => { 87 | const client = new Client({ 88 | url, 89 | auth: { username, password } 90 | }) 91 | 92 | const response = await client.app.getDocuments({ 93 | engine_name: engineName, 94 | ids: documentIds 95 | }) 96 | t.equal(response.length, 4) 97 | 98 | await client.close() 99 | }) 100 | 101 | test('searches for a document', async t => { 102 | const client = new Client({ 103 | url, 104 | auth: { username, password } 105 | }) 106 | 107 | const response = await client.app.search({ 108 | engine_name: engineName, 109 | body: { 110 | query: 'Pack-Man' 111 | } 112 | }) 113 | // @ts-expect-error 114 | t.equal(response.results[0].name.raw, 'Pack-Man') 115 | // @ts-expect-error 116 | t.equal(response.results[0].year.raw, '1980') 117 | 118 | await client.close() 119 | }) 120 | 121 | test('deletes a document', async t => { 122 | const client = new Client({ 123 | url, 124 | auth: { username, password } 125 | }) 126 | 127 | const response = await client.app.deleteDocuments({ 128 | engine_name: engineName, 129 | documentIds: [documentIds[0]] 130 | }) 131 | t.same(response, [{ 132 | id: documentIds[0], 133 | deleted: true 134 | }]) 135 | 136 | await client.close() 137 | }) 138 | 139 | test('updates a document', async t => { 140 | const client = new Client({ 141 | url, 142 | auth: { username, password } 143 | }) 144 | 145 | const response1 = await client.app.putDocuments({ 146 | engine_name: engineName, 147 | documents: [{ id: documentIds[0], year: '9999' }] 148 | }) 149 | t.same(response1, [{ 150 | id: documentIds[0], 151 | errors: [] 152 | }]) 153 | 154 | const response2 = await client.app.getDocuments({ 155 | engine_name: engineName, 156 | documentIds: [documentIds[0]] 157 | }) 158 | t.equal(response2[0]?.year, '9999') 159 | 160 | await client.close() 161 | }) 162 | -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/engines.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown, afterEach } from 'tap' 21 | import { cleanup, genName, createEngine, deleteEngines } from '../helper' 22 | import { Client, errors } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | 28 | teardown(cleanup) 29 | 30 | afterEach(async () => { 31 | await deleteEngines() 32 | }) 33 | 34 | test('creates a new engine', async t => { 35 | const client = new Client({ 36 | url, 37 | auth: { username, password } 38 | }) 39 | 40 | const engineName = genName() 41 | const response = await client.app.createEngine({ 42 | body: { 43 | name: engineName 44 | } 45 | }) 46 | t.same(response, { 47 | name: engineName, 48 | type: 'default', 49 | language: null, 50 | index_create_settings_override: {}, 51 | document_count: 0 52 | }) 53 | 54 | await client.close() 55 | }) 56 | 57 | test('lists engines', async t => { 58 | const client = new Client({ 59 | url, 60 | auth: { username, password } 61 | }) 62 | 63 | const engines = [ 64 | await createEngine(), 65 | await createEngine() 66 | ] 67 | 68 | const response = await client.app.listEngines() 69 | t.equal(response.results.length, 2) 70 | t.ok(engines.includes(response.results[0].name)) 71 | t.ok(engines.includes(response.results[1].name)) 72 | 73 | await client.close() 74 | }) 75 | 76 | test('retrieves an engine by name', async t => { 77 | const client = new Client({ 78 | url, 79 | auth: { username, password } 80 | }) 81 | 82 | const engineName = await createEngine() 83 | 84 | const response = await client.app.getEngine({ engine_name: engineName }) 85 | t.same(response, { 86 | name: engineName, 87 | type: 'default', 88 | language: null, 89 | index_create_settings_override: {}, 90 | document_count: 0 91 | }) 92 | 93 | await client.close() 94 | }) 95 | 96 | test('deletes an engine', async t => { 97 | const client = new Client({ 98 | url, 99 | auth: { username, password } 100 | }) 101 | 102 | const engineName = await createEngine() 103 | 104 | const response = await client.app.deleteEngine({ engine_name: engineName }) 105 | t.ok(response.deleted) 106 | 107 | try { 108 | await client.app.getEngine({ engine_name: engineName }) 109 | } catch (err: any) { 110 | t.ok(err instanceof errors.ResponseError) 111 | t.equal(err.statusCode, 404) 112 | } 113 | 114 | await client.close() 115 | }) -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/log-clickthrough.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown } from 'tap' 21 | import { cleanup, createEngine } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | 28 | teardown(cleanup) 29 | 30 | test('logs clicked results', async t => { 31 | const client = new Client({ 32 | url, 33 | auth: { username, password } 34 | }) 35 | 36 | const engineName = await createEngine() 37 | const response = await client.app.logClickthrough({ 38 | engine_name: engineName, 39 | body: { 40 | query: 'moon', 41 | document_id: 'doc_id' 42 | } 43 | }) 44 | t.type(response, 'string') 45 | 46 | await client.close() 47 | }) -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/meta-engines.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown, beforeEach } from 'tap' 21 | import { cleanup, createEngine, genName } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | let engineNames: string[] = [] 28 | let metaEngineName = '' 29 | 30 | teardown(cleanup) 31 | 32 | beforeEach(async () => { 33 | const client = new Client({ 34 | url, 35 | auth: { username, password } 36 | }) 37 | 38 | engineNames = [ 39 | await createEngine(), 40 | await createEngine() 41 | ].sort() 42 | metaEngineName = genName() 43 | await client.app.createEngine({ 44 | body: { 45 | name: metaEngineName, 46 | type: 'meta', 47 | source_engines: engineNames 48 | } 49 | }) 50 | await client.close() 51 | }) 52 | 53 | test('creates a meta engine', async t => { 54 | const client = new Client({ 55 | url, 56 | auth: { username, password } 57 | }) 58 | 59 | const response = await client.app.getEngine({ engine_name: metaEngineName }) 60 | t.equal(response.name, metaEngineName) 61 | t.equal(response.type, 'meta') 62 | t.same(response.source_engines?.sort(), engineNames) 63 | 64 | await client.close() 65 | }) 66 | 67 | test('adds a new source engine to a meta engine', async t => { 68 | const client = new Client({ 69 | url, 70 | auth: { username, password } 71 | }) 72 | 73 | const engineName = await createEngine() 74 | const response = await client.app.addMetaEngineSource({ 75 | engine_name: metaEngineName, 76 | sourceEngines: [engineName] 77 | }) 78 | t.same(response.source_engines?.sort(), engineNames.concat(engineName).sort()) 79 | 80 | await client.close() 81 | }) 82 | 83 | test('removes a source engine from a meta engine', async t => { 84 | const client = new Client({ 85 | url, 86 | auth: { username, password } 87 | }) 88 | 89 | const response = await client.app.deleteMetaEngineSource({ 90 | engine_name: metaEngineName, 91 | sourceEngines: [engineNames[0]] 92 | }) 93 | t.same(response.source_engines, [engineNames[1]]) 94 | 95 | await client.close() 96 | }) -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/query-suggestion.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown } from 'tap' 21 | import { cleanup, createEngine, sleep } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | 28 | teardown(cleanup) 29 | 30 | test('provides query suggestions', async t => { 31 | const client = new Client({ 32 | url, 33 | auth: { username, password } 34 | }) 35 | 36 | const engineName = await createEngine() 37 | await client.app.indexDocuments({ 38 | engine_name: engineName, 39 | documents: [{ title: 'A trip to the moon' }] 40 | }) 41 | 42 | await sleep(1000) 43 | 44 | const response = await client.app.querySuggestion({ 45 | engine_name: engineName, 46 | body: { 47 | query: 'moo' 48 | } 49 | }) 50 | 51 | t.same(response.results?.documents, [{ suggestion: 'moon' }]) 52 | 53 | await client.close() 54 | }) -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/schema.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown, beforeEach } from 'tap' 21 | import { cleanup, createEngine, sleep } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | let engineName = '' 28 | 29 | teardown(cleanup) 30 | 31 | beforeEach(async () => { 32 | const client = new Client({ 33 | url, 34 | auth: { username, password } 35 | }) 36 | 37 | engineName = await createEngine() 38 | await client.app.indexDocuments({ 39 | engine_name: engineName, 40 | documents: [{ title: 'test', director: 'someone' }] 41 | }) 42 | await sleep(1000) 43 | await client.close() 44 | }) 45 | 46 | test('returns an engine schema', async t => { 47 | const client = new Client({ 48 | url, 49 | auth: { username, password } 50 | }) 51 | 52 | const response = await client.app.getSchema({ engine_name: engineName }) 53 | t.same(response, { 54 | title: 'text', 55 | director: 'text' 56 | }) 57 | 58 | await client.close() 59 | }) 60 | 61 | test('updates a schema for an engine', async t => { 62 | const client = new Client({ 63 | url, 64 | auth: { username, password } 65 | }) 66 | 67 | const schema = await client.app.putSchema({ 68 | engine_name: engineName, 69 | // @ts-expect-error 70 | schema: { year: 'number' } 71 | }) 72 | t.same(schema, { 73 | title: 'text', 74 | director: 'text', 75 | year: 'number' 76 | }) 77 | 78 | const response = await client.app.getSchema({ engine_name: engineName }) 79 | t.same(response, { 80 | title: 'text', 81 | director: 'text', 82 | year: 'number' 83 | }) 84 | 85 | await client.close() 86 | }) -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/search-settings.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown, beforeEach } from 'tap' 21 | import { cleanup, createEngine, sleep } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | let engineName = '' 28 | 29 | teardown(cleanup) 30 | 31 | beforeEach(async () => { 32 | const client = new Client({ 33 | url, 34 | auth: { username, password } 35 | }) 36 | 37 | engineName = await createEngine() 38 | await client.close() 39 | }) 40 | 41 | test('returns engine search settings', async t => { 42 | const client = new Client({ 43 | url, 44 | auth: { username, password } 45 | }) 46 | 47 | const response = await client.app.getSearchSettings({ engine_name: engineName }) 48 | t.type(response.search_fields, 'object') 49 | t.type(response.result_fields, 'object') 50 | t.type(response.boosts, 'object') 51 | 52 | await client.close() 53 | }) 54 | 55 | test('update search settings', async t => { 56 | const client = new Client({ 57 | url, 58 | auth: { username, password } 59 | }) 60 | 61 | // @ts-expect-error 62 | await client.app.putSchema({ engine_name: engineName, schema: { year: 'number' } }) 63 | await client.app.indexDocuments({ 64 | engine_name: engineName, 65 | documents: [ 66 | { title: 'Attack of the Giant Leeches', year: 1959, director: 'Bernard L. Kowalski' }, 67 | { title: '20,000 Leagues Under the Sea', year: 1916, director: 'Stuart Paton' }, 68 | { title: 'Indestructible Man', year: 1956, director: 'Jack Pollexfen' }, 69 | { title: 'Metropolis', year: 1927, director: 'Fritz Lang' } 70 | ] 71 | }) 72 | await sleep(1000) 73 | 74 | const response = await client.app.putSearchSettings({ 75 | engine_name: engineName, 76 | body: { 77 | boosts: { 78 | year: [{ 79 | type: 'proximity', 80 | function: 'linear', 81 | center: 1950, 82 | factor: 9 83 | }] 84 | } 85 | } 86 | }) 87 | t.same(response.boosts, { 88 | year: [{ 89 | type: 'proximity', 90 | function: 'linear', 91 | center: 1950, 92 | factor: 9 93 | }] 94 | }) 95 | 96 | await client.close() 97 | }) 98 | 99 | test('resets search setting', async t => { 100 | const client = new Client({ 101 | url, 102 | auth: { username, password } 103 | }) 104 | 105 | const response = await client.app.resetSearchSettings({ engine_name: engineName }) 106 | t.type(response.search_fields, 'object') 107 | t.type(response.result_fields, 'object') 108 | t.type(response.boosts, 'object') 109 | 110 | await client.close() 111 | }) -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/synonyms.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown, beforeEach } from 'tap' 21 | import { cleanup, createEngine } from '../helper' 22 | import { Client, errors } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | let engineName = '' 28 | 29 | teardown(cleanup) 30 | 31 | beforeEach(async () => { 32 | const client = new Client({ 33 | url, 34 | auth: { username, password } 35 | }) 36 | 37 | engineName = await createEngine() 38 | await client.close() 39 | }) 40 | 41 | test('creates a synonym set', async t => { 42 | const client = new Client({ 43 | url, 44 | auth: { username, password } 45 | }) 46 | 47 | const response = await client.app.createSynonymSet({ 48 | engine_name: engineName, 49 | body: { 50 | synonyms: ['joypad', 'gamepad'] 51 | } 52 | }) 53 | t.same(response.synonyms, ['joypad', 'gamepad']) 54 | t.type(response.id, 'string') 55 | 56 | await client.close() 57 | }) 58 | 59 | test('lists a synonym set', async t => { 60 | const client = new Client({ 61 | url, 62 | auth: { username, password } 63 | }) 64 | 65 | await client.app.createSynonymSet({ 66 | engine_name: engineName, 67 | body: { 68 | synonyms: ['joypad', 'gamepad'] 69 | } 70 | }) 71 | 72 | const response = await client.app.listSynonymSets({ engine_name: engineName }) 73 | t.ok(response.results.length > 0) 74 | t.same(response.results[0].synonyms, ['joypad', 'gamepad']) 75 | 76 | await client.close() 77 | }) 78 | 79 | test('retrieves a synonym set by ID', async t => { 80 | const client = new Client({ 81 | url, 82 | auth: { username, password } 83 | }) 84 | 85 | const synonym = await client.app.createSynonymSet({ 86 | engine_name: engineName, 87 | body: { 88 | synonyms: ['joypad', 'gamepad'] 89 | } 90 | }) 91 | 92 | const response = await client.app.getSynonymSet({ 93 | engine_name: engineName, 94 | synonym_set_id: synonym.id! 95 | }) 96 | t.same(response.synonyms, ['joypad', 'gamepad']) 97 | 98 | await client.close() 99 | }) 100 | 101 | test('updates a synonym set', async t => { 102 | const client = new Client({ 103 | url, 104 | auth: { username, password } 105 | }) 106 | 107 | const synonym = await client.app.createSynonymSet({ 108 | engine_name: engineName, 109 | body: { 110 | synonyms: ['joypad', 'gamepad'] 111 | } 112 | }) 113 | 114 | const response1 = await client.app.putSynonymSet({ 115 | engine_name: engineName, 116 | synonym_set_id: synonym.id!, 117 | body: { 118 | synonyms: ['gamepad', 'controller'] 119 | } 120 | }) 121 | t.same(response1.synonyms, ['gamepad', 'controller']) 122 | 123 | const response2 = await client.app.getSynonymSet({ 124 | engine_name: engineName, 125 | synonym_set_id: synonym.id! 126 | }) 127 | t.same(response2.synonyms, ['gamepad', 'controller']) 128 | 129 | await client.close() 130 | }) 131 | 132 | test('deletes a synonym set', async t => { 133 | const client = new Client({ 134 | url, 135 | auth: { username, password } 136 | }) 137 | 138 | const synonym = await client.app.createSynonymSet({ 139 | engine_name: engineName, 140 | body: { 141 | synonyms: ['joypad', 'gamepad'] 142 | } 143 | }) 144 | 145 | const response1 = await client.app.deleteSynonymSet({ 146 | engine_name: engineName, 147 | synonym_set_id: synonym.id! 148 | }) 149 | t.ok(response1.deleted) 150 | 151 | try { 152 | await client.app.getSynonymSet({ 153 | engine_name: engineName, 154 | synonym_set_id: synonym.id! 155 | }) 156 | } catch (err: any) { 157 | t.ok(err instanceof errors.ResponseError) 158 | t.equal(err.statusCode, 404) 159 | } 160 | 161 | await client.close() 162 | }) -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/top-clicks-analytics.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown, beforeEach } from 'tap' 21 | import { cleanup, createEngine } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | let engineName = '' 28 | 29 | teardown(cleanup) 30 | 31 | beforeEach(async () => { 32 | const client = new Client({ 33 | url, 34 | auth: { username, password } 35 | }) 36 | 37 | engineName = await createEngine() 38 | await client.close() 39 | }) 40 | 41 | test('returns api_top_clicks_analytics with no query', async t => { 42 | const client = new Client({ 43 | url, 44 | auth: { username, password } 45 | }) 46 | 47 | const response = await client.app.getTopClicksAnalytics({ engine_name: engineName }) 48 | t.type(response.meta, 'object') 49 | t.type(response.results, 'object') 50 | 51 | await client.close() 52 | }) 53 | 54 | test('returns api_top_clicks_analytics with query', async t => { 55 | const client = new Client({ 56 | url, 57 | auth: { username, password } 58 | }) 59 | 60 | const response = await client.app.getTopClicksAnalytics({ 61 | engine_name: engineName, 62 | body: { 63 | query: 'test' 64 | } 65 | }) 66 | t.type(response.meta, 'object') 67 | t.type(response.results, 'object') 68 | 69 | await client.close() 70 | }) -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/app/top-queries-analytics.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown, beforeEach } from 'tap' 21 | import { cleanup, createEngine } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | let engineName = '' 28 | 29 | teardown(cleanup) 30 | 31 | beforeEach(async () => { 32 | const client = new Client({ 33 | url, 34 | auth: { username, password } 35 | }) 36 | 37 | engineName = await createEngine() 38 | await client.close() 39 | }) 40 | 41 | test('returns api_top_queries_analytics with no query', async t => { 42 | const client = new Client({ 43 | url, 44 | auth: { username, password } 45 | }) 46 | 47 | const response = await client.app.getTopQueriesAnalytics({ engine_name: engineName }) 48 | t.type(response.meta, 'object') 49 | t.type(response.results, 'object') 50 | 51 | await client.close() 52 | }) -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/enterprise/index.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test } from 'tap' 21 | import { Client } from '../../..' 22 | 23 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 24 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 25 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 26 | 27 | test('getHealth', async t => { 28 | const client = new Client({ 29 | url, 30 | auth: { username, password } 31 | }) 32 | 33 | const response = await client.enterprise.getHealth() 34 | t.type(response.name, 'string') 35 | t.type(response.cluster_uuid, 'string') 36 | 37 | await client.close() 38 | }) 39 | 40 | test('getReadOnly', async t => { 41 | const client = new Client({ 42 | url, 43 | auth: { username, password } 44 | }) 45 | 46 | const response = await client.enterprise.getReadOnly() 47 | t.type(response.enabled, 'boolean') 48 | 49 | await client.close() 50 | }) 51 | 52 | test('putReadOnly true', async t => { 53 | const client = new Client({ 54 | url, 55 | auth: { username, password } 56 | }) 57 | 58 | let response = await client.enterprise.putReadOnly({ 59 | body: { enabled: true } 60 | }) 61 | t.equal(response.enabled, true) 62 | 63 | response = await client.enterprise.getReadOnly() 64 | t.equal(response.enabled, true) 65 | 66 | await client.close() 67 | }) 68 | 69 | test('putReadOnly false', async t => { 70 | const client = new Client({ 71 | url, 72 | auth: { username, password } 73 | }) 74 | 75 | let response = await client.enterprise.putReadOnly({ 76 | body: { enabled: false } 77 | }) 78 | t.equal(response.enabled, false) 79 | 80 | response = await client.enterprise.getReadOnly() 81 | t.equal(response.enabled, false) 82 | 83 | await client.close() 84 | }) 85 | 86 | test('getStats', async t => { 87 | const client = new Client({ 88 | url, 89 | auth: { username, password } 90 | }) 91 | 92 | const response = await client.enterprise.getStats() 93 | t.type(response.cluster_uuid, 'string') 94 | t.type(response.app.pid, 'number') 95 | t.type(response.connectors.alive, 'boolean') 96 | 97 | await client.close() 98 | }) 99 | 100 | test('getVersion', async t => { 101 | const client = new Client({ 102 | url, 103 | auth: { username, password } 104 | }) 105 | 106 | const response = await client.enterprise.getVersion() 107 | t.type(response.number, 'string') 108 | t.type(response.build_hash, 'string') 109 | t.type(response.build_date, 'string') 110 | 111 | await client.close() 112 | }) -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/helper.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { promisify } from 'util' 21 | import { customAlphabet } from 'nanoid' 22 | import { Client } from '../..' 23 | 24 | const sleep = promisify(setTimeout) 25 | const genName = customAlphabet('abcdefghijklmnopqrstuvwxyz0123456789', 10) 26 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 27 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 28 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 29 | 30 | export { genName, sleep } 31 | 32 | export async function createEngine (name = genName()): Promise { 33 | const client = new Client({ url, auth: { username, password } }) 34 | await client.app.createEngine({ body: { name } }) 35 | await client.close() 36 | return name 37 | } 38 | 39 | export async function createCuration (engineName: string, queries: string[], promoted: string[], hidden: string[]): Promise { 40 | const client = new Client({ url, auth: { username, password } }) 41 | const curation = await client.app.createCuration({ 42 | engine_name: engineName, 43 | body: { 44 | queries, 45 | promoted, 46 | hidden 47 | } 48 | }) 49 | await client.close() 50 | await sleep(500) 51 | return curation.id 52 | } 53 | 54 | export async function deleteEngines (name?: string): Promise { 55 | const client = new Client({ url, auth: { username, password } }) 56 | if (typeof name === 'string') { 57 | await client.app.deleteEngine({ engine_name: name }) 58 | } else { 59 | const { results } = await client.app.listEngines() 60 | for (const { name } of results) { 61 | await client.app.deleteEngine({ engine_name: name }) 62 | } 63 | } 64 | await client.close() 65 | } 66 | 67 | export async function createContentSource (name = genName()): Promise { 68 | const client = new Client({ url, auth: { username, password } }) 69 | const response = await client.workplace.createContentSource({ body: { name } }) 70 | await client.close() 71 | return response.id 72 | } 73 | 74 | export async function deleteContentSources (id?: string): Promise { 75 | const client = new Client({ url, auth: { username, password } }) 76 | if (typeof id === 'string') { 77 | await client.workplace.deleteContentSource({ content_source_id: id }) 78 | } else { 79 | const { results } = await client.workplace.listContentSources() 80 | for (const { id } of results) { 81 | await client.workplace.deleteContentSource({ content_source_id: id }) 82 | } 83 | } 84 | await client.close() 85 | } 86 | 87 | export async function cleanup (): Promise { 88 | const client = new Client({ url, auth: { username, password } }) 89 | 90 | const engines = await client.app.listEngines() 91 | for (const { name } of engines.results) { 92 | await client.app.deleteEngine({ engine_name: name }) 93 | } 94 | 95 | const apiKeys = await client.app.listApiKeys() 96 | for (const { name } of apiKeys.results) { 97 | await client.app.deleteApiKey({ api_key_name: name }) 98 | } 99 | 100 | const contentSources = await client.workplace.listContentSources() 101 | for (const { id } of contentSources.results) { 102 | await client.workplace.deleteContentSource({ content_source_id: id }) 103 | } 104 | 105 | await client.close() 106 | } 107 | -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/workplace/content-sources.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { readFile } from 'fs/promises' 21 | import { join } from 'path' 22 | import { test, beforeEach, teardown } from 'tap' 23 | import { cleanup, createContentSource, genName } from '../helper' 24 | import { Client } from '../../..' 25 | 26 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 27 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 28 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 29 | let contentSourceId = '' 30 | 31 | teardown(cleanup) 32 | 33 | beforeEach(async () => { 34 | contentSourceId = await createContentSource() 35 | }) 36 | 37 | test('creates, retrieves and deletes authenticated with basic auth', async t => { 38 | const client = new Client({ 39 | url, 40 | auth: { username, password } 41 | }) 42 | 43 | const contentSource = await client.workplace.getContentSource({ content_source_id: contentSourceId }) 44 | t.type(contentSource.name, 'string') 45 | 46 | const response1 = await client.workplace.listContentSources() 47 | t.equal(response1.results.length, 1) 48 | 49 | const response2 = await client.workplace.deleteContentSource({ content_source_id: contentSourceId }) 50 | t.ok(response2.deleted) 51 | 52 | const response3 = await client.workplace.listContentSources() 53 | t.equal(response3.results.length, 0) 54 | 55 | await client.close() 56 | }) 57 | 58 | test('creates and updates', async t => { 59 | const client = new Client({ 60 | url, 61 | auth: { username, password } 62 | }) 63 | 64 | const newName = genName() 65 | const contentSource = await client.workplace.getContentSource({ content_source_id: contentSourceId }) 66 | 67 | const response1 = await client.workplace.putContentSource({ 68 | content_source_id: contentSource.id, 69 | body: { 70 | name: newName, 71 | schema: { title: 'text', body: 'text', url: 'text' }, 72 | display: { title_field: 'title', url_field: 'url', color: '#f00f00' }, 73 | is_searchable: true 74 | } 75 | }) 76 | t.equal(response1.name, newName) 77 | 78 | const response2 = await client.workplace.getContentSource({ content_source_id: contentSource.id }) 79 | t.not(contentSource.name, response2.name) 80 | t.equal(response2.name, newName) 81 | 82 | await client.close() 83 | }) 84 | 85 | test('syncs jobs', async t => { 86 | const client = new Client({ 87 | url, 88 | auth: { username, password } 89 | }) 90 | 91 | const response = await client.workplace.commandSyncJobs({ 92 | content_source_id: contentSourceId, 93 | body: { command: 'interrupt' } 94 | }) 95 | t.same(Object.keys(response.results), ['interrupted']) 96 | 97 | await client.close() 98 | }) 99 | 100 | test('puts an icon', async t => { 101 | const client = new Client({ 102 | url, 103 | auth: { username, password } 104 | }) 105 | 106 | const icon = await readFile( 107 | join(__dirname, '..', '..', 'fixtures', 'icon.png'), 108 | { encoding: 'base64' } 109 | ) 110 | const response = await client.workplace.putContentSourceIcons({ 111 | content_source_id: contentSourceId, 112 | body: { 113 | main_icon: icon, 114 | alt_icon: icon 115 | } 116 | }) 117 | t.same(response.results, { 118 | main_icon: 'success', 119 | alt_icon: 'success' 120 | }) 121 | 122 | await client.close() 123 | }) 124 | 125 | test('auto query refinements details', async t => { 126 | const client = new Client({ 127 | url, 128 | auth: { username, password } 129 | }) 130 | 131 | const response = await client.workplace.getAutoQueryRefinementDetails({ content_source_id: contentSourceId }) 132 | t.type(response.results, 'object') 133 | t.type(response.overrides, 'object') 134 | t.type(response.defaults, 'object') 135 | 136 | await client.close() 137 | }) 138 | -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/workplace/documents.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, beforeEach, teardown } from 'tap' 21 | import { cleanup, createContentSource, sleep } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | let contentSourceId = '' 28 | const documents = [{ 29 | id: '4e696e74656e646f203634', 30 | url: 'https://www.elastic.co/blog/introducing-quick-start-guides-getting-started-with-elastic-enterprise-search-for-free', 31 | title: 'Getting started with Elastic Enterprise Search for free', 32 | body: 'this is a test' 33 | }, { 34 | id: '47616d6520426f7920436f6c6f72', 35 | url: 'https://www.elastic.co/workplace-search', 36 | title: 'One-stop answer shop for the virtual workplace', 37 | body: 'this is also a test' 38 | }] 39 | 40 | teardown(cleanup) 41 | 42 | beforeEach(async () => { 43 | contentSourceId = await createContentSource() 44 | }) 45 | 46 | test('indexes', async t => { 47 | const client = new Client({ 48 | url, 49 | auth: { username, password } 50 | }) 51 | 52 | const response = await client.workplace.indexDocuments({ 53 | content_source_id: contentSourceId, 54 | documents 55 | }) 56 | t.equal(response.results.length, 2) 57 | 58 | await client.close() 59 | }) 60 | 61 | test('deletes', async t => { 62 | const client = new Client({ 63 | url, 64 | auth: { username, password } 65 | }) 66 | 67 | await client.workplace.indexDocuments({ 68 | content_source_id: contentSourceId, 69 | documents 70 | }) 71 | 72 | await sleep(1000) 73 | 74 | const response = await client.workplace.deleteDocuments({ 75 | content_source_id: contentSourceId, 76 | document_ids: documents.map(doc => doc.id) 77 | }) 78 | t.equal(response.results.length, 2) 79 | 80 | await client.close() 81 | }) 82 | 83 | test('Gets a document in a content source', async t => { 84 | const client = new Client({ 85 | url, 86 | auth: { username, password } 87 | }) 88 | 89 | await client.workplace.indexDocuments({ 90 | content_source_id: contentSourceId, 91 | documents 92 | }) 93 | 94 | await sleep(1000) 95 | 96 | const response = await client.workplace.getDocument({ 97 | content_source_id: contentSourceId, 98 | document_id: documents[0].id 99 | }) 100 | t.type(response.updated_at, 'string') 101 | t.type(response.last_updated, 'string') 102 | t.equal(response.content_source_id, contentSourceId) 103 | t.match(response, documents[0]) 104 | 105 | await client.close() 106 | }) 107 | 108 | test('Deletes documents by query', { skip: 'bad definition?' }, async t => { 109 | const client = new Client({ 110 | url, 111 | auth: { username, password } 112 | }) 113 | 114 | await client.workplace.indexDocuments({ 115 | content_source_id: contentSourceId, 116 | documents 117 | }) 118 | 119 | await sleep(1000) 120 | 121 | const response = await client.workplace.deleteDocumentsByQuery({ 122 | content_source_id: contentSourceId, 123 | body: { 124 | // @ts-expect-error 125 | query: 'answer' 126 | } 127 | }) 128 | t.equal(response.deleted, 1) 129 | t.same(response.failures, {}) 130 | t.equal(response.total, 1) 131 | 132 | await client.close() 133 | }) 134 | -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/workplace/synonym.sets.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown, afterEach } from 'tap' 21 | import { cleanup } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | 28 | teardown(cleanup) 29 | 30 | afterEach(async () => { 31 | const client = new Client({ 32 | url, 33 | auth: { username, password } 34 | }) 35 | const synonyms = await client.workplace.listSynonymSets() 36 | for (const synonym of synonyms.results ?? []) { 37 | await client.workplace.deleteSynonymSet({ synonym_set_id: synonym.id! }) 38 | } 39 | await client.close() 40 | }) 41 | 42 | test('creates a batch synonym set', async t => { 43 | const client = new Client({ 44 | url, 45 | auth: { username, password } 46 | }) 47 | 48 | const response = await client.workplace.createBatchSynonymSets({ 49 | body: { 50 | synonym_sets: [ 51 | { synonyms: ['house', 'home', 'abode'] }, 52 | { synonyms: ['cat', 'feline', 'kitty'] }, 53 | { synonyms: ['mouses', 'mice'] } 54 | ] 55 | } 56 | }) 57 | t.equal(response.synonym_sets?.length, 3) 58 | t.notOk(response.has_errors) 59 | 60 | await client.close() 61 | }) 62 | 63 | test('lists a synonym set', async t => { 64 | const client = new Client({ 65 | url, 66 | auth: { username, password } 67 | }) 68 | 69 | await client.workplace.createBatchSynonymSets({ 70 | body: { 71 | synonym_sets: [ 72 | { synonyms: ['house', 'home', 'abode'] }, 73 | { synonyms: ['cat', 'feline', 'kitty'] }, 74 | { synonyms: ['mouses', 'mice'] } 75 | ] 76 | } 77 | }) 78 | 79 | const response = await client.workplace.listSynonymSets() 80 | t.equal(response.results?.length, 3) 81 | 82 | await client.close() 83 | }) 84 | 85 | test('get a single synonym set', async t => { 86 | const client = new Client({ 87 | url, 88 | auth: { username, password } 89 | }) 90 | 91 | const response = await client.workplace.createBatchSynonymSets({ 92 | body: { 93 | synonym_sets: [ 94 | { synonyms: ['house', 'home', 'abode'] }, 95 | { synonyms: ['cat', 'feline', 'kitty'] }, 96 | { synonyms: ['mouses', 'mice'] } 97 | ] 98 | } 99 | }) 100 | 101 | // @ts-expect-error 102 | const synomym = await client.workplace.getSynonymSet({ synonym_set_id: response.synonym_sets[0].id! }) 103 | t.same(synomym.synonyms, ['house', 'home', 'abode']) 104 | 105 | await client.close() 106 | }) 107 | 108 | test('updates a single synonym set', async t => { 109 | const client = new Client({ 110 | url, 111 | auth: { username, password } 112 | }) 113 | 114 | const response1 = await client.workplace.createBatchSynonymSets({ 115 | body: { 116 | synonym_sets: [ 117 | { synonyms: ['house', 'home', 'abode'] } 118 | ] 119 | } 120 | }) 121 | 122 | const response2 = await client.workplace.putSynonymSet({ 123 | // @ts-expect-error 124 | synonym_set_id: response1.synonym_sets[0].id!, 125 | body: { 126 | synonyms: ['mouses', 'mice', 'luch'] 127 | } 128 | }) 129 | // @ts-expect-error 130 | t.equal(response2.id, response1.synonym_sets[0].id!) 131 | 132 | // @ts-expect-error 133 | const synomym = await client.workplace.getSynonymSet({ synonym_set_id: response1.synonym_sets[0].id! }) 134 | t.same(synomym.synonyms, ['mouses', 'mice', 'luch']) 135 | 136 | await client.close() 137 | }) 138 | -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/workplace/triggers.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown } from 'tap' 21 | import { cleanup, genName } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | 28 | teardown(cleanup) 29 | 30 | test('creates a batch synonym set', { skip: 'the definiton is not correct' }, async t => { 31 | const client = new Client({ 32 | url, 33 | auth: { username, password } 34 | }) 35 | 36 | const newBlock = genName() 37 | const initial = await client.workplace.getTriggersBlocklist() 38 | t.type(initial.blocklist, 'object') 39 | 40 | const response = await client.workplace.putTriggersBlocklist({ 41 | body: initial.blocklist.concat(newBlock) 42 | }) 43 | t.same(response.blocklist, initial.blocklist.concat(newBlock)) 44 | 45 | await client.workplace.putTriggersBlocklist({ 46 | body: initial.blocklist 47 | }) 48 | 49 | await client.close() 50 | }) 51 | -------------------------------------------------------------------------------- /packages/enterprise-search/test/integration/workplace/users.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test, teardown } from 'tap' 21 | import { cleanup } from '../helper' 22 | import { Client } from '../../..' 23 | 24 | const url = process.env.ENTERPRISE_SEARCH_URL ?? 'http://localhost:3002' 25 | const username = process.env.ELASTIC_ENTERPRISE_USER ?? 'elastic' 26 | const password = process.env.ELASTIC_ENTERPRISE_PASSWORD ?? 'changeme' 27 | 28 | teardown(cleanup) 29 | 30 | test('gets the current user', async t => { 31 | const client = new Client({ 32 | url, 33 | auth: { username, password } 34 | }) 35 | 36 | const response = await client.workplace.getCurrentUser() 37 | t.same(Object.keys(response), ['email', 'username']) 38 | 39 | await client.close() 40 | }) 41 | -------------------------------------------------------------------------------- /packages/enterprise-search/test/unit/serializer.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Elasticsearch B.V. under one or more contributor 3 | * license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright 5 | * ownership. Elasticsearch B.V. licenses this file to you under 6 | * the Apache License, Version 2.0 (the "License"); you may 7 | * not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import { test } from 'tap' 21 | import qs from 'qs' 22 | import Serializer from '../../lib/Serializer' 23 | 24 | test('qserialize', t => { 25 | t.plan(1) 26 | const s = new Serializer() 27 | const obj = { 28 | hello: 'world', 29 | you_know: 'for search' 30 | } 31 | 32 | t.equal( 33 | s.qserialize(obj), 34 | qs.stringify(obj) 35 | ) 36 | }) 37 | 38 | test('qserialize array', t => { 39 | t.plan(1) 40 | const s = new Serializer() 41 | const obj = { 42 | foo: 'bar', 43 | baz: [1, 2, 3] 44 | } 45 | 46 | t.equal( 47 | s.qserialize(obj), 48 | 'foo=bar&baz%5B%5D=1&baz%5B%5D=2&baz%5B%5D=3' 49 | ) 50 | }) 51 | 52 | test('qserialize nested object', t => { 53 | t.plan(1) 54 | const s = new Serializer() 55 | const obj = { 56 | page: { 57 | size: 0, 58 | current: 1 59 | } 60 | } 61 | 62 | t.equal( 63 | s.qserialize(obj), 64 | 'page%5Bsize%5D=0&page%5Bcurrent%5D=1' 65 | ) 66 | }) 67 | -------------------------------------------------------------------------------- /packages/enterprise-search/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2019", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "declaration": true, 7 | "pretty": true, 8 | "noEmitOnError": true, 9 | "strict": true, 10 | "resolveJsonModule": true, 11 | "removeComments": false, 12 | "sourceMap": true, 13 | "newLine": "lf", 14 | "noUnusedLocals": true, 15 | "noFallthroughCasesInSwitch": true, 16 | "useDefineForClassFields": true, 17 | "forceConsistentCasingInFileNames": true, 18 | "skipLibCheck": false, 19 | "esModuleInterop": true, 20 | "isolatedModules": true, 21 | "importHelpers": true, 22 | "outDir": "lib", 23 | "lib": [ 24 | "esnext", 25 | "dom" 26 | ] 27 | }, 28 | "formatCodeOptions": { 29 | "identSize": 2, 30 | "tabSize": 2 31 | }, 32 | "exclude": [ 33 | "node_modules" 34 | ], 35 | "include": [ 36 | "./src/**/*.ts" 37 | ] 38 | } 39 | --------------------------------------------------------------------------------