@socialgouv/matomo-postgres 2.1.0 → 2.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/dist/index.js CHANGED
@@ -12,55 +12,89 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
+ const eachDayOfInterval_1 = __importDefault(require("date-fns/eachDayOfInterval"));
16
+ const debug_1 = __importDefault(require("debug"));
15
17
  const kysely_1 = require("kysely");
16
18
  const p_all_1 = __importDefault(require("p-all"));
17
- const debug_1 = __importDefault(require("debug"));
18
- const eachDayOfInterval_1 = __importDefault(require("date-fns/eachDayOfInterval"));
19
- const PiwikClient_1 = __importDefault(require("./PiwikClient"));
20
- const db_1 = require("./db");
21
19
  const config_1 = require("./config");
20
+ const db_1 = require("./db");
22
21
  const importDate_1 = require("./importDate");
23
- const debug = (0, debug_1.default)("index");
22
+ const PiwikClient_1 = __importDefault(require("./PiwikClient"));
23
+ const debug = (0, debug_1.default)('index');
24
24
  function run(date) {
25
25
  return __awaiter(this, void 0, void 0, function* () {
26
- debug("run, date=" + date);
26
+ console.log(`🚀 Starting data import process`);
27
+ debug('run, date=' + date);
28
+ console.log(`🔗 Initializing Matomo client`);
29
+ console.log(` - Matomo URL: ${config_1.MATOMO_URL}`);
30
+ console.log(` - Matomo Site ID: ${config_1.MATOMO_SITE}`);
27
31
  const piwik = new PiwikClient_1.default(config_1.MATOMO_URL, config_1.MATOMO_KEY);
32
+ console.log(`📅 Determining reference date for import...`);
28
33
  // priority:
29
34
  // - optional parameter date
30
35
  // - last event in the table
31
36
  // - optional env.STARTDATE
32
37
  // - today
33
38
  let referenceDate;
34
- if (!referenceDate && date)
39
+ if (!referenceDate && date) {
35
40
  referenceDate = new Date(date);
36
- if (!referenceDate)
37
- referenceDate = yield findLastEventInMatomo(db_1.db);
38
- if (!referenceDate && process.env.STARTDATE)
41
+ console.log(`✅ Using provided date parameter: ${referenceDate.toISOString()}`);
42
+ }
43
+ if (!referenceDate && process.env.STARTDATE) {
39
44
  referenceDate = new Date(process.env.STARTDATE);
40
- if (!referenceDate)
45
+ console.log(`✅ Using STARTDATE environment variable: ${referenceDate.toISOString()}`);
46
+ }
47
+ if (!referenceDate) {
48
+ console.log(`🔍 Looking for last event in database...`);
49
+ referenceDate = yield findLastEventInMatomo(db_1.db);
50
+ if (referenceDate) {
51
+ console.log(`✅ Found last event, starting from: ${referenceDate.toISOString()}`);
52
+ }
53
+ else {
54
+ console.log(`â„šī¸ No previous events found in database`);
55
+ }
56
+ }
57
+ if (!referenceDate) {
41
58
  referenceDate = new Date(new Date().getTime() - +config_1.INITIAL_OFFSET * 24 * 60 * 60 * 1000);
59
+ console.log(`✅ Using default offset (${config_1.INITIAL_OFFSET} days ago): ${referenceDate.toISOString()}`);
60
+ }
61
+ const endDate = new Date(new Date().getTime() + 24 * 60 * 60 * 1000);
42
62
  const dates = (0, eachDayOfInterval_1.default)({
43
63
  start: referenceDate,
44
- end: new Date(new Date().getTime() + 24 * 60 * 60 * 1000),
64
+ end: endDate
45
65
  });
66
+ console.log(`📊 Import date range determined:`);
67
+ console.log(` - Start date: ${dates[0].toISOString()}`);
68
+ console.log(` - End date: ${endDate.toISOString()}`);
69
+ console.log(` - Total days to process: ${dates.length}`);
46
70
  debug(`import starting at : ${dates[0].toISOString()}`);
71
+ console.log(`🔄 Starting sequential import for each date...`);
47
72
  // for each date, serial-import data
48
- const res = yield (0, p_all_1.default)(dates.map((date) => () => (0, importDate_1.importDate)(piwik.api.bind(piwik), date)), { concurrency: 1, stopOnError: true });
49
- debug("close");
73
+ const res = yield (0, p_all_1.default)(dates.map((date, index) => () => {
74
+ console.log(`📅 Processing date ${index + 1}/${dates.length}: ${date.toISOString().split('T')[0]}`);
75
+ return (0, importDate_1.importDate)(piwik.api.bind(piwik), date);
76
+ }), { concurrency: 1, stopOnError: true });
77
+ const totalEvents = res.flat().length;
78
+ console.log(`✅ Import process completed`);
79
+ console.log(`📈 Summary:`);
80
+ console.log(` - Days processed: ${dates.length}`);
81
+ console.log(` - Total events imported: ${totalEvents}`);
82
+ debug('close');
50
83
  return res;
51
84
  });
52
85
  }
