quidproquo-webserver 0.1.12 → 0.1.13
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/lib/commonjs/config/settings/migration.js +2 -2
- package/lib/commonjs/config/settings/migration.js.map +1 -1
- package/lib/commonjs/config/settings/seed.js +2 -2
- package/lib/commonjs/config/settings/seed.js.map +1 -1
- package/lib/commonjs/services/index.d.ts +1 -0
- package/lib/commonjs/services/index.js +1 -0
- package/lib/commonjs/services/index.js.map +1 -1
- package/lib/commonjs/services/migration/index.d.ts +2 -0
- package/lib/commonjs/services/migration/index.js +22 -0
- package/lib/commonjs/services/migration/index.js.map +1 -0
- package/lib/commonjs/services/migration/logic/askRunPendingMigrations.d.ts +18 -0
- package/lib/commonjs/services/migration/logic/askRunPendingMigrations.js +33 -0
- package/lib/commonjs/services/migration/logic/askRunPendingMigrations.js.map +1 -0
- package/lib/commonjs/services/migration/logic/onDeployLogic.js +5 -4
- package/lib/commonjs/services/migration/logic/onDeployLogic.js.map +1 -1
- package/lib/commonjs/services/migration/logic/pendingMigrations.d.ts +7 -0
- package/lib/commonjs/services/migration/logic/pendingMigrations.js +77 -0
- package/lib/commonjs/services/migration/logic/pendingMigrations.js.map +1 -0
- package/lib/esm/config/settings/migration.js +1 -1
- package/lib/esm/config/settings/migration.js.map +1 -1
- package/lib/esm/config/settings/seed.js +1 -1
- package/lib/esm/config/settings/seed.js.map +1 -1
- package/lib/esm/services/index.d.ts +1 -0
- package/lib/esm/services/index.js +1 -0
- package/lib/esm/services/index.js.map +1 -1
- package/lib/esm/services/migration/index.d.ts +2 -0
- package/lib/esm/services/migration/index.js +6 -0
- package/lib/esm/services/migration/index.js.map +1 -0
- package/lib/esm/services/migration/logic/askRunPendingMigrations.d.ts +18 -0
- package/lib/esm/services/migration/logic/askRunPendingMigrations.js +30 -0
- package/lib/esm/services/migration/logic/askRunPendingMigrations.js.map +1 -0
- package/lib/esm/services/migration/logic/onDeployLogic.js +5 -4
- package/lib/esm/services/migration/logic/onDeployLogic.js.map +1 -1
- package/lib/esm/services/migration/logic/pendingMigrations.d.ts +7 -0
- package/lib/esm/services/migration/logic/pendingMigrations.js +36 -0
- package/lib/esm/services/migration/logic/pendingMigrations.js.map +1 -0
- package/package.json +3 -3
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.defineMigration = void 0;
|
|
4
4
|
exports.getQpqMigrationQueueTypeFromQpqFunctionRuntime = getQpqMigrationQueueTypeFromQpqFunctionRuntime;
|
|
5
5
|
const quidproquo_core_1 = require("quidproquo-core");
|
|
6
|
-
const
|
|
6
|
+
const getServiceEntryQpqFunctionRuntime_1 = require("../../services/getServiceEntryQpqFunctionRuntime");
|
|
7
7
|
function removeLeadingSlashs(text) {
|
|
8
8
|
if (text.startsWith('/')) {
|
|
9
9
|
return removeLeadingSlashs(text.slice(1));
|
|
@@ -24,7 +24,7 @@ const defineMigration = (migrations, options) => {
|
|
|
24
24
|
// Create a kvs so we can track which migrations have been run
|
|
25
25
|
(0, quidproquo_core_1.defineKeyValueStore)('qpqMigrations', 'srcPath', ['deployType'], options),
|
|
26
26
|
// Listen to deploy events
|
|
27
|
-
(0, quidproquo_core_1.defineDeployEvent)('qpqMigrations', (0,
|
|
27
|
+
(0, quidproquo_core_1.defineDeployEvent)('qpqMigrations', (0, getServiceEntryQpqFunctionRuntime_1.getServiceEntryQpqFunctionRuntime)('migration', 'deployEvent', 'onDeploy::onDeploy')),
|
|
28
28
|
// Build up a queue where the src names are the event types
|
|
29
29
|
(0, quidproquo_core_1.defineQueue)('qpqMigrations', migrations.reduce((acc, m) => (Object.assign(Object.assign({}, acc), { [getQpqMigrationQueueTypeFromQpqFunctionRuntime(m.runtime)]: m.runtime })), {}), Object.assign(Object.assign({}, options), { maxConcurrentExecutions: 1, batchSize: 1, concurrency: 1 })),
|
|
30
30
|
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration.js","sourceRoot":"","sources":["../../../../src/config/settings/migration.ts"],"names":[],"mappings":";;;AA6BA,wGAOC;AApCD,qDAUyB;AAEzB,
|
|
1
|
+
{"version":3,"file":"migration.js","sourceRoot":"","sources":["../../../../src/config/settings/migration.ts"],"names":[],"mappings":";;;AA6BA,wGAOC;AApCD,qDAUyB;AAEzB,wGAAqG;AASrG,SAAS,mBAAmB,CAAC,IAAY;IACvC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,8CAA8C,CAAC,kBAAsC;IACnG,IAAI,IAAA,8CAA4B,EAAC,kBAAkB,CAAC,EAAE,CAAC;QACrD,OAAO,GAAG,kBAAkB,CAAC,QAAQ,IAAI,mBAAmB,CAAC,kBAAkB,CAAC,YAAY,CAAC,EAAE,CAAC;IAClG,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACjD,OAAO,mBAAmB,CAAC,OAAO,CAAC,CAAC;AACtC,CAAC;AAEM,MAAM,eAAe,GAAG,CAAC,UAAuB,EAAE,OAA4C,EAAa,EAAE;IAClH,OAAO;QACL,+DAA+D;QAC/D,IAAA,8BAAY,EAAC,eAAe,EAAE,UAAU,CAAC;QAEzC,8DAA8D;QAC9D,IAAA,qCAAmB,EAAC,eAAe,EAAE,SAAS,EAAE,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;QAExE,0BAA0B;QAC1B,IAAA,mCAAiB,EAAC,eAAe,EAAE,IAAA,qEAAiC,EAAC,WAAW,EAAE,aAAa,EAAE,oBAAoB,CAAC,CAAC;QAEvH,2DAA2D;QAC3D,IAAA,6BAAW,EACT,eAAe,EACf,UAAU,CAAC,MAAM,CACf,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iCACP,GAAG,KACN,CAAC,8CAA8C,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,IACtE,EACF,EAAE,CACH,kCAEI,OAAO,KACV,uBAAuB,EAAE,CAAC,EAC1B,SAAS,EAAE,CAAC,EACZ,WAAW,EAAE,CAAC,IAEjB;KACF,CAAC;AACJ,CAAC,CAAC;AA7BW,QAAA,eAAe,mBA6B1B","sourcesContent":["import {\n defineDeployEvent,\n defineGlobal,\n defineKeyValueStore,\n defineQueue,\n DeployEventType,\n isQpqFunctionRuntimeAdvanced,\n QPQConfig,\n QPQConfigAdvancedSettings,\n QpqFunctionRuntime,\n} from 'quidproquo-core';\n\nimport { getServiceEntryQpqFunctionRuntime } from '../../services/getServiceEntryQpqFunctionRuntime';\n\nexport interface Migration {\n runtime: QpqFunctionRuntime;\n deployType: DeployEventType;\n}\n\nexport interface QPQConfigAdvancedMigrationSettings extends QPQConfigAdvancedSettings {}\n\nfunction removeLeadingSlashs(text: string): string {\n if (text.startsWith('/')) {\n return removeLeadingSlashs(text.slice(1));\n }\n\n return text;\n}\n\nexport function getQpqMigrationQueueTypeFromQpqFunctionRuntime(qpqFunctionRuntime: QpqFunctionRuntime): string {\n if (isQpqFunctionRuntimeAdvanced(qpqFunctionRuntime)) {\n return `${qpqFunctionRuntime.basePath}/${removeLeadingSlashs(qpqFunctionRuntime.relativePath)}`;\n }\n\n const [srcPath] = qpqFunctionRuntime.split('::');\n return removeLeadingSlashs(srcPath);\n}\n\nexport const defineMigration = (migrations: Migration[], options?: QPQConfigAdvancedMigrationSettings): QPQConfig => {\n return [\n // Define a global so we can access the migrations from the src\n defineGlobal('qpqMigrations', migrations),\n\n // Create a kvs so we can track which migrations have been run\n defineKeyValueStore('qpqMigrations', 'srcPath', ['deployType'], options),\n\n // Listen to deploy events\n defineDeployEvent('qpqMigrations', getServiceEntryQpqFunctionRuntime('migration', 'deployEvent', 'onDeploy::onDeploy')),\n\n // Build up a queue where the src names are the event types\n defineQueue(\n 'qpqMigrations',\n migrations.reduce(\n (acc, m) => ({\n ...acc,\n [getQpqMigrationQueueTypeFromQpqFunctionRuntime(m.runtime)]: m.runtime,\n }),\n {},\n ),\n {\n ...options,\n maxConcurrentExecutions: 1,\n batchSize: 1,\n concurrency: 1,\n },\n ),\n ];\n};\n"]}
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.defineSeed = void 0;
|
|
4
4
|
const quidproquo_core_1 = require("quidproquo-core");
|
|
5
|
-
const
|
|
5
|
+
const getServiceEntryQpqFunctionRuntime_1 = require("../../services/getServiceEntryQpqFunctionRuntime");
|
|
6
6
|
const defineSeed = (seeds) => {
|
|
7
7
|
return [
|
|
8
8
|
// Define a global so we can access the seeds from the src
|
|
9
9
|
(0, quidproquo_core_1.defineGlobal)('qpqSeeds', seeds),
|
|
10
10
|
// Listen to deploy events
|
|
11
|
-
(0, quidproquo_core_1.defineDeployEvent)('qpqSeeds', (0,
|
|
11
|
+
(0, quidproquo_core_1.defineDeployEvent)('qpqSeeds', (0, getServiceEntryQpqFunctionRuntime_1.getServiceEntryQpqFunctionRuntime)('seed', 'deployEvent', 'onDeploy::onDeploy')),
|
|
12
12
|
// Build up a queue where the src names are the event types
|
|
13
13
|
(0, quidproquo_core_1.defineQueue)('qpqSeeds', seeds.reduce((acc, s) => (Object.assign(Object.assign({}, acc), { [(0, quidproquo_core_1.getUniqueKeyFromQpqFunctionRuntime)(s)]: s })), {}), {
|
|
14
14
|
maxConcurrentExecutions: 1,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seed.js","sourceRoot":"","sources":["../../../../src/config/settings/seed.ts"],"names":[],"mappings":";;;AAAA,qDAAkJ;AAElJ,
|
|
1
|
+
{"version":3,"file":"seed.js","sourceRoot":"","sources":["../../../../src/config/settings/seed.ts"],"names":[],"mappings":";;;AAAA,qDAAkJ;AAElJ,wGAAqG;AAE9F,MAAM,UAAU,GAAG,CAAC,KAA2B,EAAa,EAAE;IACnE,OAAO;QACL,0DAA0D;QAC1D,IAAA,8BAAY,EAAC,UAAU,EAAE,KAAK,CAAC;QAE/B,0BAA0B;QAC1B,IAAA,mCAAiB,EAAC,UAAU,EAAE,IAAA,qEAAiC,EAAC,MAAM,EAAE,aAAa,EAAE,oBAAoB,CAAC,CAAC;QAE7G,2DAA2D;QAC3D,IAAA,6BAAW,EACT,UAAU,EACV,KAAK,CAAC,MAAM,CACV,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iCACP,GAAG,KACN,CAAC,IAAA,oDAAkC,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAC1C,EACF,EAAE,CACH,EACD;YACE,uBAAuB,EAAE,CAAC;YAC1B,SAAS,EAAE,CAAC;YACZ,WAAW,EAAE,CAAC;SACf,CACF;KACF,CAAC;AACJ,CAAC,CAAC;AAzBW,QAAA,UAAU,cAyBrB","sourcesContent":["import { defineDeployEvent, defineGlobal, defineQueue, getUniqueKeyFromQpqFunctionRuntime, QPQConfig, QpqFunctionRuntime } from 'quidproquo-core';\n\nimport { getServiceEntryQpqFunctionRuntime } from '../../services/getServiceEntryQpqFunctionRuntime';\n\nexport const defineSeed = (seeds: QpqFunctionRuntime[]): QPQConfig => {\n return [\n // Define a global so we can access the seeds from the src\n defineGlobal('qpqSeeds', seeds),\n\n // Listen to deploy events\n defineDeployEvent('qpqSeeds', getServiceEntryQpqFunctionRuntime('seed', 'deployEvent', 'onDeploy::onDeploy')),\n\n // Build up a queue where the src names are the event types\n defineQueue(\n 'qpqSeeds',\n seeds.reduce(\n (acc, s) => ({\n ...acc,\n [getUniqueKeyFromQpqFunctionRuntime(s)]: s,\n }),\n {},\n ),\n {\n maxConcurrentExecutions: 1,\n batchSize: 1,\n concurrency: 1,\n },\n ),\n ];\n};\n"]}
|
|
@@ -16,5 +16,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./auth"), exports);
|
|
18
18
|
__exportStar(require("./getServiceEntryQpqFunctionRuntime"), exports);
|
|
19
|
+
__exportStar(require("./migration"), exports);
|
|
19
20
|
__exportStar(require("./serviceImporter"), exports);
|
|
20
21
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,yCAAuB;AACvB,sEAAoD;AACpD,oDAAkC","sourcesContent":["export * from './auth';\nexport * from './getServiceEntryQpqFunctionRuntime';\nexport * from './serviceImporter';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,yCAAuB;AACvB,sEAAoD;AACpD,8CAA4B;AAC5B,oDAAkC","sourcesContent":["export * from './auth';\nexport * from './getServiceEntryQpqFunctionRuntime';\nexport * from './migration';\nexport * from './serviceImporter';\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
// The migration service's public surface. Its entry points are loaded by runtime path (see
|
|
18
|
+
// defineMigration), so only what a HOST needs is exported: the local runner used by
|
|
19
|
+
// `qpq migrate`, and the shared notion of which migrations are still pending.
|
|
20
|
+
__exportStar(require("./logic/askRunPendingMigrations"), exports);
|
|
21
|
+
__exportStar(require("./logic/pendingMigrations"), exports);
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/services/migration/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2FAA2F;AAC3F,oFAAoF;AACpF,8EAA8E;AAC9E,kEAAgD;AAChD,4DAA0C","sourcesContent":["// The migration service's public surface. Its entry points are loaded by runtime path (see\n// defineMigration), so only what a HOST needs is exported: the local runner used by\n// `qpq migrate`, and the shared notion of which migrations are still pending.\nexport * from './logic/askRunPendingMigrations';\nexport * from './logic/pendingMigrations';\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { AskResponse } from 'quidproquo-core';
|
|
2
|
+
/**
|
|
3
|
+
* Enqueue every migration that has not run yet, and record it as run.
|
|
4
|
+
*
|
|
5
|
+
* The same two steps `askProcessOnDeployUpdate` performs, without the deploy event. Deployed,
|
|
6
|
+
* a stack update is what triggers migrations; locally nothing ever does, which is why
|
|
7
|
+
* `qpq migrate` exists — and why this goes through the SAME queue rather than invoking the
|
|
8
|
+
* handlers directly. A migration that only works under the local runner is worse than no
|
|
9
|
+
* local runner: the point is to rehearse the deployed path.
|
|
10
|
+
*
|
|
11
|
+
* Returns the keys enqueued, so a caller can report what it did (and report nothing when
|
|
12
|
+
* there was nothing to do, which should be the common case).
|
|
13
|
+
*
|
|
14
|
+
* Recording happens per migration as it is enqueued, matching the deploy path. That means a
|
|
15
|
+
* migration is marked run before its handler necessarily finishes: a crash mid-run leaves it
|
|
16
|
+
* recorded and unfinished, so migrations have to be safe to write as idempotent anyway.
|
|
17
|
+
*/
|
|
18
|
+
export declare function askRunPendingMigrations(): AskResponse<string[]>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.askRunPendingMigrations = askRunPendingMigrations;
|
|
4
|
+
const quidproquo_core_1 = require("quidproquo-core");
|
|
5
|
+
const pendingMigrations_1 = require("./pendingMigrations");
|
|
6
|
+
/**
|
|
7
|
+
* Enqueue every migration that has not run yet, and record it as run.
|
|
8
|
+
*
|
|
9
|
+
* The same two steps `askProcessOnDeployUpdate` performs, without the deploy event. Deployed,
|
|
10
|
+
* a stack update is what triggers migrations; locally nothing ever does, which is why
|
|
11
|
+
* `qpq migrate` exists — and why this goes through the SAME queue rather than invoking the
|
|
12
|
+
* handlers directly. A migration that only works under the local runner is worse than no
|
|
13
|
+
* local runner: the point is to rehearse the deployed path.
|
|
14
|
+
*
|
|
15
|
+
* Returns the keys enqueued, so a caller can report what it did (and report nothing when
|
|
16
|
+
* there was nothing to do, which should be the common case).
|
|
17
|
+
*
|
|
18
|
+
* Recording happens per migration as it is enqueued, matching the deploy path. That means a
|
|
19
|
+
* migration is marked run before its handler necessarily finishes: a crash mid-run leaves it
|
|
20
|
+
* recorded and unfinished, so migrations have to be safe to write as idempotent anyway.
|
|
21
|
+
*/
|
|
22
|
+
function* askRunPendingMigrations() {
|
|
23
|
+
const pending = yield* (0, pendingMigrations_1.askPendingMigrations)();
|
|
24
|
+
for (const migration of pending) {
|
|
25
|
+
const key = (0, pendingMigrations_1.getMigrationKey)(migration);
|
|
26
|
+
yield* (0, quidproquo_core_1.askLogCreate)(quidproquo_core_1.LogLevelEnum.Info, `Running migration: ${key}`);
|
|
27
|
+
const message = { type: key, payload: undefined };
|
|
28
|
+
yield* (0, quidproquo_core_1.askQueueSendMessages)('qpqMigrations', message);
|
|
29
|
+
yield* (0, pendingMigrations_1.askRecordMigrationRan)(migration);
|
|
30
|
+
}
|
|
31
|
+
return pending.map(pendingMigrations_1.getMigrationKey);
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=askRunPendingMigrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"askRunPendingMigrations.js","sourceRoot":"","sources":["../../../../../src/services/migration/logic/askRunPendingMigrations.ts"],"names":[],"mappings":";;AAoBA,0DAeC;AAnCD,qDAA8G;AAE9G,2DAAmG;AAEnG;;;;;;;;;;;;;;;GAeG;AACH,QAAe,CAAC,CAAC,uBAAuB;IACtC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,IAAA,wCAAoB,GAAE,CAAC;IAE9C,KAAK,MAAM,SAAS,IAAI,OAAO,EAAE,CAAC;QAChC,MAAM,GAAG,GAAG,IAAA,mCAAe,EAAC,SAAS,CAAC,CAAC;QAEvC,KAAK,CAAC,CAAC,IAAA,8BAAY,EAAC,8BAAY,CAAC,IAAI,EAAE,sBAAsB,GAAG,EAAE,CAAC,CAAC;QAEpE,MAAM,OAAO,GAA4B,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;QAC3E,KAAK,CAAC,CAAC,IAAA,sCAAoB,EAAC,eAAe,EAAE,OAAO,CAAC,CAAC;QAEtD,KAAK,CAAC,CAAC,IAAA,yCAAqB,EAAC,SAAS,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,OAAO,CAAC,GAAG,CAAC,mCAAe,CAAC,CAAC;AACtC,CAAC","sourcesContent":["import { askLogCreate, askQueueSendMessages, AskResponse, LogLevelEnum, QueueMessage } from 'quidproquo-core';\n\nimport { askPendingMigrations, askRecordMigrationRan, getMigrationKey } from './pendingMigrations';\n\n/**\n * Enqueue every migration that has not run yet, and record it as run.\n *\n * The same two steps `askProcessOnDeployUpdate` performs, without the deploy event. Deployed,\n * a stack update is what triggers migrations; locally nothing ever does, which is why\n * `qpq migrate` exists — and why this goes through the SAME queue rather than invoking the\n * handlers directly. A migration that only works under the local runner is worse than no\n * local runner: the point is to rehearse the deployed path.\n *\n * Returns the keys enqueued, so a caller can report what it did (and report nothing when\n * there was nothing to do, which should be the common case).\n *\n * Recording happens per migration as it is enqueued, matching the deploy path. That means a\n * migration is marked run before its handler necessarily finishes: a crash mid-run leaves it\n * recorded and unfinished, so migrations have to be safe to write as idempotent anyway.\n */\nexport function* askRunPendingMigrations(): AskResponse<string[]> {\n const pending = yield* askPendingMigrations();\n\n for (const migration of pending) {\n const key = getMigrationKey(migration);\n\n yield* askLogCreate(LogLevelEnum.Info, `Running migration: ${key}`);\n\n const message: QueueMessage<undefined> = { type: key, payload: undefined };\n yield* askQueueSendMessages('qpqMigrations', message);\n\n yield* askRecordMigrationRan(migration);\n }\n\n return pending.map(getMigrationKey);\n}\n"]}
|
|
@@ -39,6 +39,7 @@ exports.onDeploy = onDeploy;
|
|
|
39
39
|
const quidproquo_core_1 = require("quidproquo-core");
|
|
40
40
|
const migration_1 = require("../../../config/settings/migration");
|
|
41
41
|
const migrationInfoData = __importStar(require("../data/migrationInfoData"));
|
|
42
|
+
const pendingMigrations_1 = require("./pendingMigrations");
|
|
42
43
|
function* askProcessOnDeployCreate() {
|
|
43
44
|
const allMigrations = yield* (0, quidproquo_core_1.askConfigGetGlobal)('qpqMigrations');
|
|
44
45
|
// Insert all migrations into the database
|
|
@@ -56,10 +57,10 @@ function* askProcessOnDeployUpdate(deployEventType) {
|
|
|
56
57
|
const allMigrations = yield* (0, quidproquo_core_1.askConfigGetGlobal)('qpqMigrations');
|
|
57
58
|
const migrationsForThisDeploy = allMigrations.filter((m) => m.deployType === deployEventType);
|
|
58
59
|
for (const migration of migrationsForThisDeploy) {
|
|
59
|
-
const srcPathType = (0,
|
|
60
|
-
|
|
61
|
-
//
|
|
62
|
-
if (
|
|
60
|
+
const srcPathType = (0, pendingMigrations_1.getMigrationKey)(migration);
|
|
61
|
+
// Ignore if we have already run it. Shared with the local runner (qpq migrate) so both
|
|
62
|
+
// agree on what pending means.
|
|
63
|
+
if (!(yield* (0, pendingMigrations_1.askIsMigrationPending)(migration))) {
|
|
63
64
|
continue;
|
|
64
65
|
}
|
|
65
66
|
// Send a message to the queue to run the migration.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onDeployLogic.js","sourceRoot":"","sources":["../../../../../src/services/migration/logic/onDeployLogic.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"onDeployLogic.js","sourceRoot":"","sources":["../../../../../src/services/migration/logic/onDeployLogic.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,4DAaC;AAED,4DA2BC;AAED,4BAMC;AAxDD,qDAA8I;AAE9I,kEAA+G;AAC/G,6EAA+D;AAC/D,2DAA6E;AAE7E,QAAe,CAAC,CAAC,wBAAwB;IACvC,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,IAAA,oCAAkB,EAAc,eAAe,CAAC,CAAC;IAE9E,0CAA0C;IAC1C,8CAA8C;IAC9C,mDAAmD;IACnD,KAAK,MAAM,SAAS,IAAI,aAAa,EAAE,CAAC;QACtC,yDAAyD;QACzD,KAAK,CAAC,CAAC,iBAAiB,CAAC,SAAS,CAAC;YACjC,UAAU,EAAE,SAAS,CAAC,UAAU;YAChC,OAAO,EAAE,IAAA,0DAA8C,EAAC,SAAS,CAAC,OAAO,CAAC;SAC3E,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,QAAe,CAAC,CAAC,wBAAwB,CAAC,eAAgC;IACxE,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,IAAA,oCAAkB,EAAc,eAAe,CAAC,CAAC;IAC9E,MAAM,uBAAuB,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,eAAe,CAAC,CAAC;IAE9F,KAAK,MAAM,SAAS,IAAI,uBAAuB,EAAE,CAAC;QAChD,MAAM,WAAW,GAAG,IAAA,mCAAe,EAAC,SAAS,CAAC,CAAC;QAE/C,uFAAuF;QACvF,+BAA+B;QAC/B,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,IAAA,yCAAqB,EAAC,SAAS,CAAC,CAAC,EAAE,CAAC;YAC/C,SAAS;QACX,CAAC;QAED,oDAAoD;QACpD,MAAM,OAAO,GAA4B;YACvC,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,SAAS;SACnB,CAAC;QAEF,KAAK,CAAC,CAAC,IAAA,sCAAoB,EAAC,eAAe,EAAE,OAAO,CAAC,CAAC;QAEtD,8CAA8C;QAC9C,KAAK,CAAC,CAAC,iBAAiB,CAAC,SAAS,CAAC;YACjC,UAAU,EAAE,SAAS,CAAC,UAAU;YAChC,OAAO,EAAE,WAAW;SACrB,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,QAAe,CAAC,CAAC,QAAQ,CAAC,eAAgC,EAAE,qBAA4C;IACtG,IAAI,qBAAqB,KAAK,uCAAqB,CAAC,MAAM,EAAE,CAAC;QAC3D,KAAK,CAAC,CAAC,wBAAwB,CAAC,eAAe,CAAC,CAAC;IACnD,CAAC;SAAM,IAAI,qBAAqB,KAAK,uCAAqB,CAAC,MAAM,EAAE,CAAC;QAClE,KAAK,CAAC,CAAC,wBAAwB,EAAE,CAAC;IACpC,CAAC;AACH,CAAC","sourcesContent":["import { askConfigGetGlobal, askQueueSendMessages, AskResponse, DeployEventStatusType, DeployEventType, QueueMessage } from 'quidproquo-core';\n\nimport { getQpqMigrationQueueTypeFromQpqFunctionRuntime, Migration } from '../../../config/settings/migration';\nimport * as migrationInfoData from '../data/migrationInfoData';\nimport { askIsMigrationPending, getMigrationKey } from './pendingMigrations';\n\nexport function* askProcessOnDeployCreate(): AskResponse<void> {\n const allMigrations = yield* askConfigGetGlobal<Migration[]>('qpqMigrations');\n\n // Insert all migrations into the database\n // we don't need to run any current migrations\n // because database should be ready with seed data.\n for (const migration of allMigrations) {\n // We remove the leading slash for backward compatibility\n yield* migrationInfoData.askUpsert({\n deployType: migration.deployType,\n srcPath: getQpqMigrationQueueTypeFromQpqFunctionRuntime(migration.runtime),\n });\n }\n}\n\nexport function* askProcessOnDeployUpdate(deployEventType: DeployEventType): AskResponse<void> {\n const allMigrations = yield* askConfigGetGlobal<Migration[]>('qpqMigrations');\n const migrationsForThisDeploy = allMigrations.filter((m) => m.deployType === deployEventType);\n\n for (const migration of migrationsForThisDeploy) {\n const srcPathType = getMigrationKey(migration);\n\n // Ignore if we have already run it. Shared with the local runner (qpq migrate) so both\n // agree on what pending means.\n if (!(yield* askIsMigrationPending(migration))) {\n continue;\n }\n\n // Send a message to the queue to run the migration.\n const message: QueueMessage<undefined> = {\n type: srcPathType,\n payload: undefined,\n };\n\n yield* askQueueSendMessages('qpqMigrations', message);\n\n // Insert the migration into into the database\n yield* migrationInfoData.askUpsert({\n deployType: migration.deployType,\n srcPath: srcPathType,\n });\n }\n}\n\nexport function* onDeploy(deployEventType: DeployEventType, deployEventStatusType: DeployEventStatusType): AskResponse<void> {\n if (deployEventStatusType === DeployEventStatusType.Update) {\n yield* askProcessOnDeployUpdate(deployEventType);\n } else if (deployEventStatusType === DeployEventStatusType.Create) {\n yield* askProcessOnDeployCreate();\n }\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AskResponse } from 'quidproquo-core';
|
|
2
|
+
import { Migration } from '../../../config/settings/migration';
|
|
3
|
+
export declare const getMigrationKey: (migration: Migration) => string;
|
|
4
|
+
export declare function askIsMigrationPending(migration: Migration): AskResponse<boolean>;
|
|
5
|
+
export declare function askAllMigrations(): AskResponse<Migration[]>;
|
|
6
|
+
export declare function askPendingMigrations(): AskResponse<Migration[]>;
|
|
7
|
+
export declare function askRecordMigrationRan(migration: Migration): AskResponse<void>;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getMigrationKey = void 0;
|
|
37
|
+
exports.askIsMigrationPending = askIsMigrationPending;
|
|
38
|
+
exports.askAllMigrations = askAllMigrations;
|
|
39
|
+
exports.askPendingMigrations = askPendingMigrations;
|
|
40
|
+
exports.askRecordMigrationRan = askRecordMigrationRan;
|
|
41
|
+
const quidproquo_core_1 = require("quidproquo-core");
|
|
42
|
+
const migration_1 = require("../../../config/settings/migration");
|
|
43
|
+
const migrationInfoData = __importStar(require("../data/migrationInfoData"));
|
|
44
|
+
// A migration is identified by its source path, which is also its queue event type.
|
|
45
|
+
const getMigrationKey = (migration) => (0, migration_1.getQpqMigrationQueueTypeFromQpqFunctionRuntime)(migration.runtime);
|
|
46
|
+
exports.getMigrationKey = getMigrationKey;
|
|
47
|
+
// Has this migration already been recorded as run? Shared by the deploy path and the local
|
|
48
|
+
// runner so the two can never disagree about what "pending" means — a runner that answered
|
|
49
|
+
// differently would either re-run a migration or skip one.
|
|
50
|
+
function* askIsMigrationPending(migration) {
|
|
51
|
+
const migrationInfo = yield* migrationInfoData.askGetMigrationBySrcPath((0, exports.getMigrationKey)(migration));
|
|
52
|
+
return !migrationInfo;
|
|
53
|
+
}
|
|
54
|
+
// Every configured migration, in declaration order (the config preserves the sorted filename
|
|
55
|
+
// order the app registered them in, so dependencies between migrations hold).
|
|
56
|
+
function* askAllMigrations() {
|
|
57
|
+
return yield* (0, quidproquo_core_1.askConfigGetGlobal)('qpqMigrations');
|
|
58
|
+
}
|
|
59
|
+
// The ones not yet recorded as run, in order.
|
|
60
|
+
function* askPendingMigrations() {
|
|
61
|
+
const allMigrations = yield* askAllMigrations();
|
|
62
|
+
const pending = [];
|
|
63
|
+
for (const migration of allMigrations) {
|
|
64
|
+
if (yield* askIsMigrationPending(migration)) {
|
|
65
|
+
pending.push(migration);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return pending;
|
|
69
|
+
}
|
|
70
|
+
// Record a migration as run, so neither the deploy path nor the local runner picks it up again.
|
|
71
|
+
function* askRecordMigrationRan(migration) {
|
|
72
|
+
yield* migrationInfoData.askUpsert({
|
|
73
|
+
deployType: migration.deployType,
|
|
74
|
+
srcPath: (0, exports.getMigrationKey)(migration),
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=pendingMigrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pendingMigrations.js","sourceRoot":"","sources":["../../../../../src/services/migration/logic/pendingMigrations.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWA,sDAIC;AAID,4CAEC;AAGD,oDAYC;AAGD,sDAKC;AA5CD,qDAAkE;AAElE,kEAA+G;AAC/G,6EAA+D;AAE/D,oFAAoF;AAC7E,MAAM,eAAe,GAAG,CAAC,SAAoB,EAAU,EAAE,CAAC,IAAA,0DAA8C,EAAC,SAAS,CAAC,OAAO,CAAC,CAAC;AAAtH,QAAA,eAAe,mBAAuG;AAEnI,2FAA2F;AAC3F,2FAA2F;AAC3F,2DAA2D;AAC3D,QAAe,CAAC,CAAC,qBAAqB,CAAC,SAAoB;IACzD,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,iBAAiB,CAAC,wBAAwB,CAAC,IAAA,uBAAe,EAAC,SAAS,CAAC,CAAC,CAAC;IAEpG,OAAO,CAAC,aAAa,CAAC;AACxB,CAAC;AAED,6FAA6F;AAC7F,8EAA8E;AAC9E,QAAe,CAAC,CAAC,gBAAgB;IAC/B,OAAO,KAAK,CAAC,CAAC,IAAA,oCAAkB,EAAc,eAAe,CAAC,CAAC;AACjE,CAAC;AAED,8CAA8C;AAC9C,QAAe,CAAC,CAAC,oBAAoB;IACnC,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,gBAAgB,EAAE,CAAC;IAEhD,MAAM,OAAO,GAAgB,EAAE,CAAC;IAEhC,KAAK,MAAM,SAAS,IAAI,aAAa,EAAE,CAAC;QACtC,IAAI,KAAK,CAAC,CAAC,qBAAqB,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5C,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,gGAAgG;AAChG,QAAe,CAAC,CAAC,qBAAqB,CAAC,SAAoB;IACzD,KAAK,CAAC,CAAC,iBAAiB,CAAC,SAAS,CAAC;QACjC,UAAU,EAAE,SAAS,CAAC,UAAU;QAChC,OAAO,EAAE,IAAA,uBAAe,EAAC,SAAS,CAAC;KACpC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { askConfigGetGlobal, AskResponse } from 'quidproquo-core';\n\nimport { getQpqMigrationQueueTypeFromQpqFunctionRuntime, Migration } from '../../../config/settings/migration';\nimport * as migrationInfoData from '../data/migrationInfoData';\n\n// A migration is identified by its source path, which is also its queue event type.\nexport const getMigrationKey = (migration: Migration): string => getQpqMigrationQueueTypeFromQpqFunctionRuntime(migration.runtime);\n\n// Has this migration already been recorded as run? Shared by the deploy path and the local\n// runner so the two can never disagree about what \"pending\" means — a runner that answered\n// differently would either re-run a migration or skip one.\nexport function* askIsMigrationPending(migration: Migration): AskResponse<boolean> {\n const migrationInfo = yield* migrationInfoData.askGetMigrationBySrcPath(getMigrationKey(migration));\n\n return !migrationInfo;\n}\n\n// Every configured migration, in declaration order (the config preserves the sorted filename\n// order the app registered them in, so dependencies between migrations hold).\nexport function* askAllMigrations(): AskResponse<Migration[]> {\n return yield* askConfigGetGlobal<Migration[]>('qpqMigrations');\n}\n\n// The ones not yet recorded as run, in order.\nexport function* askPendingMigrations(): AskResponse<Migration[]> {\n const allMigrations = yield* askAllMigrations();\n\n const pending: Migration[] = [];\n\n for (const migration of allMigrations) {\n if (yield* askIsMigrationPending(migration)) {\n pending.push(migration);\n }\n }\n\n return pending;\n}\n\n// Record a migration as run, so neither the deploy path nor the local runner picks it up again.\nexport function* askRecordMigrationRan(migration: Migration): AskResponse<void> {\n yield* migrationInfoData.askUpsert({\n deployType: migration.deployType,\n srcPath: getMigrationKey(migration),\n });\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineDeployEvent, defineGlobal, defineKeyValueStore, defineQueue, isQpqFunctionRuntimeAdvanced, } from 'quidproquo-core';
|
|
2
|
-
import { getServiceEntryQpqFunctionRuntime } from '../../services';
|
|
2
|
+
import { getServiceEntryQpqFunctionRuntime } from '../../services/getServiceEntryQpqFunctionRuntime';
|
|
3
3
|
function removeLeadingSlashs(text) {
|
|
4
4
|
if (text.startsWith('/')) {
|
|
5
5
|
return removeLeadingSlashs(text.slice(1));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration.js","sourceRoot":"","sources":["../../../../src/config/settings/migration.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,WAAW,EAEX,4BAA4B,GAI7B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,iCAAiC,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"migration.js","sourceRoot":"","sources":["../../../../src/config/settings/migration.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,WAAW,EAEX,4BAA4B,GAI7B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,iCAAiC,EAAE,MAAM,kDAAkD,CAAC;AASrG,SAAS,mBAAmB,CAAC,IAAY;IACvC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,8CAA8C,CAAC,kBAAsC;IACnG,IAAI,4BAA4B,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACrD,OAAO,GAAG,kBAAkB,CAAC,QAAQ,IAAI,mBAAmB,CAAC,kBAAkB,CAAC,YAAY,CAAC,EAAE,CAAC;IAClG,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACjD,OAAO,mBAAmB,CAAC,OAAO,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,UAAuB,EAAE,OAA4C,EAAa,EAAE;IAClH,OAAO;QACL,+DAA+D;QAC/D,YAAY,CAAC,eAAe,EAAE,UAAU,CAAC;QAEzC,8DAA8D;QAC9D,mBAAmB,CAAC,eAAe,EAAE,SAAS,EAAE,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;QAExE,0BAA0B;QAC1B,iBAAiB,CAAC,eAAe,EAAE,iCAAiC,CAAC,WAAW,EAAE,aAAa,EAAE,oBAAoB,CAAC,CAAC;QAEvH,2DAA2D;QAC3D,WAAW,CACT,eAAe,EACf,UAAU,CAAC,MAAM,CACf,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YACX,GAAG,GAAG;YACN,CAAC,8CAA8C,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO;SACvE,CAAC,EACF,EAAE,CACH,EACD;YACE,GAAG,OAAO;YACV,uBAAuB,EAAE,CAAC;YAC1B,SAAS,EAAE,CAAC;YACZ,WAAW,EAAE,CAAC;SACf,CACF;KACF,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {\n defineDeployEvent,\n defineGlobal,\n defineKeyValueStore,\n defineQueue,\n DeployEventType,\n isQpqFunctionRuntimeAdvanced,\n QPQConfig,\n QPQConfigAdvancedSettings,\n QpqFunctionRuntime,\n} from 'quidproquo-core';\n\nimport { getServiceEntryQpqFunctionRuntime } from '../../services/getServiceEntryQpqFunctionRuntime';\n\nexport interface Migration {\n runtime: QpqFunctionRuntime;\n deployType: DeployEventType;\n}\n\nexport interface QPQConfigAdvancedMigrationSettings extends QPQConfigAdvancedSettings {}\n\nfunction removeLeadingSlashs(text: string): string {\n if (text.startsWith('/')) {\n return removeLeadingSlashs(text.slice(1));\n }\n\n return text;\n}\n\nexport function getQpqMigrationQueueTypeFromQpqFunctionRuntime(qpqFunctionRuntime: QpqFunctionRuntime): string {\n if (isQpqFunctionRuntimeAdvanced(qpqFunctionRuntime)) {\n return `${qpqFunctionRuntime.basePath}/${removeLeadingSlashs(qpqFunctionRuntime.relativePath)}`;\n }\n\n const [srcPath] = qpqFunctionRuntime.split('::');\n return removeLeadingSlashs(srcPath);\n}\n\nexport const defineMigration = (migrations: Migration[], options?: QPQConfigAdvancedMigrationSettings): QPQConfig => {\n return [\n // Define a global so we can access the migrations from the src\n defineGlobal('qpqMigrations', migrations),\n\n // Create a kvs so we can track which migrations have been run\n defineKeyValueStore('qpqMigrations', 'srcPath', ['deployType'], options),\n\n // Listen to deploy events\n defineDeployEvent('qpqMigrations', getServiceEntryQpqFunctionRuntime('migration', 'deployEvent', 'onDeploy::onDeploy')),\n\n // Build up a queue where the src names are the event types\n defineQueue(\n 'qpqMigrations',\n migrations.reduce(\n (acc, m) => ({\n ...acc,\n [getQpqMigrationQueueTypeFromQpqFunctionRuntime(m.runtime)]: m.runtime,\n }),\n {},\n ),\n {\n ...options,\n maxConcurrentExecutions: 1,\n batchSize: 1,\n concurrency: 1,\n },\n ),\n ];\n};\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineDeployEvent, defineGlobal, defineQueue, getUniqueKeyFromQpqFunctionRuntime } from 'quidproquo-core';
|
|
2
|
-
import { getServiceEntryQpqFunctionRuntime } from '../../services';
|
|
2
|
+
import { getServiceEntryQpqFunctionRuntime } from '../../services/getServiceEntryQpqFunctionRuntime';
|
|
3
3
|
export const defineSeed = (seeds) => {
|
|
4
4
|
return [
|
|
5
5
|
// Define a global so we can access the seeds from the src
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seed.js","sourceRoot":"","sources":["../../../../src/config/settings/seed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,WAAW,EAAE,kCAAkC,EAAiC,MAAM,iBAAiB,CAAC;AAElJ,OAAO,EAAE,iCAAiC,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"seed.js","sourceRoot":"","sources":["../../../../src/config/settings/seed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,WAAW,EAAE,kCAAkC,EAAiC,MAAM,iBAAiB,CAAC;AAElJ,OAAO,EAAE,iCAAiC,EAAE,MAAM,kDAAkD,CAAC;AAErG,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAA2B,EAAa,EAAE;IACnE,OAAO;QACL,0DAA0D;QAC1D,YAAY,CAAC,UAAU,EAAE,KAAK,CAAC;QAE/B,0BAA0B;QAC1B,iBAAiB,CAAC,UAAU,EAAE,iCAAiC,CAAC,MAAM,EAAE,aAAa,EAAE,oBAAoB,CAAC,CAAC;QAE7G,2DAA2D;QAC3D,WAAW,CACT,UAAU,EACV,KAAK,CAAC,MAAM,CACV,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YACX,GAAG,GAAG;YACN,CAAC,kCAAkC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SAC3C,CAAC,EACF,EAAE,CACH,EACD;YACE,uBAAuB,EAAE,CAAC;YAC1B,SAAS,EAAE,CAAC;YACZ,WAAW,EAAE,CAAC;SACf,CACF;KACF,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { defineDeployEvent, defineGlobal, defineQueue, getUniqueKeyFromQpqFunctionRuntime, QPQConfig, QpqFunctionRuntime } from 'quidproquo-core';\n\nimport { getServiceEntryQpqFunctionRuntime } from '../../services/getServiceEntryQpqFunctionRuntime';\n\nexport const defineSeed = (seeds: QpqFunctionRuntime[]): QPQConfig => {\n return [\n // Define a global so we can access the seeds from the src\n defineGlobal('qpqSeeds', seeds),\n\n // Listen to deploy events\n defineDeployEvent('qpqSeeds', getServiceEntryQpqFunctionRuntime('seed', 'deployEvent', 'onDeploy::onDeploy')),\n\n // Build up a queue where the src names are the event types\n defineQueue(\n 'qpqSeeds',\n seeds.reduce(\n (acc, s) => ({\n ...acc,\n [getUniqueKeyFromQpqFunctionRuntime(s)]: s,\n }),\n {},\n ),\n {\n maxConcurrentExecutions: 1,\n batchSize: 1,\n concurrency: 1,\n },\n ),\n ];\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,qCAAqC,CAAC;AACpD,cAAc,mBAAmB,CAAC","sourcesContent":["export * from './auth';\nexport * from './getServiceEntryQpqFunctionRuntime';\nexport * from './serviceImporter';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,qCAAqC,CAAC;AACpD,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC","sourcesContent":["export * from './auth';\nexport * from './getServiceEntryQpqFunctionRuntime';\nexport * from './migration';\nexport * from './serviceImporter';\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// The migration service's public surface. Its entry points are loaded by runtime path (see
|
|
2
|
+
// defineMigration), so only what a HOST needs is exported: the local runner used by
|
|
3
|
+
// `qpq migrate`, and the shared notion of which migrations are still pending.
|
|
4
|
+
export * from './logic/askRunPendingMigrations';
|
|
5
|
+
export * from './logic/pendingMigrations';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/services/migration/index.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,oFAAoF;AACpF,8EAA8E;AAC9E,cAAc,iCAAiC,CAAC;AAChD,cAAc,2BAA2B,CAAC","sourcesContent":["// The migration service's public surface. Its entry points are loaded by runtime path (see\n// defineMigration), so only what a HOST needs is exported: the local runner used by\n// `qpq migrate`, and the shared notion of which migrations are still pending.\nexport * from './logic/askRunPendingMigrations';\nexport * from './logic/pendingMigrations';\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { AskResponse } from 'quidproquo-core';
|
|
2
|
+
/**
|
|
3
|
+
* Enqueue every migration that has not run yet, and record it as run.
|
|
4
|
+
*
|
|
5
|
+
* The same two steps `askProcessOnDeployUpdate` performs, without the deploy event. Deployed,
|
|
6
|
+
* a stack update is what triggers migrations; locally nothing ever does, which is why
|
|
7
|
+
* `qpq migrate` exists — and why this goes through the SAME queue rather than invoking the
|
|
8
|
+
* handlers directly. A migration that only works under the local runner is worse than no
|
|
9
|
+
* local runner: the point is to rehearse the deployed path.
|
|
10
|
+
*
|
|
11
|
+
* Returns the keys enqueued, so a caller can report what it did (and report nothing when
|
|
12
|
+
* there was nothing to do, which should be the common case).
|
|
13
|
+
*
|
|
14
|
+
* Recording happens per migration as it is enqueued, matching the deploy path. That means a
|
|
15
|
+
* migration is marked run before its handler necessarily finishes: a crash mid-run leaves it
|
|
16
|
+
* recorded and unfinished, so migrations have to be safe to write as idempotent anyway.
|
|
17
|
+
*/
|
|
18
|
+
export declare function askRunPendingMigrations(): AskResponse<string[]>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { askLogCreate, askQueueSendMessages, LogLevelEnum } from 'quidproquo-core';
|
|
2
|
+
import { askPendingMigrations, askRecordMigrationRan, getMigrationKey } from './pendingMigrations';
|
|
3
|
+
/**
|
|
4
|
+
* Enqueue every migration that has not run yet, and record it as run.
|
|
5
|
+
*
|
|
6
|
+
* The same two steps `askProcessOnDeployUpdate` performs, without the deploy event. Deployed,
|
|
7
|
+
* a stack update is what triggers migrations; locally nothing ever does, which is why
|
|
8
|
+
* `qpq migrate` exists — and why this goes through the SAME queue rather than invoking the
|
|
9
|
+
* handlers directly. A migration that only works under the local runner is worse than no
|
|
10
|
+
* local runner: the point is to rehearse the deployed path.
|
|
11
|
+
*
|
|
12
|
+
* Returns the keys enqueued, so a caller can report what it did (and report nothing when
|
|
13
|
+
* there was nothing to do, which should be the common case).
|
|
14
|
+
*
|
|
15
|
+
* Recording happens per migration as it is enqueued, matching the deploy path. That means a
|
|
16
|
+
* migration is marked run before its handler necessarily finishes: a crash mid-run leaves it
|
|
17
|
+
* recorded and unfinished, so migrations have to be safe to write as idempotent anyway.
|
|
18
|
+
*/
|
|
19
|
+
export function* askRunPendingMigrations() {
|
|
20
|
+
const pending = yield* askPendingMigrations();
|
|
21
|
+
for (const migration of pending) {
|
|
22
|
+
const key = getMigrationKey(migration);
|
|
23
|
+
yield* askLogCreate(LogLevelEnum.Info, `Running migration: ${key}`);
|
|
24
|
+
const message = { type: key, payload: undefined };
|
|
25
|
+
yield* askQueueSendMessages('qpqMigrations', message);
|
|
26
|
+
yield* askRecordMigrationRan(migration);
|
|
27
|
+
}
|
|
28
|
+
return pending.map(getMigrationKey);
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=askRunPendingMigrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"askRunPendingMigrations.js","sourceRoot":"","sources":["../../../../../src/services/migration/logic/askRunPendingMigrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAe,YAAY,EAAgB,MAAM,iBAAiB,CAAC;AAE9G,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEnG;;;;;;;;;;;;;;;GAeG;AACH,MAAM,SAAS,CAAC,CAAC,uBAAuB;IACtC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,oBAAoB,EAAE,CAAC;IAE9C,KAAK,MAAM,SAAS,IAAI,OAAO,EAAE,CAAC;QAChC,MAAM,GAAG,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;QAEvC,KAAK,CAAC,CAAC,YAAY,CAAC,YAAY,CAAC,IAAI,EAAE,sBAAsB,GAAG,EAAE,CAAC,CAAC;QAEpE,MAAM,OAAO,GAA4B,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;QAC3E,KAAK,CAAC,CAAC,oBAAoB,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;QAEtD,KAAK,CAAC,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;AACtC,CAAC","sourcesContent":["import { askLogCreate, askQueueSendMessages, AskResponse, LogLevelEnum, QueueMessage } from 'quidproquo-core';\n\nimport { askPendingMigrations, askRecordMigrationRan, getMigrationKey } from './pendingMigrations';\n\n/**\n * Enqueue every migration that has not run yet, and record it as run.\n *\n * The same two steps `askProcessOnDeployUpdate` performs, without the deploy event. Deployed,\n * a stack update is what triggers migrations; locally nothing ever does, which is why\n * `qpq migrate` exists — and why this goes through the SAME queue rather than invoking the\n * handlers directly. A migration that only works under the local runner is worse than no\n * local runner: the point is to rehearse the deployed path.\n *\n * Returns the keys enqueued, so a caller can report what it did (and report nothing when\n * there was nothing to do, which should be the common case).\n *\n * Recording happens per migration as it is enqueued, matching the deploy path. That means a\n * migration is marked run before its handler necessarily finishes: a crash mid-run leaves it\n * recorded and unfinished, so migrations have to be safe to write as idempotent anyway.\n */\nexport function* askRunPendingMigrations(): AskResponse<string[]> {\n const pending = yield* askPendingMigrations();\n\n for (const migration of pending) {\n const key = getMigrationKey(migration);\n\n yield* askLogCreate(LogLevelEnum.Info, `Running migration: ${key}`);\n\n const message: QueueMessage<undefined> = { type: key, payload: undefined };\n yield* askQueueSendMessages('qpqMigrations', message);\n\n yield* askRecordMigrationRan(migration);\n }\n\n return pending.map(getMigrationKey);\n}\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { askConfigGetGlobal, askQueueSendMessages, DeployEventStatusType } from 'quidproquo-core';
|
|
2
2
|
import { getQpqMigrationQueueTypeFromQpqFunctionRuntime } from '../../../config/settings/migration';
|
|
3
3
|
import * as migrationInfoData from '../data/migrationInfoData';
|
|
4
|
+
import { askIsMigrationPending, getMigrationKey } from './pendingMigrations';
|
|
4
5
|
export function* askProcessOnDeployCreate() {
|
|
5
6
|
const allMigrations = yield* askConfigGetGlobal('qpqMigrations');
|
|
6
7
|
// Insert all migrations into the database
|
|
@@ -18,10 +19,10 @@ export function* askProcessOnDeployUpdate(deployEventType) {
|
|
|
18
19
|
const allMigrations = yield* askConfigGetGlobal('qpqMigrations');
|
|
19
20
|
const migrationsForThisDeploy = allMigrations.filter((m) => m.deployType === deployEventType);
|
|
20
21
|
for (const migration of migrationsForThisDeploy) {
|
|
21
|
-
const srcPathType =
|
|
22
|
-
|
|
23
|
-
//
|
|
24
|
-
if (
|
|
22
|
+
const srcPathType = getMigrationKey(migration);
|
|
23
|
+
// Ignore if we have already run it. Shared with the local runner (qpq migrate) so both
|
|
24
|
+
// agree on what pending means.
|
|
25
|
+
if (!(yield* askIsMigrationPending(migration))) {
|
|
25
26
|
continue;
|
|
26
27
|
}
|
|
27
28
|
// Send a message to the queue to run the migration.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onDeployLogic.js","sourceRoot":"","sources":["../../../../../src/services/migration/logic/onDeployLogic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAe,qBAAqB,EAAiC,MAAM,iBAAiB,CAAC;AAE9I,OAAO,EAAE,8CAA8C,EAAa,MAAM,oCAAoC,CAAC;AAC/G,OAAO,KAAK,iBAAiB,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"onDeployLogic.js","sourceRoot":"","sources":["../../../../../src/services/migration/logic/onDeployLogic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAe,qBAAqB,EAAiC,MAAM,iBAAiB,CAAC;AAE9I,OAAO,EAAE,8CAA8C,EAAa,MAAM,oCAAoC,CAAC;AAC/G,OAAO,KAAK,iBAAiB,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE7E,MAAM,SAAS,CAAC,CAAC,wBAAwB;IACvC,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,kBAAkB,CAAc,eAAe,CAAC,CAAC;IAE9E,0CAA0C;IAC1C,8CAA8C;IAC9C,mDAAmD;IACnD,KAAK,MAAM,SAAS,IAAI,aAAa,EAAE,CAAC;QACtC,yDAAyD;QACzD,KAAK,CAAC,CAAC,iBAAiB,CAAC,SAAS,CAAC;YACjC,UAAU,EAAE,SAAS,CAAC,UAAU;YAChC,OAAO,EAAE,8CAA8C,CAAC,SAAS,CAAC,OAAO,CAAC;SAC3E,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,MAAM,SAAS,CAAC,CAAC,wBAAwB,CAAC,eAAgC;IACxE,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,kBAAkB,CAAc,eAAe,CAAC,CAAC;IAC9E,MAAM,uBAAuB,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,eAAe,CAAC,CAAC;IAE9F,KAAK,MAAM,SAAS,IAAI,uBAAuB,EAAE,CAAC;QAChD,MAAM,WAAW,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;QAE/C,uFAAuF;QACvF,+BAA+B;QAC/B,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;YAC/C,SAAS;QACX,CAAC;QAED,oDAAoD;QACpD,MAAM,OAAO,GAA4B;YACvC,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,SAAS;SACnB,CAAC;QAEF,KAAK,CAAC,CAAC,oBAAoB,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;QAEtD,8CAA8C;QAC9C,KAAK,CAAC,CAAC,iBAAiB,CAAC,SAAS,CAAC;YACjC,UAAU,EAAE,SAAS,CAAC,UAAU;YAChC,OAAO,EAAE,WAAW;SACrB,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,MAAM,SAAS,CAAC,CAAC,QAAQ,CAAC,eAAgC,EAAE,qBAA4C;IACtG,IAAI,qBAAqB,KAAK,qBAAqB,CAAC,MAAM,EAAE,CAAC;QAC3D,KAAK,CAAC,CAAC,wBAAwB,CAAC,eAAe,CAAC,CAAC;IACnD,CAAC;SAAM,IAAI,qBAAqB,KAAK,qBAAqB,CAAC,MAAM,EAAE,CAAC;QAClE,KAAK,CAAC,CAAC,wBAAwB,EAAE,CAAC;IACpC,CAAC;AACH,CAAC","sourcesContent":["import { askConfigGetGlobal, askQueueSendMessages, AskResponse, DeployEventStatusType, DeployEventType, QueueMessage } from 'quidproquo-core';\n\nimport { getQpqMigrationQueueTypeFromQpqFunctionRuntime, Migration } from '../../../config/settings/migration';\nimport * as migrationInfoData from '../data/migrationInfoData';\nimport { askIsMigrationPending, getMigrationKey } from './pendingMigrations';\n\nexport function* askProcessOnDeployCreate(): AskResponse<void> {\n const allMigrations = yield* askConfigGetGlobal<Migration[]>('qpqMigrations');\n\n // Insert all migrations into the database\n // we don't need to run any current migrations\n // because database should be ready with seed data.\n for (const migration of allMigrations) {\n // We remove the leading slash for backward compatibility\n yield* migrationInfoData.askUpsert({\n deployType: migration.deployType,\n srcPath: getQpqMigrationQueueTypeFromQpqFunctionRuntime(migration.runtime),\n });\n }\n}\n\nexport function* askProcessOnDeployUpdate(deployEventType: DeployEventType): AskResponse<void> {\n const allMigrations = yield* askConfigGetGlobal<Migration[]>('qpqMigrations');\n const migrationsForThisDeploy = allMigrations.filter((m) => m.deployType === deployEventType);\n\n for (const migration of migrationsForThisDeploy) {\n const srcPathType = getMigrationKey(migration);\n\n // Ignore if we have already run it. Shared with the local runner (qpq migrate) so both\n // agree on what pending means.\n if (!(yield* askIsMigrationPending(migration))) {\n continue;\n }\n\n // Send a message to the queue to run the migration.\n const message: QueueMessage<undefined> = {\n type: srcPathType,\n payload: undefined,\n };\n\n yield* askQueueSendMessages('qpqMigrations', message);\n\n // Insert the migration into into the database\n yield* migrationInfoData.askUpsert({\n deployType: migration.deployType,\n srcPath: srcPathType,\n });\n }\n}\n\nexport function* onDeploy(deployEventType: DeployEventType, deployEventStatusType: DeployEventStatusType): AskResponse<void> {\n if (deployEventStatusType === DeployEventStatusType.Update) {\n yield* askProcessOnDeployUpdate(deployEventType);\n } else if (deployEventStatusType === DeployEventStatusType.Create) {\n yield* askProcessOnDeployCreate();\n }\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AskResponse } from 'quidproquo-core';
|
|
2
|
+
import { Migration } from '../../../config/settings/migration';
|
|
3
|
+
export declare const getMigrationKey: (migration: Migration) => string;
|
|
4
|
+
export declare function askIsMigrationPending(migration: Migration): AskResponse<boolean>;
|
|
5
|
+
export declare function askAllMigrations(): AskResponse<Migration[]>;
|
|
6
|
+
export declare function askPendingMigrations(): AskResponse<Migration[]>;
|
|
7
|
+
export declare function askRecordMigrationRan(migration: Migration): AskResponse<void>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { askConfigGetGlobal } from 'quidproquo-core';
|
|
2
|
+
import { getQpqMigrationQueueTypeFromQpqFunctionRuntime } from '../../../config/settings/migration';
|
|
3
|
+
import * as migrationInfoData from '../data/migrationInfoData';
|
|
4
|
+
// A migration is identified by its source path, which is also its queue event type.
|
|
5
|
+
export const getMigrationKey = (migration) => getQpqMigrationQueueTypeFromQpqFunctionRuntime(migration.runtime);
|
|
6
|
+
// Has this migration already been recorded as run? Shared by the deploy path and the local
|
|
7
|
+
// runner so the two can never disagree about what "pending" means — a runner that answered
|
|
8
|
+
// differently would either re-run a migration or skip one.
|
|
9
|
+
export function* askIsMigrationPending(migration) {
|
|
10
|
+
const migrationInfo = yield* migrationInfoData.askGetMigrationBySrcPath(getMigrationKey(migration));
|
|
11
|
+
return !migrationInfo;
|
|
12
|
+
}
|
|
13
|
+
// Every configured migration, in declaration order (the config preserves the sorted filename
|
|
14
|
+
// order the app registered them in, so dependencies between migrations hold).
|
|
15
|
+
export function* askAllMigrations() {
|
|
16
|
+
return yield* askConfigGetGlobal('qpqMigrations');
|
|
17
|
+
}
|
|
18
|
+
// The ones not yet recorded as run, in order.
|
|
19
|
+
export function* askPendingMigrations() {
|
|
20
|
+
const allMigrations = yield* askAllMigrations();
|
|
21
|
+
const pending = [];
|
|
22
|
+
for (const migration of allMigrations) {
|
|
23
|
+
if (yield* askIsMigrationPending(migration)) {
|
|
24
|
+
pending.push(migration);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return pending;
|
|
28
|
+
}
|
|
29
|
+
// Record a migration as run, so neither the deploy path nor the local runner picks it up again.
|
|
30
|
+
export function* askRecordMigrationRan(migration) {
|
|
31
|
+
yield* migrationInfoData.askUpsert({
|
|
32
|
+
deployType: migration.deployType,
|
|
33
|
+
srcPath: getMigrationKey(migration),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=pendingMigrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pendingMigrations.js","sourceRoot":"","sources":["../../../../../src/services/migration/logic/pendingMigrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAe,MAAM,iBAAiB,CAAC;AAElE,OAAO,EAAE,8CAA8C,EAAa,MAAM,oCAAoC,CAAC;AAC/G,OAAO,KAAK,iBAAiB,MAAM,2BAA2B,CAAC;AAE/D,oFAAoF;AACpF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,SAAoB,EAAU,EAAE,CAAC,8CAA8C,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;AAEnI,2FAA2F;AAC3F,2FAA2F;AAC3F,2DAA2D;AAC3D,MAAM,SAAS,CAAC,CAAC,qBAAqB,CAAC,SAAoB;IACzD,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,iBAAiB,CAAC,wBAAwB,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC;IAEpG,OAAO,CAAC,aAAa,CAAC;AACxB,CAAC;AAED,6FAA6F;AAC7F,8EAA8E;AAC9E,MAAM,SAAS,CAAC,CAAC,gBAAgB;IAC/B,OAAO,KAAK,CAAC,CAAC,kBAAkB,CAAc,eAAe,CAAC,CAAC;AACjE,CAAC;AAED,8CAA8C;AAC9C,MAAM,SAAS,CAAC,CAAC,oBAAoB;IACnC,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,gBAAgB,EAAE,CAAC;IAEhD,MAAM,OAAO,GAAgB,EAAE,CAAC;IAEhC,KAAK,MAAM,SAAS,IAAI,aAAa,EAAE,CAAC;QACtC,IAAI,KAAK,CAAC,CAAC,qBAAqB,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5C,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,gGAAgG;AAChG,MAAM,SAAS,CAAC,CAAC,qBAAqB,CAAC,SAAoB;IACzD,KAAK,CAAC,CAAC,iBAAiB,CAAC,SAAS,CAAC;QACjC,UAAU,EAAE,SAAS,CAAC,UAAU;QAChC,OAAO,EAAE,eAAe,CAAC,SAAS,CAAC;KACpC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { askConfigGetGlobal, AskResponse } from 'quidproquo-core';\n\nimport { getQpqMigrationQueueTypeFromQpqFunctionRuntime, Migration } from '../../../config/settings/migration';\nimport * as migrationInfoData from '../data/migrationInfoData';\n\n// A migration is identified by its source path, which is also its queue event type.\nexport const getMigrationKey = (migration: Migration): string => getQpqMigrationQueueTypeFromQpqFunctionRuntime(migration.runtime);\n\n// Has this migration already been recorded as run? Shared by the deploy path and the local\n// runner so the two can never disagree about what \"pending\" means — a runner that answered\n// differently would either re-run a migration or skip one.\nexport function* askIsMigrationPending(migration: Migration): AskResponse<boolean> {\n const migrationInfo = yield* migrationInfoData.askGetMigrationBySrcPath(getMigrationKey(migration));\n\n return !migrationInfo;\n}\n\n// Every configured migration, in declaration order (the config preserves the sorted filename\n// order the app registered them in, so dependencies between migrations hold).\nexport function* askAllMigrations(): AskResponse<Migration[]> {\n return yield* askConfigGetGlobal<Migration[]>('qpqMigrations');\n}\n\n// The ones not yet recorded as run, in order.\nexport function* askPendingMigrations(): AskResponse<Migration[]> {\n const allMigrations = yield* askAllMigrations();\n\n const pending: Migration[] = [];\n\n for (const migration of allMigrations) {\n if (yield* askIsMigrationPending(migration)) {\n pending.push(migration);\n }\n }\n\n return pending;\n}\n\n// Record a migration as run, so neither the deploy path nor the local runner picks it up again.\nexport function* askRecordMigrationRan(migration: Migration): AskResponse<void> {\n yield* migrationInfoData.askUpsert({\n deployType: migration.deployType,\n srcPath: getMigrationKey(migration),\n });\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "quidproquo-webserver",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./lib/commonjs/index.js",
|
|
6
6
|
"module": "./lib/esm/index.js",
|
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
"homepage": "https://github.com/joe-coady/quidproquo#readme",
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@anthropic-ai/sdk": "^0.19.1",
|
|
36
|
-
"quidproquo-core": "0.1.
|
|
36
|
+
"quidproquo-core": "0.1.13"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"quidproquo-tsconfig": "0.1.
|
|
39
|
+
"quidproquo-tsconfig": "0.1.13",
|
|
40
40
|
"typescript": "^5.8.2"
|
|
41
41
|
}
|
|
42
42
|
}
|