aiiinotate 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/README.md +61 -0
- package/cli/import.js +142 -0
- package/cli/index.js +26 -0
- package/cli/io.js +105 -0
- package/cli/migrate.js +123 -0
- package/cli/mongoClient.js +11 -0
- package/docs/architecture.md +88 -0
- package/docs/db.md +38 -0
- package/docs/dev_iiif_compatibility.md +43 -0
- package/docs/endpoints.md +48 -0
- package/docs/progress.md +159 -0
- package/docs/specifications/0_w3c_open_annotations.md +332 -0
- package/docs/specifications/1_w3c_web_annotations.md +577 -0
- package/docs/specifications/2_iiif_apis.md +396 -0
- package/docs/specifications/3_iiif_annotations.md +103 -0
- package/docs/specifications/4_search_api.md +135 -0
- package/docs/specifications/5_sas.md +119 -0
- package/docs/specifications/6_mirador.md +119 -0
- package/docs/specifications/7_aikon.md +137 -0
- package/docs/specifications/include/presentation_2.0.webp +0 -0
- package/docs/specifications/include/presentation_2.0_white.png +0 -0
- package/docs/specifications/include/presentation_3.0.png +0 -0
- package/docs/specifications/include/presentation_3.0_resize.png +0 -0
- package/eslint.config.js +27 -0
- package/migrations/baseConfig.js +56 -0
- package/migrations/manageIndex.js +55 -0
- package/migrations/migrate-mongo-config-main.js +8 -0
- package/migrations/migrate-mongo-config-test.js +8 -0
- package/migrations/migrationScripts/20250825185706-collections.js +41 -0
- package/migrations/migrationScripts/20250826194832-annotations2-canvas-index.js +31 -0
- package/migrations/migrationScripts/20250904080710-annotations2-schema.js +42 -0
- package/migrations/migrationScripts/20251002141951-manifest2-schema.js +43 -0
- package/migrations/migrationScripts/20251006212110-manifest-unique-index.js +29 -0
- package/migrations/migrationScripts/20251028115614-annotations2-id-index.js +27 -0
- package/migrations/migrationTemplate.js +25 -0
- package/package.json +78 -0
- package/run.sh +70 -0
- package/scripts/_migrations.sh +79 -0
- package/scripts/_setup.js +31 -0
- package/scripts/setup_mongodb.sh +61 -0
- package/scripts/setup_mongodb_migrate.sh +17 -0
- package/scripts/setup_node.sh +15 -0
- package/scripts/utils.sh +192 -0
- package/setup.sh +20 -0
- package/src/app.js +113 -0
- package/src/config/.env.template +22 -0
- package/src/data/annotations/annotations2.js +419 -0
- package/src/data/annotations/annotations3.js +32 -0
- package/src/data/annotations/routes.js +271 -0
- package/src/data/annotations/routes.test.js +180 -0
- package/src/data/collectionAbstract.js +270 -0
- package/src/data/index.js +29 -0
- package/src/data/manifests/manifests2.js +305 -0
- package/src/data/manifests/manifests2.test.js +53 -0
- package/src/data/manifests/manifests3.js +23 -0
- package/src/data/manifests/routes.js +95 -0
- package/src/data/manifests/routes.test.js +69 -0
- package/src/data/routes.js +141 -0
- package/src/data/routes.test.js +117 -0
- package/src/data/utils/iiif2Utils.js +196 -0
- package/src/data/utils/iiif2Utils.test.js +98 -0
- package/src/data/utils/iiif3Utils.js +0 -0
- package/src/data/utils/iiifUtils.js +18 -0
- package/src/data/utils/routeUtils.js +109 -0
- package/src/data/utils/testUtils.js +253 -0
- package/src/data/utils/utils.js +231 -0
- package/src/db/index.js +48 -0
- package/src/fileServer/annotations.js +39 -0
- package/src/fileServer/data/annotationList_aikon_wit9_man11_anno165_all.jsonld +827 -0
- package/src/fileServer/data/annotationList_vhs_wit250_man250_anno250_all.jsonld +37514 -0
- package/src/fileServer/data/annotationList_vhs_wit253_man253_anno253_all.jsonld +20111 -0
- package/src/fileServer/data/annotations2Invalid.jsonld +39 -0
- package/src/fileServer/data/annotations2Valid.jsonld +39 -0
- package/src/fileServer/data/bnf_invalid_manifest.json +2806 -0
- package/src/fileServer/data/bnf_valid_manifest.json +2817 -0
- package/src/fileServer/data/vhs_wit253_man253_anno253_anno-24.json +1 -0
- package/src/fileServer/index.js +64 -0
- package/src/fileServer/manifests.js +14 -0
- package/src/fileServer/utils.js +35 -0
- package/src/schemas/index.js +20 -0
- package/src/schemas/schemasBase.js +47 -0
- package/src/schemas/schemasPresentation2.js +417 -0
- package/src/schemas/schemasPresentation3.js +57 -0
- package/src/schemas/schemasResolver.js +71 -0
- package/src/schemas/schemasRoutes.js +277 -0
- package/src/server.js +22 -0
- package/src/types.js +93 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* define the validation schema for collection `manifests2`.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import build from "#src/app.js"
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @param db {import('mongodb').Db}
|
|
9
|
+
* @param client {import('mongodb').MongoClient}
|
|
10
|
+
* @returns {Promise<void>}
|
|
11
|
+
*/
|
|
12
|
+
export const up = async (db, client) => {
|
|
13
|
+
const
|
|
14
|
+
fastify = await build(),
|
|
15
|
+
fastifySchema = fastify.schemasPresentation2.getSchema("manifestMongo"),
|
|
16
|
+
schema = fastify.schemasResolver(fastifySchema),
|
|
17
|
+
commandDoc = {
|
|
18
|
+
collMod: "manifests2",
|
|
19
|
+
validator: { $jsonSchema: schema },
|
|
20
|
+
},
|
|
21
|
+
r = await db.command(commandDoc);
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
if ( r.ok !== 1 ) {
|
|
25
|
+
throw new Error(`command failed with error: ${r}`);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @param db {import('mongodb').Db}
|
|
31
|
+
* @param client {import('mongodb').MongoClient}
|
|
32
|
+
* @returns {Promise<void>}
|
|
33
|
+
*/
|
|
34
|
+
export const down = async (db, client) => {
|
|
35
|
+
const r = await db.command({
|
|
36
|
+
collMod: "manifests2",
|
|
37
|
+
validator: {}
|
|
38
|
+
});
|
|
39
|
+
if ( r.ok !== 1 ) {
|
|
40
|
+
throw new Error(`command failed with error: ${r}`);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** create a unique index on `manifests2.@id` */
|
|
2
|
+
|
|
3
|
+
const
|
|
4
|
+
colName = "manifests2",
|
|
5
|
+
indexSpec = { "@id": 1 },
|
|
6
|
+
indexOptions = { name: "manifestIdIndex", unique: true };
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param {import('mongodb').Db} db
|
|
10
|
+
* @param {import('mongodb').MongoClient} client
|
|
11
|
+
* @returns {Promise<void>}
|
|
12
|
+
*/
|
|
13
|
+
export const up = async (db, client) => {
|
|
14
|
+
const collection = db.collection(colName);
|
|
15
|
+
const result = await collection.createIndex(indexSpec, indexOptions);
|
|
16
|
+
console.log("created index:", result);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param {import('mongodb').Db} db
|
|
21
|
+
* @param {import('mongodb').MongoClient} client
|
|
22
|
+
* @returns {Promise<void>}
|
|
23
|
+
*/
|
|
24
|
+
export const down = async (db, client) => {
|
|
25
|
+
const collection = db.collection(colName);
|
|
26
|
+
const result = await collection.dropIndex(indexOptions.name);
|
|
27
|
+
console.log("dropped index:", result);
|
|
28
|
+
};
|
|
29
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// template migration file generated by migrate-mongo
|
|
2
|
+
|
|
3
|
+
import {createIndex, removeIndex} from "../manageIndex.js";
|
|
4
|
+
|
|
5
|
+
const
|
|
6
|
+
colName = "annotations2",
|
|
7
|
+
indexSpec = { "@id": 1 },
|
|
8
|
+
indexOptions = { name: "annotationIdIndex" };
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @param {import('mongodb').Db} db
|
|
12
|
+
* @param {import('mongodb').MongoClient} client
|
|
13
|
+
* @returns {Promise<void>}
|
|
14
|
+
*/
|
|
15
|
+
export const up = async (db, client) => {
|
|
16
|
+
await createIndex(db, colName, indexSpec, indexOptions);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param {import('mongodb').Db} db
|
|
21
|
+
* @param {import('mongodb').MongoClient} client
|
|
22
|
+
* @returns {Promise<void>}
|
|
23
|
+
*/
|
|
24
|
+
export const down = async (db, client) => {
|
|
25
|
+
await removeIndex(db, colName, indexOptions);
|
|
26
|
+
};
|
|
27
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// template migration file generated by migrate-mongo
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param {import('mongodb').Db} db
|
|
5
|
+
* @param {import('mongodb').MongoClient} client
|
|
6
|
+
* @returns {Promise<void>}
|
|
7
|
+
*/
|
|
8
|
+
export const up = async (db, client) => {
|
|
9
|
+
// TODO write your migration here.
|
|
10
|
+
// See https://github.com/seppevs/migrate-mongo/#creating-a-new-migration-script
|
|
11
|
+
// Example:
|
|
12
|
+
// await db.collection('albums').updateOne({artist: 'The Beatles'}, {$set: {blacklisted: true}});
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param {import('mongodb').Db} db
|
|
17
|
+
* @param {import('mongodb').MongoClient} client
|
|
18
|
+
* @returns {Promise<void>}
|
|
19
|
+
*/
|
|
20
|
+
export const down = async (db, client) => {
|
|
21
|
+
// TODO write the statements to rollback your migration (if possible)
|
|
22
|
+
// Example:
|
|
23
|
+
// await db.collection('albums').updateOne({artist: 'The Beatles'}, {$set: {blacklisted: false}});
|
|
24
|
+
};
|
|
25
|
+
|
package/package.json
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "aiiinotate",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "a fast IIIF-compliant annotation server",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"directories": {
|
|
8
|
+
"doc": "docs"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"setup": "bash run.sh -s",
|
|
12
|
+
"start": "bash run.sh -d",
|
|
13
|
+
"prod": "bash run.sh -p",
|
|
14
|
+
"test": "bash run.sh -t",
|
|
15
|
+
"cli": "dotenvx run -f ./src/config/.env -- node ./cli/index.js",
|
|
16
|
+
"lint": "npx eslint --fix",
|
|
17
|
+
"migrate-make": "npm run cli -- migrate make",
|
|
18
|
+
"migrate-apply": "npm run cli migrate apply",
|
|
19
|
+
"migrate-revert": "npm run cli migrate revert",
|
|
20
|
+
"migrate-revert-all": "npm run cli migrate revert-all"
|
|
21
|
+
},
|
|
22
|
+
"pre-commit": [
|
|
23
|
+
"lint"
|
|
24
|
+
],
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "git+https://github.com/Aikon-platform/aiiinotate.git"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"annotation-server",
|
|
31
|
+
"iiif",
|
|
32
|
+
"annotation",
|
|
33
|
+
"international-image-interoperability-framework"
|
|
34
|
+
],
|
|
35
|
+
"author": "Aikon",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/Aikon-platform/aiiinotate/issues"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://github.com/Aikon-platform/aiiinotate#readme",
|
|
41
|
+
"imports": {
|
|
42
|
+
"#types": "./src/types.js",
|
|
43
|
+
"#cli/*.js": "./cli/*.js",
|
|
44
|
+
"#src/*.js": "./src/*.js",
|
|
45
|
+
"#migrations/*.js": "./migrations/*.js",
|
|
46
|
+
"#db/*.js": "./src/db/*.js",
|
|
47
|
+
"#schemas/*.js": "./src/schemas/*.js",
|
|
48
|
+
"#config/*.js": "./src/config/*.js",
|
|
49
|
+
"#data/*.js": "./src/data/*.js",
|
|
50
|
+
"#utils/*.js": "./src/data/utils/*.js",
|
|
51
|
+
"#fileServer/*.js": "./src/fileServer/*.js",
|
|
52
|
+
"#fileServer/*.json": "./src/fileServer/*.json",
|
|
53
|
+
"#manifests/*.js": "./src/data/manifests/*.js",
|
|
54
|
+
"#annotations/*.js": "./src/data/annotations/*.js"
|
|
55
|
+
},
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"@dotenvx/dotenvx": "^1.49.0",
|
|
58
|
+
"@fastify/ajv-compiler": "^4.0.2",
|
|
59
|
+
"@fastify/cors": "^11.1.0",
|
|
60
|
+
"@fastify/mongodb": "^9.0.2",
|
|
61
|
+
"@fastify/swagger": "^9.5.2",
|
|
62
|
+
"commander": "^14.0.0",
|
|
63
|
+
"fastify": "^5.5.0",
|
|
64
|
+
"migrate-mongo": "^12.1.3",
|
|
65
|
+
"mongodb": "^6.18.0",
|
|
66
|
+
"swagger-markdown": "^3.0.0",
|
|
67
|
+
"uuid": "^11.1.0"
|
|
68
|
+
},
|
|
69
|
+
"devDependencies": {
|
|
70
|
+
"@eslint/css": "^0.10.0",
|
|
71
|
+
"@eslint/js": "^9.33.0",
|
|
72
|
+
"@eslint/json": "^0.13.1",
|
|
73
|
+
"@stylistic/eslint-plugin": "^5.2.3",
|
|
74
|
+
"eslint": "^9.33.0",
|
|
75
|
+
"globals": "^16.3.0",
|
|
76
|
+
"pre-commit": "^1.2.2"
|
|
77
|
+
}
|
|
78
|
+
}
|
package/run.sh
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/bin/env bash
|
|
2
|
+
|
|
3
|
+
source "./scripts/utils.sh";
|
|
4
|
+
|
|
5
|
+
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
6
|
+
ENV_FILE="$SCRIPT_DIR/src/config/.env";
|
|
7
|
+
|
|
8
|
+
print_usage() {
|
|
9
|
+
cat<<EOF
|
|
10
|
+
|
|
11
|
+
USAGE bash run.sh [-s, -d, -p, -t, -c, -h]
|
|
12
|
+
|
|
13
|
+
(use from the scripts defined in 'package.json': 'npm start')
|
|
14
|
+
|
|
15
|
+
-s: setup the app
|
|
16
|
+
-t: test the app
|
|
17
|
+
-d: run the app in dev mode
|
|
18
|
+
-p: run the app in prod mode
|
|
19
|
+
-c: run the command line interface
|
|
20
|
+
-h: print help and exit
|
|
21
|
+
|
|
22
|
+
EOF
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
start () {
|
|
26
|
+
local mode="$1"
|
|
27
|
+
|
|
28
|
+
if [ ! -f "$ENV_FILE" ];
|
|
29
|
+
then echo -e "\nERROR: .env file not found at '$ENV_FILE'. exiting..." && exit 1;
|
|
30
|
+
fi;
|
|
31
|
+
|
|
32
|
+
start_mongod
|
|
33
|
+
|
|
34
|
+
if [ "$mode" = "setup" ]; then
|
|
35
|
+
dotenvx run -f "$ENV_FILE" -- \
|
|
36
|
+
node "$SCRIPT_DIR/scripts/setup.js";
|
|
37
|
+
elif [ "$mode" = "dev" ]; then
|
|
38
|
+
dotenvx run -f "$ENV_FILE" -- \
|
|
39
|
+
node --watch "$SCRIPT_DIR/src/server.js";
|
|
40
|
+
elif [ "$mode" = "test" ]; then
|
|
41
|
+
dotenvx run -f "$ENV_FILE" -- \
|
|
42
|
+
node --test --test-isolation=none;
|
|
43
|
+
elif [ "$mode" = "cli" ] ; then
|
|
44
|
+
dotenvx run -f "$ENV_FILE" -- \
|
|
45
|
+
node "$SCRIPT_DIR/cli/index.js";
|
|
46
|
+
else echo -e "\nERROR: mode not implemented: '$mode'\n"; print_usage; exit 1;
|
|
47
|
+
fi;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
while getopts 'hdptcs' mode_flag; do
|
|
51
|
+
case "${mode_flag}" in
|
|
52
|
+
s) MODE="setup"
|
|
53
|
+
break;;
|
|
54
|
+
d) MODE="dev"
|
|
55
|
+
break;;
|
|
56
|
+
p) MODE="prod"
|
|
57
|
+
break;;
|
|
58
|
+
t) MODE="test"
|
|
59
|
+
break;;
|
|
60
|
+
c) MODE="cli"
|
|
61
|
+
break;;
|
|
62
|
+
h) print_usage
|
|
63
|
+
exit 0;;
|
|
64
|
+
*) print_usage
|
|
65
|
+
exit 1;;
|
|
66
|
+
esac
|
|
67
|
+
done
|
|
68
|
+
|
|
69
|
+
start "$MODE";
|
|
70
|
+
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/bin/env bash
|
|
2
|
+
|
|
3
|
+
# use through package.json scripts.
|
|
4
|
+
|
|
5
|
+
# these sripts are used to manage all migrations in parallel
|
|
6
|
+
# on both the main database and the test database.
|
|
7
|
+
#NOTE migrate-init is not implemented.
|
|
8
|
+
|
|
9
|
+
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
10
|
+
|
|
11
|
+
source "$SCRIPT_DIR/utils.sh" || exit 1;
|
|
12
|
+
|
|
13
|
+
MIGRATIONS_CONFIG_MAIN="$MIGRATIONS_DIR/migrate-mongo-config-main.js";
|
|
14
|
+
MIGRATIONS_CONFIG_TEST="$MIGRATIONS_DIR/migrate-mongo-config-test.js";
|
|
15
|
+
MIGRATIONS_CONFIGS=("$MIGRATIONS_CONFIG_MAIN" "$MIGRATIONS_CONFIG_TEST");
|
|
16
|
+
|
|
17
|
+
##################################################
|
|
18
|
+
# functions
|
|
19
|
+
|
|
20
|
+
# create a migration
|
|
21
|
+
# NOTE `migrate-mongo create` generates a timestamped file and, since this script is run twice
|
|
22
|
+
# (once per config file), 2 migration files are created. so what we do is mimic migrate-make by
|
|
23
|
+
# copying a blank template file to the `migrationScripts` directory.
|
|
24
|
+
migrate_make() {
|
|
25
|
+
config_fp=$1; # path to config file
|
|
26
|
+
migration_name="$2"; # name of migration to create
|
|
27
|
+
|
|
28
|
+
if [ -z "$migration_name" ];
|
|
29
|
+
then echo "ERROR. a migration name must be given."; exit 1;
|
|
30
|
+
fi;
|
|
31
|
+
|
|
32
|
+
cp "$MIGRATIONS_DIR/migrationTemplate.js" "$MIGRATIONS_DIR/migrationScripts/$(date +'%Y%m%d%H%M%S')-$migration_name.js";
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
# apply migrations
|
|
36
|
+
migrate_apply() {
|
|
37
|
+
config_fp=$1; # path to config file
|
|
38
|
+
dotenvx run -f "$ENV_FILE" -- npx migrate-mongo up -f "$config_fp";
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
# rvert the last migration
|
|
42
|
+
migrate_revert() {
|
|
43
|
+
config_fp=$1; # path to config file
|
|
44
|
+
dotenvx run -f "$ENV_FILE" -- npx migrate-mongo down -f "$config_fp";
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
# undo all migrations
|
|
48
|
+
migrate_revert_all() {
|
|
49
|
+
config_fp=$1; # path to config file
|
|
50
|
+
|
|
51
|
+
for _ in "$MIGRATIONS_DIR"/migrationScripts/*;
|
|
52
|
+
do dotenvx run -f "$ENV_FILE" -- npx migrate-mongo down -f "$config_fp";
|
|
53
|
+
done;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
##################################################
|
|
58
|
+
# cli
|
|
59
|
+
|
|
60
|
+
OP=$1
|
|
61
|
+
MIGRATION_NAME=$2 # only used by `migrate_make`
|
|
62
|
+
|
|
63
|
+
case "$OP" in
|
|
64
|
+
make) FUNC=migrate_make;;
|
|
65
|
+
apply) FUNC=migrate_apply;;
|
|
66
|
+
revert) FUNC=migrate_revert;;
|
|
67
|
+
revertAll) FUNC=migrate_revert_all;;
|
|
68
|
+
esac;
|
|
69
|
+
|
|
70
|
+
if [ -z "$FUNC" ];
|
|
71
|
+
then echo "ERROR: unrecognized keyword '$OP'. please use one of 'make', 'apply', 'revert', 'revertAll'. exiting..."; exit 1;
|
|
72
|
+
fi;
|
|
73
|
+
|
|
74
|
+
start_mongod
|
|
75
|
+
|
|
76
|
+
for config_fp in "${MIGRATIONS_CONFIGS[@]}"; do
|
|
77
|
+
$FUNC "$config_fp" "$MIGRATION_NAME";
|
|
78
|
+
done
|
|
79
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!usr/bin/env node
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { execSync } from "node:child_process";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
|
|
6
|
+
import { MongoClient } from "mongodb";
|
|
7
|
+
|
|
8
|
+
const
|
|
9
|
+
// path to dirctory of curent file
|
|
10
|
+
dirScripts = path.dirname(fileURLToPath(import.meta.url)),
|
|
11
|
+
dirRoot = path.resolve(dirScripts, ".."),
|
|
12
|
+
dirMigrations = path.resolve(dirRoot, "migrations");
|
|
13
|
+
|
|
14
|
+
const connString = process.env.MONGODB_CONNSTRING;
|
|
15
|
+
|
|
16
|
+
(async () => {
|
|
17
|
+
let client;
|
|
18
|
+
try {
|
|
19
|
+
client = new MongoClient(connString);
|
|
20
|
+
await client.connect();
|
|
21
|
+
console.log("CONNECTED !")
|
|
22
|
+
console.log(dirScripts);
|
|
23
|
+
console.log(dirRoot);
|
|
24
|
+
console.log(dirMigrations);
|
|
25
|
+
} finally {
|
|
26
|
+
if ( client != null ) {
|
|
27
|
+
client.close()
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
)();
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/bin/env bash
|
|
2
|
+
|
|
3
|
+
# mongo install guide: https://www.mongodb.com/docs/manual/tutorial/install-mongodb-on-ubuntu/#std-label-install-mdb-community-ubuntu
|
|
4
|
+
|
|
5
|
+
#NOTE only the mongodb installation is done here. for database creation, see `setup_mongodb_populate.sh`
|
|
6
|
+
|
|
7
|
+
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
8
|
+
source "$SCRIPT_DIR/utils.sh";
|
|
9
|
+
|
|
10
|
+
install_mongodb_ubuntu () {
|
|
11
|
+
|
|
12
|
+
sudo apt-get install gnupg curl
|
|
13
|
+
|
|
14
|
+
curl -fsSL https://www.mongodb.org/static/pgp/server-8.0.asc | \
|
|
15
|
+
sudo gpg -o /usr/share/keyrings/mongodb-server-8.0.gpg \
|
|
16
|
+
--dearmor
|
|
17
|
+
|
|
18
|
+
# assert we have an 86 64 architecture
|
|
19
|
+
if [ "$(arch)" != "x86_64" ];
|
|
20
|
+
then echo "MongoDB only supports x86_64 architectures (yours is $(arch)). exiting..."; exit 1
|
|
21
|
+
fi;
|
|
22
|
+
|
|
23
|
+
# fetch the release name. Mongo only supports LTS versions, so if the user's Ubuntu version is not LTS, we get the name of the last LTS released before the user's version.
|
|
24
|
+
source "/etc/lsb-release"
|
|
25
|
+
if float_comparison "$DISTRIB_RELEASE >= 24.04";
|
|
26
|
+
then DISTRIB="noble";
|
|
27
|
+
elif float_comparison "$DISTRIB_RELEASE >= 22.04";
|
|
28
|
+
then DISTRIB="jammy";
|
|
29
|
+
elif float_comparison "$DISTRIB_RELEASE >= 20.04";
|
|
30
|
+
then DISTRIB="focal";
|
|
31
|
+
else echo "Your Ubuntu version ($DISTRIB_RELEASE) is not supported by MongoDB 8.0"; exit 1;
|
|
32
|
+
fi;
|
|
33
|
+
|
|
34
|
+
# create list file
|
|
35
|
+
echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-8.0.gpg ] https://repo.mongodb.org/apt/ubuntu $DISTRIB/mongodb-org/8.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-8.0.list
|
|
36
|
+
|
|
37
|
+
sudo apt-get update
|
|
38
|
+
|
|
39
|
+
sudo apt-get install -y mongodb-org
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
install_mongodb_mac () {
|
|
43
|
+
xcode-select --install;
|
|
44
|
+
brew tap mongodb/brew;
|
|
45
|
+
brew update;
|
|
46
|
+
brew install mongodb-community@8.0;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if ! command -v mongod ; then
|
|
50
|
+
echo_title "INSTALL MONGODB"
|
|
51
|
+
|
|
52
|
+
if [ "$OS" = "Linux" ]; then
|
|
53
|
+
install_mongodb_ubuntu;
|
|
54
|
+
sudo systemctl start mongod;
|
|
55
|
+
elif [ "$OS" = "Mac" ]; then
|
|
56
|
+
install_mongodb_mac;
|
|
57
|
+
brew services start mongodb-community@8.0;
|
|
58
|
+
else echo "Unsupported OS: $OS"; exit 1;
|
|
59
|
+
fi;
|
|
60
|
+
|
|
61
|
+
fi;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/bin/env bash
|
|
2
|
+
|
|
3
|
+
#NOTE : this setup creates and populates our db WITHOUT users or authentication.
|
|
4
|
+
# it is possible to add users and auth to a mongodb instance, but
|
|
5
|
+
# - it is a bit convoluted in itself
|
|
6
|
+
# - it is difficult to automate: we would need to
|
|
7
|
+
# - create a root user + a user for the app
|
|
8
|
+
# - create this app user by generating mongosh scripts from the user's .env files (so use Python to write custom JS)
|
|
9
|
+
# - update the mongodb conf file so that the systemd mongodb service uses auth login, which would need to parse YAML, so to use python
|
|
10
|
+
|
|
11
|
+
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
12
|
+
ROOT_DIR="$SCRIPT_DIR/../"
|
|
13
|
+
|
|
14
|
+
cd "$ROOT_DIR"
|
|
15
|
+
|
|
16
|
+
npm run migrate-apply
|
|
17
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/bin/env bash
|
|
2
|
+
|
|
3
|
+
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
4
|
+
source "$SCRIPT_DIR/utils.sh";
|
|
5
|
+
|
|
6
|
+
if ! command -v npm &> /dev/null; then
|
|
7
|
+
echo_title "INSTALL NVM & NODE";
|
|
8
|
+
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash
|
|
9
|
+
nvm install node
|
|
10
|
+
npm install -g webpack webpack-cli
|
|
11
|
+
fi
|
|
12
|
+
|
|
13
|
+
echo_title "SETUP FASTIFY APP";
|
|
14
|
+
cd "$ROOT_DIR";
|
|
15
|
+
npm i;
|
package/scripts/utils.sh
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
#!/bin/env bash
|
|
2
|
+
|
|
3
|
+
# directory of the current script
|
|
4
|
+
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
5
|
+
# root of the app
|
|
6
|
+
ROOT_DIR=$( dirname "$SCRIPT_DIR" )
|
|
7
|
+
# src/ directory
|
|
8
|
+
SRC_DIR="$ROOT_DIR/src"
|
|
9
|
+
# migrations/ dir
|
|
10
|
+
MIGRATIONS_DIR="$ROOT_DIR/migrations";
|
|
11
|
+
# .env file
|
|
12
|
+
ENV_FILE="$SRC_DIR/config/.env"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
color_echo() {
|
|
16
|
+
Color_Off="\033[0m"
|
|
17
|
+
Red="\033[1;91m" # Red
|
|
18
|
+
Green="\033[1;92m" # Green
|
|
19
|
+
Yellow="\033[1;93m" # Yellow
|
|
20
|
+
Blue="\033[1;94m" # Blue
|
|
21
|
+
Purple="\033[1;95m" # Purple
|
|
22
|
+
Cyan="\033[1;96m" # Cyan
|
|
23
|
+
|
|
24
|
+
case "$1" in
|
|
25
|
+
"green") echo -e "$Green$2$Color_Off";;
|
|
26
|
+
"red") echo -e "$Red$2$Color_Off";;
|
|
27
|
+
"blue") echo -e "$Blue$2$Color_Off";;
|
|
28
|
+
"yellow") echo -e "$Yellow$2$Color_Off";;
|
|
29
|
+
"purple") echo -e "$Purple$2$Color_Off";;
|
|
30
|
+
"cyan") echo -e "$Cyan$2$Color_Off";;
|
|
31
|
+
*) echo "$2";;
|
|
32
|
+
esac
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
echo_title(){
|
|
36
|
+
sep_line="========================================"
|
|
37
|
+
len_title=${#1}
|
|
38
|
+
|
|
39
|
+
if [ "$len_title" -gt 40 ]; then
|
|
40
|
+
sep_line=$(printf "%0.s=" $(seq 1 $len_title))
|
|
41
|
+
title="$1"
|
|
42
|
+
else
|
|
43
|
+
diff=$((38 - len_title))
|
|
44
|
+
half_diff=$((diff / 2))
|
|
45
|
+
sep=$(printf "%0.s=" $(seq 1 $half_diff))
|
|
46
|
+
|
|
47
|
+
if [ $((diff % 2)) -ne 0 ]; then
|
|
48
|
+
title="$sep $1 $sep="
|
|
49
|
+
else
|
|
50
|
+
title="$sep $1 $sep"
|
|
51
|
+
fi
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
color_echo purple "\n\n$sep_line\n$title\n$sep_line"
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
get_os() {
|
|
58
|
+
unameOut="$(uname -s)"
|
|
59
|
+
case "${unameOut}" in
|
|
60
|
+
Linux*) os=Linux;;
|
|
61
|
+
Darwin*) os=Mac;;
|
|
62
|
+
CYGWIN*) os=Cygwin;;
|
|
63
|
+
MINGW*) os=MinGw;;
|
|
64
|
+
MSYS_NT*) os=Git;;
|
|
65
|
+
*) os="UNKNOWN:${unameOut}"
|
|
66
|
+
esac
|
|
67
|
+
echo "${os}"
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export OS
|
|
71
|
+
OS=$(get_os)
|
|
72
|
+
|
|
73
|
+
# gets a password and validates it by running a dummy cmd.
|
|
74
|
+
# parent process must call the function with `get_password || exit` to exit the script if `SUDO_PSW` is invalid
|
|
75
|
+
get_password() {
|
|
76
|
+
if [ -z "$SUDO_PSW" ]; then
|
|
77
|
+
read -s -p "Enter your sudo password: " SUDO_PSW
|
|
78
|
+
echo
|
|
79
|
+
echo "$SUDO_PSW" | sudo -S whoami > /dev/null 2>&1
|
|
80
|
+
if [ $? -ne 0 ]; then
|
|
81
|
+
echo "Invalid sudo password. Exiting..."
|
|
82
|
+
return 1
|
|
83
|
+
fi
|
|
84
|
+
return 0
|
|
85
|
+
fi
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
# the sed at the end removes trailing non-alphanumeric chars.
|
|
89
|
+
generate_random_string() {
|
|
90
|
+
echo "$(openssl rand -base64 32 | tr -d '/\n' | sed -r -e "s/[^a-zA-Z0-9]+$//")"
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
get_env_value() {
|
|
94
|
+
param=$1
|
|
95
|
+
env_file=$2
|
|
96
|
+
value=$(awk -F= -v param="$param" '/^[^#]/ && $1 == param {gsub(/"/, "", $2); print $2}' "$env_file")
|
|
97
|
+
echo "$value"
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
get_env_desc() {
|
|
101
|
+
current_line="$1"
|
|
102
|
+
prev_line="$2"
|
|
103
|
+
desc=""
|
|
104
|
+
if [[ $prev_line =~ ^# ]]; then
|
|
105
|
+
desc=$(echo "$prev_line" | sed 's/^#\s*//')
|
|
106
|
+
fi
|
|
107
|
+
echo "$desc"
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
ask() {
|
|
111
|
+
options=("yes" "no")
|
|
112
|
+
color_echo blue "$1"
|
|
113
|
+
answer=$(printf "%s\n" "${options[@]}" | fzy)
|
|
114
|
+
echo ""
|
|
115
|
+
if [ "$answer" = "no" ]; then
|
|
116
|
+
exit 1
|
|
117
|
+
fi
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
# float arithmetic comparison is not supported by bash and we need to use `bc`
|
|
121
|
+
# usage: if float_comparison "a >= b"; then... ; fi
|
|
122
|
+
float_comparison () {
|
|
123
|
+
expr="$1"
|
|
124
|
+
(( $(echo "$expr" |bc -l) ));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
# sed replacements in place
|
|
128
|
+
# `sed -i` can't be used in the same way with Linux and Mac: it's `sed -i` on Linux, `sed -i ""` on Mac
|
|
129
|
+
sed_repl_inplace() {
|
|
130
|
+
sed_expr="$1"
|
|
131
|
+
file="$2"
|
|
132
|
+
|
|
133
|
+
if [ "$OS" = "Linux" ]; then
|
|
134
|
+
sed -i -e "$sed_expr" "$file"
|
|
135
|
+
else
|
|
136
|
+
sed -i "" -e "$sed_expr" "$file"
|
|
137
|
+
fi
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
# sudo does not inherit from bash functions so this is a copy of "sed_repl_inplace" with sudo privileges (see: https://stackoverflow.com/a/9448969)
|
|
141
|
+
sudo_sed_repl_inplace() {
|
|
142
|
+
sed_expr="$1"
|
|
143
|
+
file="$2"
|
|
144
|
+
|
|
145
|
+
if [ "$OS" = "Linux" ]; then
|
|
146
|
+
[ -n "$SUDO_PSW" ] && echo "$SUDO_PSW" | sudo -S sed -i -e "$sed_expr" "$file" || sudo sed -i -e "$sed_expr" "$file"
|
|
147
|
+
else
|
|
148
|
+
[ -n "$SUDO_PSW" ] && echo "$SUDO_PSW" | sudo -S sed -i "" -e "$sed_expr" "$file" || sudo sed -i "" -e "$sed_expr" "$file"
|
|
149
|
+
fi
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
# ed replacements to a new file
|
|
153
|
+
sed_repl_newfile() {
|
|
154
|
+
sed_expr="$1"
|
|
155
|
+
infile="$2"
|
|
156
|
+
outfile="$3"
|
|
157
|
+
|
|
158
|
+
sed "$sed_expr" "$infile" | tee "$outfile" > /dev/null
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
sudo_sed_repl_newfile() {
|
|
162
|
+
sed_expr="$1"
|
|
163
|
+
infile="$2"
|
|
164
|
+
outfile="$3"
|
|
165
|
+
|
|
166
|
+
sudo sed "$sed_expr" "$infile" | sudo tee "$outfile" > /dev/null
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
run_script() {
|
|
170
|
+
local script_name="$1"
|
|
171
|
+
local description="$2"
|
|
172
|
+
local SCRIPT_DIR=${3:-${SCRIPT_DIR}}
|
|
173
|
+
options=("yes" "no")
|
|
174
|
+
|
|
175
|
+
color_echo blue "Do you want to run $description?"
|
|
176
|
+
answer=$(printf "%s\n" "${options[@]}" | fzy)
|
|
177
|
+
echo ""
|
|
178
|
+
if [ "$answer" = "yes" ]; then
|
|
179
|
+
bash "$SCRIPT_DIR/$script_name" \
|
|
180
|
+
&& color_echo green "$description completed successfully" \
|
|
181
|
+
|| color_echo red "$description failed with exit code. Continuing..."
|
|
182
|
+
else
|
|
183
|
+
color_echo cyan "Skipping $description"
|
|
184
|
+
fi
|
|
185
|
+
echo ""
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
start_mongod() {
|
|
189
|
+
if ! systemctl is-active --quiet mongod;
|
|
190
|
+
then sudo systemctl start mongod;
|
|
191
|
+
fi;
|
|
192
|
+
}
|