53
86
  exports.default = run;
54
87
  if (require.main === module) {
88
+ ;
55
89
  (() => __awaiter(void 0, void 0, void 0, function* () {
56
90
  if (!config_1.MATOMO_SITE)
57
- return console.error("Missing env MATOMO_SITE");
91
+ return console.error('Missing env MATOMO_SITE');
58
92
  if (!config_1.MATOMO_KEY)
59
- return console.error("Missing env MATOMO_KEY");
93
+ return console.error('Missing env MATOMO_KEY');
60
94
  if (!config_1.PGDATABASE)
61
- return console.error("Missing env PGDATABASE");
95
+ return console.error('Missing env PGDATABASE');
62
96
  yield run();
63
- debug("run finished");
97
+ debug('run finished');
64
98
  db_1.db.destroy();
65
99
  }))();
66
100
  }
@@ -68,12 +102,12 @@ function findLastEventInMatomo(db) {
68
102
  return __awaiter(this, void 0, void 0, function* () {
69
103
  const latest = yield db
70
104
  .selectFrom(config_1.DESTINATION_TABLE)
71
- .select((0, kysely_1.sql) `action_timestamp at time zone 'UTC'`.as("action_timestamp"))
72
- .orderBy("action_timestamp", "desc")
105
+ .select((0, kysely_1.sql) `action_timestamp at time zone 'UTC'`.as('action_timestamp'))
106
+ .orderBy('action_timestamp', 'desc')
73
107
  .limit(1)
74
108
  .executeTakeFirst();
75
109
  if (latest) {
76
- // check from the day before just to be sure we haev all events
110
+ // check from the day before just to be sure we have all events
77
111
  const date = new Date(new Date(latest.action_timestamp).getTime() - 2 * 24 * 60 * 60 * 1000);
78
112
  return date;
79
113
  }
@@ -32,9 +32,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
32
32
  });
33
33
  };
34
34
  Object.defineProperty(exports, "__esModule", { value: true });
35
- const path = __importStar(require("path"));
36
35
  const fs_1 = require("fs");
37
36
  const kysely_1 = require("kysely");
37
+ const path = __importStar(require("path"));
38
38
  const db_1 = require("./db");
39
39
  function migrateDown() {
40
40
  return __awaiter(this, void 0, void 0, function* () {
@@ -43,20 +43,20 @@ function migrateDown() {
43
43
  provider: new kysely_1.FileMigrationProvider({
44
44
  fs: fs_1.promises,
45
45
  path,
46
- migrationFolder: __dirname + "/migrations",
47
- }),
46
+ migrationFolder: __dirname + '/migrations'
47
+ })
48
48
  });
49
49
  const { error, results } = yield migrator.migrateDown();
50
50
  results === null || results === void 0 ? void 0 : results.forEach((it) => {
51
- if (it.status === "Success") {
51
+ if (it.status === 'Success') {
52
52
  console.log(`down migration "${it.migrationName}" was executed successfully`);
53
53
  }
54
- else if (it.status === "Error") {
54
+ else if (it.status === 'Error') {
55
55
  console.error(`failed to execute down migration "${it.migrationName}"`);
56
56
  }
57
57
  });
58
58
  if (error) {
59
- console.error("failed to down migrate");
59
+ console.error('failed to down migrate');
60
60
  console.error(error);
61
61
  process.exit(1);
62
62
  }
@@ -32,11 +32,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
32
32
  });
33
33
  };
34
34
  Object.defineProperty(exports, "__esModule", { value: true });
35
- const path = __importStar(require("path"));
36
35
  const fs_1 = require("fs");
37
36
  const kysely_1 = require("kysely");
