wirejs-deploy-amplify-basic 0.1.170 → 0.1.171
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/amplify-backend-assets/api/handler.ts +25 -0
- package/amplify-backend-assets/backend.ts +47 -0
- package/amplify-hosting-assets/compute/default/package.json +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -0
- package/dist/resources/cron-job.d.ts +30 -0
- package/dist/resources/cron-job.js +32 -0
- package/package.json +2 -2
|
@@ -2,6 +2,7 @@ import { env } from 'process';
|
|
|
2
2
|
import { LambdaFunctionURLHandler, APIGatewayProxyEventV2 } from 'aws-lambda';
|
|
3
3
|
import {
|
|
4
4
|
BackgroundJob,
|
|
5
|
+
CronJob,
|
|
5
6
|
CookieJar,
|
|
6
7
|
Context,
|
|
7
8
|
Endpoint,
|
|
@@ -144,6 +145,30 @@ function byPathLength(a: Endpoint, b: Endpoint) {
|
|
|
144
145
|
}
|
|
145
146
|
|
|
146
147
|
export const handler: LambdaFunctionURLHandler = async (event) => {
|
|
148
|
+
// Handle EventBridge-scheduled CronJob invocations.
|
|
149
|
+
// EventBridge events have a 'source' field; Lambda Function URL events do not.
|
|
150
|
+
if ((event as any).source === 'wirejs-cron') {
|
|
151
|
+
const cronEvent = event as any;
|
|
152
|
+
const absoluteId: string | undefined = cronEvent['wirejs-cron-id'];
|
|
153
|
+
|
|
154
|
+
if (!absoluteId) {
|
|
155
|
+
console.error('Missing wirejs-cron-id in scheduled event');
|
|
156
|
+
return { statusCode: 400, body: JSON.stringify({ error: 'Missing wirejs-cron-id' }) };
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
console.log('handling scheduled cron job', absoluteId);
|
|
160
|
+
|
|
161
|
+
const entry = (CronJob as any).registeredJobs.get(absoluteId);
|
|
162
|
+
if (!entry || typeof entry.handler !== 'function') {
|
|
163
|
+
console.error('CronJob not found', absoluteId, [...(CronJob as any).registeredJobs.keys()]);
|
|
164
|
+
return { statusCode: 404, body: JSON.stringify({ error: 'CronJob not found' }) };
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
await entry.handler();
|
|
168
|
+
|
|
169
|
+
return { statusCode: 200, body: JSON.stringify({ message: 'CronJob complete' }) };
|
|
170
|
+
}
|
|
171
|
+
|
|
147
172
|
const calls = event.body ? JSON.parse(event.body) : undefined;
|
|
148
173
|
const wjsContext = createContext(event);
|
|
149
174
|
const path = wjsContext?.location.pathname;
|
|
@@ -14,6 +14,8 @@ import { NodejsFunction, OutputFormat } from 'aws-cdk-lib/aws-lambda-nodejs';
|
|
|
14
14
|
import { Bucket, BlockPublicAccess } from 'aws-cdk-lib/aws-s3';
|
|
15
15
|
import { Table, AttributeType, BillingMode } from 'aws-cdk-lib/aws-dynamodb';
|
|
16
16
|
import { AnyPrincipal, PolicyStatement } from 'aws-cdk-lib/aws-iam';
|
|
17
|
+
import { Rule, RuleTargetInput, Schedule } from 'aws-cdk-lib/aws-events';
|
|
18
|
+
import { LambdaFunction as LambdaFunctionTarget } from 'aws-cdk-lib/aws-events-targets';
|
|
17
19
|
|
|
18
20
|
import { TableDefinition, indexName, DeploymentConfig } from 'wirejs-resources';
|
|
19
21
|
import { TableIndexes } from './constructs/table-indexes';
|
|
@@ -224,6 +226,51 @@ for (const resource of generated) {
|
|
|
224
226
|
}
|
|
225
227
|
|
|
226
228
|
|
|
229
|
+
/**
|
|
230
|
+
* Converts a standard 5-field cron expression to an AWS EventBridge Schedule.
|
|
231
|
+
*
|
|
232
|
+
* Standard cron: "minute hour day-of-month month day-of-week"
|
|
233
|
+
* EventBridge cron: "minute hour day-of-month month day-of-week year"
|
|
234
|
+
* EventBridge additionally requires that day-of-month and day-of-week cannot
|
|
235
|
+
* both be specified at the same time (one must be `?`).
|
|
236
|
+
*/
|
|
237
|
+
function cronExpressionToSchedule(expression: string): Schedule {
|
|
238
|
+
const [minute, hour, dayOfMonth, month, dayOfWeek] = expression.trim().split(/\s+/);
|
|
239
|
+
// EventBridge requires exactly one of day-of-month or day-of-week to be '?'.
|
|
240
|
+
// If neither is wildcarded, prefer keeping day-of-month and set weekday to '?'.
|
|
241
|
+
const ebDayOfMonth = dayOfWeek !== '*' && dayOfWeek !== '?' ? '?' : dayOfMonth;
|
|
242
|
+
const ebDayOfWeek = ebDayOfMonth === '?' ? dayOfWeek : '?';
|
|
243
|
+
return Schedule.cron({ minute, hour, day: ebDayOfMonth, month, weekDay: ebDayOfWeek });
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* EventBridge rules for CronJobs
|
|
248
|
+
*/
|
|
249
|
+
function isCronJob(resource: any): resource is {
|
|
250
|
+
type: 'CronJob';
|
|
251
|
+
options: { absoluteId: string; schedule: string };
|
|
252
|
+
} {
|
|
253
|
+
return resource.type === 'CronJob';
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
for (const resource of generated) {
|
|
257
|
+
if (isCronJob(resource)) {
|
|
258
|
+
const sanitizedId = resource.options.absoluteId.replace(/[^a-zA-Z0-9-_]/g, '_');
|
|
259
|
+
new Rule(backend.stack, `CronJob_${sanitizedId}`, {
|
|
260
|
+
schedule: cronExpressionToSchedule(resource.options.schedule),
|
|
261
|
+
targets: [
|
|
262
|
+
new LambdaFunctionTarget(api, {
|
|
263
|
+
event: RuleTargetInput.fromObject({
|
|
264
|
+
source: 'wirejs-cron',
|
|
265
|
+
'wirejs-cron-id': resource.options.absoluteId,
|
|
266
|
+
}),
|
|
267
|
+
}),
|
|
268
|
+
],
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
|
|
227
274
|
/**
|
|
228
275
|
* Lambda environment vars
|
|
229
276
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -5,4 +5,5 @@ export { LLM } from './services/llm.js';
|
|
|
5
5
|
export { DistributedTable } from './resources/distributed-table.js';
|
|
6
6
|
export { RealtimeService } from './services/realtime.js';
|
|
7
7
|
export { BackgroundJob } from './resources/background-job.js';
|
|
8
|
+
export { CronJob } from './resources/cron-job.js';
|
|
8
9
|
export { Endpoint } from './resources/endpoint.js';
|
package/dist/index.js
CHANGED
|
@@ -14,11 +14,14 @@ import { RealtimeService } from './services/realtime.js';
|
|
|
14
14
|
export { RealtimeService } from './services/realtime.js';
|
|
15
15
|
import { BackgroundJob } from './resources/background-job.js';
|
|
16
16
|
export { BackgroundJob } from './resources/background-job.js';
|
|
17
|
+
import { CronJob } from './resources/cron-job.js';
|
|
18
|
+
export { CronJob } from './resources/cron-job.js';
|
|
17
19
|
import { Endpoint } from './resources/endpoint.js';
|
|
18
20
|
export { Endpoint } from './resources/endpoint.js';
|
|
19
21
|
// expose resources to other resources that might depend on it.
|
|
20
22
|
overrides.AuthenticationService = AuthenticationService;
|
|
21
23
|
overrides.BackgroundJob = BackgroundJob;
|
|
24
|
+
overrides.CronJob = CronJob;
|
|
22
25
|
overrides.DistributedTable = DistributedTable;
|
|
23
26
|
overrides.Endpoint = Endpoint;
|
|
24
27
|
overrides.FileService = FileService;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Resource, CronJob as BaseCronJob } from 'wirejs-resources';
|
|
2
|
+
export type CronJobDefinition = {
|
|
3
|
+
absoluteId: string;
|
|
4
|
+
schedule: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* A function that will be executed on a recurring schedule defined by a cron expression.
|
|
8
|
+
*
|
|
9
|
+
* In AWS deployments, the schedule is managed by Amazon EventBridge.
|
|
10
|
+
*
|
|
11
|
+
* A `CronJob` can also invoke an existing BackgroundJob from its handler.
|
|
12
|
+
*
|
|
13
|
+
* ## WARNINGS
|
|
14
|
+
*
|
|
15
|
+
* 1. These jobs execute in a completely different environment that the one that defines it.
|
|
16
|
+
* DO NOT depend on global variables, closures, or other process state that is not lazily
|
|
17
|
+
* created or constructed in-place by the script.
|
|
18
|
+
* 2. In local development, **timeouts are not enforced.** (Yet.)
|
|
19
|
+
*/
|
|
20
|
+
export declare class CronJob extends Resource implements Omit<BaseCronJob, '#private'> {
|
|
21
|
+
static registeredJobs: Map<string, {
|
|
22
|
+
schedule: string;
|
|
23
|
+
handler: () => Promise<void>;
|
|
24
|
+
}>;
|
|
25
|
+
readonly schedule: string;
|
|
26
|
+
constructor(scope: Resource | string, id: string, options: {
|
|
27
|
+
schedule: string;
|
|
28
|
+
handler: () => Promise<void>;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Resource, } from 'wirejs-resources';
|
|
2
|
+
import { addResource } from '../resource-collector.js';
|
|
3
|
+
/**
|
|
4
|
+
* A function that will be executed on a recurring schedule defined by a cron expression.
|
|
5
|
+
*
|
|
6
|
+
* In AWS deployments, the schedule is managed by Amazon EventBridge.
|
|
7
|
+
*
|
|
8
|
+
* A `CronJob` can also invoke an existing BackgroundJob from its handler.
|
|
9
|
+
*
|
|
10
|
+
* ## WARNINGS
|
|
11
|
+
*
|
|
12
|
+
* 1. These jobs execute in a completely different environment that the one that defines it.
|
|
13
|
+
* DO NOT depend on global variables, closures, or other process state that is not lazily
|
|
14
|
+
* created or constructed in-place by the script.
|
|
15
|
+
* 2. In local development, **timeouts are not enforced.** (Yet.)
|
|
16
|
+
*/
|
|
17
|
+
export class CronJob extends Resource {
|
|
18
|
+
static registeredJobs = new Map();
|
|
19
|
+
schedule;
|
|
20
|
+
constructor(scope, id, options) {
|
|
21
|
+
super(scope, id);
|
|
22
|
+
this.schedule = options.schedule;
|
|
23
|
+
addResource('CronJob', {
|
|
24
|
+
absoluteId: this.absoluteId,
|
|
25
|
+
schedule: options.schedule,
|
|
26
|
+
});
|
|
27
|
+
CronJob.registeredJobs.set(this.absoluteId, {
|
|
28
|
+
schedule: options.schedule,
|
|
29
|
+
handler: options.handler,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wirejs-deploy-amplify-basic",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.171",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"recursive-copy": "^2.0.14",
|
|
45
45
|
"rimraf": "^6.0.1",
|
|
46
46
|
"wirejs-dom": "^1.0.44",
|
|
47
|
-
"wirejs-resources": "^0.1.
|
|
47
|
+
"wirejs-resources": "^0.1.171"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@aws-amplify/backend": "^1.14.0",
|