38
- const db_1 = require("./db");
37
+ const path = __importStar(require("path"));
39
38
  const config_1 = require("./config");
39
+ const db_1 = require("./db");
40
40
  function migrateToLatest() {
41
41
  return __awaiter(this, void 0, void 0, function* () {
42
42
  const migrator = new kysely_1.Migrator({
@@ -44,29 +44,29 @@ function migrateToLatest() {
44
44
  provider: new kysely_1.FileMigrationProvider({
45
45
  fs: fs_1.promises,
46
46
  path,
47
- migrationFolder: __dirname + "/migrations",
47
+ migrationFolder: __dirname + '/migrations'
48
48
  }),
49
49
  // allow to have mutliple migratable instances in a single schema
50
- migrationTableName: `${config_1.DESTINATION_TABLE}_migration`,
51
- migrationLockTableName: `${config_1.DESTINATION_TABLE}_migration_lock`,
50
+ migrationTableName: `${config_1.MATOMO_TABLE_NAME}_migration`,
51
+ migrationLockTableName: `${config_1.MATOMO_TABLE_NAME}_migration_lock`
52
52
  });
53
53
  const { error, results } = yield migrator.migrateToLatest();
54
54
  results === null || results === void 0 ? void 0 : results.forEach((it) => {
55
- if (it.status === "Success") {
55
+ if (it.status === 'Success') {
56
56
  console.log(`migration "${it.migrationName}" was executed successfully`);
57
57
  }
58
- else if (it.status === "Error") {
58
+ else if (it.status === 'Error') {
59
59
  console.error(`failed to execute migration "${it.migrationName}"`);
60
60
  }
61
61
  });
62
62
  if (error) {
63
- console.error("failed to migrate");
63
+ console.error('failed to migrate');
64
64
  console.error(error);
65
65
  process.exit(1);
66
66
  }
67
67
  else {
68
68
  if (!(results === null || results === void 0 ? void 0 : results.length)) {
69
- console.log("No migration to run");
69
+ console.log('No migration to run');
70
70
  }
71
71
  }
72
72
  });
@@ -11,60 +11,60 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.down = exports.up = void 0;
13
13
  const kysely_1 = require("kysely");
14
- const DESTINATION_TABLE = process.env.DESTINATION_TABLE || "matomo";
14
+ const MATOMO_TABLE_NAME = process.env.MATOMO_TABLE_NAME || 'matomo';
15
15
  function up(db) {
16
16
  return __awaiter(this, void 0, void 0, function* () {
17
17
  yield db.schema
18
- .createTable(DESTINATION_TABLE)
18
+ .createTable(MATOMO_TABLE_NAME)
19
19
  .ifNotExists()
20
- .addColumn("action_id", "text", (col) => col.unique().notNull())
21
- .addColumn("idsite", "text")
22
- .addColumn("idvisit", "text")
23
- .addColumn("actions", "text")
24
- .addColumn("country", "text")
25
- .addColumn("region", "text")
26
- .addColumn("city", "text")
27
- .addColumn("operatingsystemname", "text")
28
- .addColumn("devicemodel", "text")
29
- .addColumn("devicebrand", "text")
30
- .addColumn("visitduration", "text")
31
- .addColumn("dayssincefirstvisit", "text")
32
- .addColumn("visitortype", "text")
33
- .addColumn("sitename", "text")
34
- .addColumn("userid", "text")
35
- .addColumn("serverdateprettyfirstaction", "date")
36
- .addColumn("action_type", "text")
37
- .addColumn("action_eventcategory", "text")
38
- .addColumn("action_eventaction", "text")
39
- .addColumn("action_eventname", "text")
40
- .addColumn("action_eventvalue", "numeric")
41
- .addColumn("action_timespent", "text")
42
- .addColumn("action_timestamp", "timestamptz", (col) => col.defaultTo((0, kysely_1.sql) `now()`))
43
- .addColumn("usercustomproperties", "json")
44
- .addColumn("usercustomdimensions", "json")
45
- .addColumn("dimension1", "text")
46
- .addColumn("dimension2", "text")
47
- .addColumn("dimension3", "text")
48
- .addColumn("dimension4", "text")
49
- .addColumn("dimension5", "text")
50
- .addColumn("dimension6", "text")
51
- .addColumn("dimension7", "text")
52
- .addColumn("dimension8", "text")
53
- .addColumn("dimension9", "text")
54
- .addColumn("dimension10", "text")
55
- .addColumn("action_url", "text")
56
- .addColumn("sitesearchkeyword", "text")
57
- .addColumn("action_title", "text")
58
- .addColumn("visitorid", "text")
59
- .addColumn("referrertype", "text")
60
- .addColumn("referrername", "text")
20
+ .addColumn('action_id', 'text', (col) => col.unique().notNull())
21
+ .addColumn('idsite', 'text')
22
+ .addColumn('idvisit', 'text')
23
+ .addColumn('actions', 'text')
24
+ .addColumn('country', 'text')
25
+ .addColumn('region', 'text')
26
+ .addColumn('city', 'text')
27
+ .addColumn('operatingsystemname', 'text')
28
+ .addColumn('devicemodel', 'text')
29
+ .addColumn('devicebrand', 'text')
30
+ .addColumn('visitduration', 'text')
31
+ .addColumn('dayssincefirstvisit', 'text')
32
+ .addColumn('visitortype', 'text')
33
+ .addColumn('sitename', 'text')
34
+ .addColumn('userid', 'text')
35
+ .addColumn('serverdateprettyfirstaction', 'date')
36
+ .addColumn('action_type', 'text')
37
+ .addColumn('action_eventcategory', 'text')
38
+ .addColumn('action_eventaction', 'text')
39
+ .addColumn('action_eventname', 'text')
40
+ .addColumn('action_eventvalue', 'numeric')
41
+ .addColumn('action_timespent', 'text')
42
+ .addColumn('action_timestamp', 'timestamptz', (col) => col.defaultTo((0, kysely_1.sql) `now()`))
43
+ .addColumn('usercustomproperties', 'json')
44
+ .addColumn('usercustomdimensions', 'json')
45
+ .addColumn('dimension1', 'text')
46
+ .addColumn('dimension2', 'text')
47
+ .addColumn('dimension3', 'text')
48
+ .addColumn('dimension4', 'text')
49
+ .addColumn('dimension5', 'text')
50
+ .addColumn('dimension6', 'text')
51
+ .addColumn('dimension7', 'text')
52
+ .addColumn('dimension8', 'text')
53
+ .addColumn('dimension9', 'text')
54
+ .addColumn('dimension10', 'text')
55
+ .addColumn('action_url', 'text')
56
+ .addColumn('sitesearchkeyword', 'text')
57
+ .addColumn('action_title', 'text')
58
+ .addColumn('visitorid', 'text')
59
+ .addColumn('referrertype', 'text')
60
+ .addColumn('referrername', 'text')
61
61
  .execute();
62
62
  });
63
63
  }
64
64
  exports.up = up;
65
65
  function down(db) {
66
66
  return __awaiter(this, void 0, void 0, function* () {
67
- yield db.schema.dropTable(DESTINATION_TABLE).execute();
67
+ yield db.schema.dropTable(MATOMO_TABLE_NAME).execute();
68
68
  });
69
69
  }
70
70
  exports.down = down;
@@ -11,68 +11,68 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.down = exports.up = void 0;
13
13
  const kysely_1 = require("kysely");
14
- const DESTINATION_TABLE = process.env.DESTINATION_TABLE || "matomo";
14
+ const MATOMO_TABLE_NAME = process.env.MATOMO_TABLE_NAME || 'matomo';
15
15
  const indexes = [
16
16
  {
17
- name: "idx_action_eventaction_matomo",
18
- columns: ["action_eventaction"],
17
+ name: 'idx_action_eventaction_matomo',
18
+ columns: ['action_eventaction']
19
19
  },
20
20
  {
21
- name: "idx_action_eventcategory_matomo",
22
- columns: ["action_eventcategory"],
21
+ name: 'idx_action_eventcategory_matomo',
22
+ columns: ['action_eventcategory']
23
23
  },
24
24
  {
25
- name: "idx_action_id",
26
- columns: ["action_id"],
25
+ name: 'idx_action_id',
26
+ columns: ['action_id']
27
27
  },
28
28
  {
29
- name: "idx_action_timestamp_matomo",
30
- columns: ["action_timestamp"],
29
+ name: 'idx_action_timestamp_matomo',
30
+ columns: ['action_timestamp']
31
31
  },
32
32
  {
33
- name: "idx_action_type_matomo",
34
- columns: ["action_type"],
33
+ name: 'idx_action_type_matomo',
34
+ columns: ['action_type']
35
35
  },
36
36
  {
37
- name: "idx_actionurl",
38
- columns: ["action_url"],
37
+ name: 'idx_actionurl',
38
+ columns: ['action_url']
39
39
  },
40
40
  {
41
- name: "idx_dimension1",
42
- columns: ["dimension1"],
41
+ name: 'idx_dimension1',
42
+ columns: ['dimension1']
43
43
  },
44
44
  {
45
- name: "idx_dimension2",
46
- columns: ["dimension2"],
45
+ name: 'idx_dimension2',
46
+ columns: ['dimension2']
47
47
  },
48
48
  {
49
- name: "idx_dimension3",
50
- columns: ["dimension3"],
49
+ name: 'idx_dimension3',
50
+ columns: ['dimension3']
51
51
  },
52
52
  {
53
- name: "idx_dimension4",
54
- columns: ["dimension4"],
53
+ name: 'idx_dimension4',
54
+ columns: ['dimension4']
55
55
  },
56
56
  {
57
- name: "idx_dimension5",
58
- columns: ["dimension5"],
57
+ name: 'idx_dimension5',
58
+ columns: ['dimension5']
59
59
  },
60
60
  {
61
- name: "idx_idvisit_matomo",
62
- columns: ["idvisit"],
61
+ name: 'idx_idvisit_matomo',
62
+ columns: ['idvisit']
63
63
  },
64
64
  {
65
- name: "idx_region",
66
- columns: ["region"],
65
+ name: 'idx_region',
66
+ columns: ['region']
67
67
  },
68
68
  {
69
- name: "idx_userid",
70
- columns: ["userid"],
69
+ name: 'idx_userid',
70
+ columns: ['userid']
71
71
  },
72
72
  {
73
- name: "idx_visitorid",
74
- columns: ["visitorid"],
75
- },
73
+ name: 'idx_visitorid',
74
+ columns: ['visitorid']
75
+ }
76
76
  ];
77
77
  function up(db) {
78
78
  return __awaiter(this, void 0, void 0, function* () {
@@ -80,15 +80,15 @@ function up(db) {
80
80
  yield db.schema
81
81
  .createIndex(index.name)
82
82
  .ifNotExists()
83
- .on(DESTINATION_TABLE)
84
- .using("btree")
83
+ .on(MATOMO_TABLE_NAME)
84
+ .using('btree')
85
85
  .columns(index.columns)
86
86
  .execute();
87
87
  }));
88
88
  yield db.schema
89
- .createIndex("actions_day")
89
+ .createIndex('actions_day')
90
90
  .ifNotExists()
91
- .on(DESTINATION_TABLE)
91
+ .on(MATOMO_TABLE_NAME)
92
92
  .expression((0, kysely_1.sql) `date(timezone('UTC', action_timestamp))`)
93
93
  .execute();
94
94
  });
@@ -99,7 +99,7 @@ function down(db) {
99
99
  indexes.forEach((index) => __awaiter(this, void 0, void 0, function* () {
100
100
  yield db.schema.dropIndex(index.name).execute();
101
101
  }));
102
- db.schema.dropIndex("actions_day").execute();
102
+ db.schema.dropIndex('actions_day').execute();
103
103
  });
104
104
  }
105
105
  exports.down = down;
@@ -10,16 +10,22 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.down = exports.up = void 0;
13
- const DESTINATION_TABLE = process.env.DESTINATION_TABLE || "matomo";
13
+ const MATOMO_TABLE_NAME = process.env.MATOMO_TABLE_NAME || 'matomo';
14
14
  function up(db) {
15
15
  return __awaiter(this, void 0, void 0, function* () {
16
- yield db.schema.alterTable(DESTINATION_TABLE).addColumn("resolution", "text").execute();
16
+ yield db.schema
17
+ .alterTable(MATOMO_TABLE_NAME)
18
+ .addColumn('resolution', 'text')
19
+ .execute();
17
20
  });
18
21
  }
19
22
  exports.up = up;
20
23
  function down(db) {
21
24
  return __awaiter(this, void 0, void 0, function* () {
22
- yield db.schema.alterTable(DESTINATION_TABLE).dropColumn("resolution").execute();
25
+ yield db.schema
26
+ .alterTable(MATOMO_TABLE_NAME)
27
+ .dropColumn('resolution')
28
+ .execute();
23
29
  });
24
30
  }
25
31
  exports.down = down;