From 083f995550ba92b06473e5206be701686f73f105 Mon Sep 17 00:00:00 2001 From: Uri Bar <106860404+staycoolcall911@users.noreply.github.com> Date: Wed, 3 Apr 2024 13:31:54 +0300 Subject: [PATCH 01/16] fix(sdk): revert lift/permissions errors are not caught in simulator (#6125) Reverts winglang/wing#6079 due to a bug with hot-reloading in wing console. To reproduce: ```ts // main.w bring cloud; let api = new cloud.Api(); class Code { extern "search.js" inflight pub static handler(event: Json, ctx:Json): Json; } api.get("/search", inflight (req) => { return { status: 200, body: "Hello " }; let event = MutJson {}; let ctx = MutJson {}; let result = Code.handler(event, ctx); return { }; }); ``` ```js //search.js export const handler = async (event, ctx) => { event.success = true; return { status: 200, body: JSON.stringify(event), } }; ``` --- .../04-standard-library/sim/api-reference.md | 224 +--- .../invalid/simulator_permissions.test.w | 26 - .../tests/sdk_tests/service/callbacks.test.w | 2 +- libs/wingsdk/src/cloud/bucket.ts | 2 +- libs/wingsdk/src/shared/sandbox.ts | 4 +- libs/wingsdk/src/simulator/client.ts | 16 +- libs/wingsdk/src/simulator/simulator.ts | 178 +-- libs/wingsdk/src/simulator/util.ts | 19 - libs/wingsdk/src/target-sim/api.inflight.ts | 15 +- libs/wingsdk/src/target-sim/api.ts | 6 +- libs/wingsdk/src/target-sim/app.ts | 17 +- .../wingsdk/src/target-sim/bucket.inflight.ts | 20 +- libs/wingsdk/src/target-sim/bucket.ts | 47 +- .../src/target-sim/container.inflight.ts | 32 +- libs/wingsdk/src/target-sim/container.ts | 2 +- .../src/target-sim/counter.inflight.ts | 18 +- libs/wingsdk/src/target-sim/counter.ts | 2 +- .../wingsdk/src/target-sim/domain.inflight.ts | 4 +- .../src/target-sim/endpoint.inflight.ts | 26 +- .../src/target-sim/event-mapping.inflight.ts | 33 +- libs/wingsdk/src/target-sim/event-mapping.ts | 8 +- .../src/target-sim/function.inflight.ts | 33 +- libs/wingsdk/src/target-sim/function.ts | 27 +- libs/wingsdk/src/target-sim/index.ts | 1 - .../src/target-sim/on-deploy.inflight.ts | 19 +- libs/wingsdk/src/target-sim/on-deploy.ts | 4 +- .../wingsdk/src/target-sim/policy.inflight.ts | 22 - libs/wingsdk/src/target-sim/policy.ts | 72 -- libs/wingsdk/src/target-sim/queue.inflight.ts | 21 +- libs/wingsdk/src/target-sim/queue.ts | 17 +- .../src/target-sim/react-app.inflight.ts | 15 +- libs/wingsdk/src/target-sim/react-app.ts | 2 +- libs/wingsdk/src/target-sim/redis.inflight.ts | 7 +- libs/wingsdk/src/target-sim/redis.ts | 2 +- libs/wingsdk/src/target-sim/resource.ts | 26 +- .../src/target-sim/schedule.inflight.ts | 15 +- libs/wingsdk/src/target-sim/schedule.ts | 6 +- .../src/target-sim/schema-resources.ts | 57 +- .../wingsdk/src/target-sim/secret.inflight.ts | 16 +- libs/wingsdk/src/target-sim/secret.ts | 2 +- .../src/target-sim/service.inflight.ts | 86 +- libs/wingsdk/src/target-sim/service.ts | 81 +- libs/wingsdk/src/target-sim/state.inflight.ts | 17 +- libs/wingsdk/src/target-sim/state.ts | 2 +- libs/wingsdk/src/target-sim/table.inflight.ts | 15 +- libs/wingsdk/src/target-sim/table.ts | 2 +- .../src/target-sim/test-runner.inflight.ts | 20 +- libs/wingsdk/src/target-sim/test-runner.ts | 2 +- libs/wingsdk/src/target-sim/topic.inflight.ts | 19 +- libs/wingsdk/src/target-sim/topic.ts | 7 +- libs/wingsdk/src/target-sim/util.ts | 19 +- .../src/target-sim/website.inflight.ts | 16 +- libs/wingsdk/src/target-sim/website.ts | 2 +- libs/wingsdk/src/util/enhanced-error.ts | 3 +- .../__snapshots__/connections.test.ts.snap | 58 - libs/wingsdk/test/simulator/cleanup.test.ts | 6 +- libs/wingsdk/test/simulator/on-trace.test.ts | 2 +- libs/wingsdk/test/simulator/simulator.test.ts | 190 +-- .../target-sim/__snapshots__/api.test.ts.snap | 1064 +---------------- .../__snapshots__/bucket.test.ts.snap | 197 +-- .../__snapshots__/counter.test.ts.snap | 56 - .../__snapshots__/file-counter.test.ts.snap | 111 +- .../__snapshots__/function.test.ts.snap | 292 +---- .../immutable-capture.test.ts.snap | 462 ------- .../__snapshots__/on-deploy.test.ts.snap | 36 - .../__snapshots__/queue.test.ts.snap | 270 +---- .../__snapshots__/redis.test.ts.snap | 8 - .../__snapshots__/schedule.test.ts.snap | 216 ---- .../__snapshots__/secret.test.ts.snap | 8 - .../__snapshots__/service.test.ts.snap | 59 +- .../__snapshots__/table.test.ts.snap | 56 - .../__snapshots__/test.test.ts.snap | 33 - .../__snapshots__/topic-producer.test.ts.snap | 11 +- .../__snapshots__/topic.test.ts.snap | 33 - libs/wingsdk/test/target-sim/app.test.ts | 9 +- libs/wingsdk/test/target-sim/bucket.test.ts | 16 +- libs/wingsdk/test/target-sim/function.test.ts | 18 +- .../wingsdk/test/target-sim/on-deploy.test.ts | 2 +- libs/wingsdk/test/target-sim/queue.test.ts | 2 +- libs/wingsdk/test/target-sim/service.test.ts | 5 +- .../test/target-sim/topic-producer.test.ts | 7 +- libs/wingsdk/test/target-sim/util.ts | 2 +- .../test/ui/__snapshots__/ui.test.ts.snap | 4 - tools/hangar/__snapshots__/invalid.ts.snap | 26 - 84 files changed, 301 insertions(+), 4314 deletions(-) delete mode 100644 examples/tests/invalid/simulator_permissions.test.w delete mode 100644 libs/wingsdk/src/simulator/util.ts delete mode 100644 libs/wingsdk/src/target-sim/policy.inflight.ts delete mode 100644 libs/wingsdk/src/target-sim/policy.ts diff --git a/docs/docs/04-standard-library/sim/api-reference.md b/docs/docs/04-standard-library/sim/api-reference.md index 6749af2595a..0ecb35cda5c 100644 --- a/docs/docs/04-standard-library/sim/api-reference.md +++ b/docs/docs/04-standard-library/sim/api-reference.md @@ -126,126 +126,6 @@ A token that resolves to the host port of this container. --- -### Policy - -- *Implements:* ISimulatorResource - -Implementation of `sim.Policy`. - -#### Initializers - -```wing -bring sim; - -new sim.Policy(props: PolicyProps); -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| props | PolicyProps | *No description.* | - ---- - -##### `props`Required - -- *Type:* PolicyProps - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| addStatement | Adds a statement to the policy. | -| toSimulator | Convert this resource to a resource schema for the simulator. | - ---- - -##### `addStatement` - -```wing -addStatement(resource: IResource, op: str): void -``` - -Adds a statement to the policy. - -###### `resource`Required - -- *Type:* IResource - ---- - -###### `op`Required - -- *Type:* str - ---- - -##### `toSimulator` - -```wing -toSimulator(): BaseResourceSchema -``` - -Convert this resource to a resource schema for the simulator. - -#### Static Functions - -| **Name** | **Description** | -| --- | --- | -| onLiftType | A hook called by the Wing compiler once for each inflight host that needs to use this type inflight. | - ---- - -##### `onLiftType` - -```wing -bring sim; - -sim.Policy.onLiftType(host: IInflightHost, ops: MutArray); -``` - -A hook called by the Wing compiler once for each inflight host that needs to use this type inflight. - -The list of requested inflight methods -needed by the inflight host are given by `ops`. - -This method is commonly used for adding permissions, environment variables, or -other capabilities to the inflight host. - -###### `host`Required - -- *Type:* IInflightHost - ---- - -###### `ops`Required - -- *Type:* MutArray<str> - ---- - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - - ### State - *Implements:* ISimulatorResource @@ -556,115 +436,15 @@ A glob of local files to consider as input sources for the container, relative t --- -### PolicyProps - -Options for `sim.Policy`. - -#### Initializer - -```wing -bring sim; - -let PolicyProps = sim.PolicyProps{ ... }; -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| principal | IResource | The resource to which the policy is attached. | - ---- - -##### `principal`Required - -```wing -principal: IResource; -``` - -- *Type:* IResource - -The resource to which the policy is attached. - ---- - ## Protocols -### IPolicyClient - -- *Implemented By:* IPolicyClient - -Inflight interface for `Policy`. - - - -### ISimulatorInflightHost - -- *Extends:* IInflightHost - -- *Implemented By:* ISimulatorInflightHost - -Interfaces shared by all preflight classes that host inflight code. - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| addPermission | Add a simulated permission to this inflight host. | - ---- - -##### `addPermission` - -```wing -addPermission(resource: IResource, op: str): void -``` - -Add a simulated permission to this inflight host. - -###### `resource`Required - -- *Type:* IResource - -The resource to add. - ---- - -###### `op`Required - -- *Type:* str - -The action to add. - ---- - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - ### ISimulatorResource - *Extends:* IResource -- *Implemented By:* Container, Policy, State, ISimulatorResource +- *Implemented By:* Container, State, ISimulatorResource -Interfaces shared by all preflight classes targeting the simulator. +Interfaces shared by all polycon implementations (preflight classes) targeting the simulator. #### Methods diff --git a/examples/tests/invalid/simulator_permissions.test.w b/examples/tests/invalid/simulator_permissions.test.w deleted file mode 100644 index 81f3ab9f033..00000000000 --- a/examples/tests/invalid/simulator_permissions.test.w +++ /dev/null @@ -1,26 +0,0 @@ -bring cloud; - -let buckets = [ - new cloud.Bucket() as "b1", - new cloud.Bucket() as "b2" -]; - -test "incorrect resource permission" { - // This test fails because permission is granted to b2, not b1 - lift(buckets.at(1), ["put"]); - let var i = 10; - while i > 0 { - i -= 1; - } - buckets.at(i).put("key", "value"); -} - -test "incorrect permission operation" { - // This test fails because permission is granted for "list", not "put" - lift(buckets.at(0), ["list"]); - let var i = 10; - while i > 0 { - i -= 1; - } - buckets.at(i).put("key", "value"); -} diff --git a/examples/tests/sdk_tests/service/callbacks.test.w b/examples/tests/sdk_tests/service/callbacks.test.w index 1f35b77da80..3ed3b962a62 100644 --- a/examples/tests/sdk_tests/service/callbacks.test.w +++ b/examples/tests/sdk_tests/service/callbacks.test.w @@ -50,4 +50,4 @@ if util.env("WING_TARGET") == "sim" { assert(startCounter.peek() == 0); assert(b.get(status) == stopped); } -} +} \ No newline at end of file diff --git a/libs/wingsdk/src/cloud/bucket.ts b/libs/wingsdk/src/cloud/bucket.ts index dae03e3c800..e35992a38e4 100644 --- a/libs/wingsdk/src/cloud/bucket.ts +++ b/libs/wingsdk/src/cloud/bucket.ts @@ -107,7 +107,7 @@ export class Bucket extends Resource { * Gets topic form the topics map, or creates if not exists * @param actionType */ - protected getTopic(actionType: BucketEventType): Topic { + private getTopic(actionType: BucketEventType): Topic { if (!this._topics.has(actionType)) { this._topics.set(actionType, this.createTopic(actionType)); } diff --git a/libs/wingsdk/src/shared/sandbox.ts b/libs/wingsdk/src/shared/sandbox.ts index e892f584430..0fe362f3195 100644 --- a/libs/wingsdk/src/shared/sandbox.ts +++ b/libs/wingsdk/src/shared/sandbox.ts @@ -222,14 +222,14 @@ process.on("message", async (message) => { // "exit" could be emitted if the user code called process.exit(), or if we killed the process // due to a timeout or unexpected error. In any case, we reject the promise. - this.onChildExit = (code: number | null, signal: unknown) => { + this.onChildExit = (code: number | null) => { this.debugLog("Child processed stopped."); this.child = undefined; this.available = true; if (this.timeout) { clearTimeout(this.timeout); } - reject(new Error(`Process exited with code ${code}, signal ${signal}`)); + reject(new Error(`Process exited with code ${code}`)); }; if (this.options.timeout) { diff --git a/libs/wingsdk/src/simulator/client.ts b/libs/wingsdk/src/simulator/client.ts index 9b223330fbd..a46262b7f05 100644 --- a/libs/wingsdk/src/simulator/client.ts +++ b/libs/wingsdk/src/simulator/client.ts @@ -35,19 +35,7 @@ function makeHttpRequest(options: HttpRequestOptions): Promise { }); } -/** - * Creates a proxy object that forwards method calls to the simulator server. - * - * @param url The URL of the simulator server - * @param handle The handle for the resource we're calling methods on or getting properties from - * @param caller The handle of the resource that is making the calls - * @returns A proxy object that forwards calls to the simulator server - */ -export function makeSimulatorClient( - url: string, - handle: string, - caller: string -) { +export function makeSimulatorClient(url: string, handle: string) { let proxy: any; let hasThenMethod = true; // assume that the object has a "then" method until proven otherwise @@ -57,7 +45,7 @@ export function makeSimulatorClient( } return async function (...args: any[]) { - const body: SimulatorServerRequest = { caller, handle, method, args }; + const body: SimulatorServerRequest = { handle, method, args }; const parsedUrl = new URL(url); const resp = await makeHttpRequest({ hostname: parsedUrl.hostname, diff --git a/libs/wingsdk/src/simulator/simulator.ts b/libs/wingsdk/src/simulator/simulator.ts index f445875160e..bb63842446b 100644 --- a/libs/wingsdk/src/simulator/simulator.ts +++ b/libs/wingsdk/src/simulator/simulator.ts @@ -7,23 +7,14 @@ import { Graph } from "./graph"; import { deserialize, serialize } from "./serialization"; import { resolveTokens } from "./tokens"; import { Tree } from "./tree"; -import { exists } from "./util"; import { SDK_VERSION } from "../constants"; import { TREE_FILE_PATH } from "../core"; import { readJsonSync } from "../shared/misc"; import { CONNECTIONS_FILE_PATH, Trace, TraceType } from "../std"; -import { POLICY_FQN } from "../target-sim"; -import { PolicySchemaProps } from "../target-sim/schema-resources"; const LOCALHOST_ADDRESS = "127.0.0.1"; const HANDLE_ATTRIBUTE = "handle"; -/** - * If an API call is made to a resource with name as the caller, any permissions - * checking will be skipped. Used by unit tests and the Wing Console. - */ -const ADMIN_PERMISSION = "admin"; - /** * Props for `Simulator`. */ @@ -102,11 +93,6 @@ export interface ISimulatorContext { */ readonly resourcePath: string; - /** - * The handle of the resource that is being simulated. - */ - readonly resourceHandle: string; - /** * The url that the simulator server is listening on. */ @@ -115,7 +101,7 @@ export interface ISimulatorContext { /** * Obtain a client given a resource's handle. */ - getClient(handle: string, asAdmin?: boolean): unknown; + getClient(handle: string): unknown; /** * Add a trace. Traces are breadcrumbs of information about resource @@ -200,7 +186,6 @@ export class Simulator { private _serverUrl: string | undefined; private _server: Server | undefined; private _model: Model; - private _policyRegistry: PolicyRegistry; // keeps the actual resolved state (props and attrs) of all started resources. this state is // merged in when calling `getResourceConfig()`. @@ -213,7 +198,6 @@ export class Simulator { this._running = "stopped"; this._handles = new HandleManager(); - this._policyRegistry = new PolicyRegistry(); this._traces = new Array(); this._traceSubscribers = new Array(); } @@ -396,19 +380,13 @@ export class Simulator { try { const resource = this._handles.find(handle); - await this.ensureStateDirExists(path); await resource.save(this.getResourceStateDir(path)); - await resource.cleanup(); this._handles.deallocate(handle); + await resource.cleanup(); } catch (err) { console.warn(err); } - // if the resource is a policy, remove it from the policy registry - if (this.getResourceConfig(path).type === POLICY_FQN) { - this._policyRegistry.deregister(path); - } - this.addSimulatorTrace(path, { message: `${path} stopped` }); delete this.state[path]; // delete the state of the resource } @@ -475,7 +453,8 @@ export class Simulator { if (!handle) { return undefined; } - return makeSimulatorClient(this.url, handle, ADMIN_PERMISSION); + + return makeSimulatorClient(this.url, handle); } private tryGetResourceHandle(path: string): string | undefined { @@ -530,14 +509,6 @@ export class Simulator { return join(this.statedir, config.addr); } - private async ensureStateDirExists(path: string) { - const statedir = this.getResourceStateDir(path); - const statedirExists = await exists(statedir); - if (!statedirExists) { - await mkdir(statedir, { recursive: true }); - } - } - /** * Obtain a resource's visual interaction components. * @returns An array of UIComponent objects @@ -580,43 +551,6 @@ export class Simulator { return structuredClone(this._model.connections); } - private checkPermission( - callerHandle: string, - calleeHandle: string, - method: string - ): { granted: boolean; reason?: string } { - if (callerHandle === ADMIN_PERMISSION) { - return { granted: true }; - } - - const callerPath = this._handles.tryFindPath(callerHandle); - if (!callerPath) { - return { - granted: false, - reason: `(Permission checking) No caller resource with handle "${callerHandle}" found.`, - }; - } - - const calleePath = this._handles.tryFindPath(calleeHandle); - if (!calleePath) { - return { - granted: false, - reason: `(Permission checking) No callee resource with handle "${calleeHandle}" found.`, - }; - } - - if ( - this._policyRegistry.checkPermission(callerHandle, calleeHandle, method) - ) { - return { granted: true }; - } - - return { - granted: false, - reason: `Resource "${callerPath}" does not have permission to perform operation "${method}" on resource "${calleePath}".`, - }; - } - /** * Start a server that allows any resource to be accessed via HTTP. */ @@ -634,24 +568,9 @@ export class Simulator { }); req.on("end", () => { const request: SimulatorServerRequest = deserialize(body); - const { caller, handle, method, args } = request; + const { handle, method, args } = request; const resource = this._handles.tryFind(handle); - // Check if the caller has permission to call the method on the resource - const grant = this.checkPermission(caller, handle, method); - if (!grant.granted) { - res.writeHead(403, { "Content-Type": "application/json" }); - res.end( - serialize({ - error: { - message: grant.reason, - }, - }), - "utf-8" - ); - return; - } - // If we weren't able to find a resource with the given handle, it could actually // be OK if the resource is still starting up or has already been cleaned up. // In that case, we return a 500 error with a message that explains what happened. @@ -771,6 +690,7 @@ export class Simulator { } const resourceConfig = this.getResourceConfig(path); + const context = this.createContext(resourceConfig); const resolvedProps = this.resolveTokens(resourceConfig.props); @@ -791,18 +711,15 @@ export class Simulator { // create the resource based on its type // eslint-disable-next-line @typescript-eslint/no-require-imports const ResourceType = require(typeInfo.sourcePath)[typeInfo.className]; - const resourceObject = new ResourceType(resolvedProps); - - // allocate a handle for the resource so others can find it - const handle = this._handles.allocate(path, resourceObject); - - // initialize the resource with the simulator context - const context = this.createContext(resourceConfig, handle); - const attrs = await resourceObject.init(context); + const resourceObject = new ResourceType(resolvedProps, context); + const attrs = await resourceObject.init(); // save the current state await resourceObject.save(); + // allocate a handle for the resource so others can find it + const handle = this._handles.allocate(resourceObject); + // merge the attributes this.state[path].attrs = { ...this.state[path].attrs, @@ -814,27 +731,16 @@ export class Simulator { this.addSimulatorTrace(path, { message: `${resourceConfig.path} started`, }); - - // if the resource is a policy, add it to the policy registry - if (resourceConfig.type === POLICY_FQN) { - const policyProps = resolvedProps as PolicySchemaProps; - this._policyRegistry.register(resourceConfig.path, policyProps); - } } - private createContext( - resourceConfig: BaseResourceSchema, - resourceHandle: string - ): ISimulatorContext { + private createContext(resourceConfig: BaseResourceSchema): ISimulatorContext { return { simdir: this._model.simdir, statedir: join(this.statedir, resourceConfig.addr), resourcePath: resourceConfig.path, - resourceHandle: resourceHandle, serverUrl: this.url, - getClient: (calleeHandle: string, asAdmin: boolean) => { - const callerHandle = asAdmin ? ADMIN_PERMISSION : resourceHandle; - return makeSimulatorClient(this.url, calleeHandle, callerHandle); + getClient: (handle: string) => { + return makeSimulatorClient(this.url, handle); }, addTrace: (trace: Trace) => { this.addTrace(trace); @@ -1038,19 +944,16 @@ export interface ISimulatorFactory { class HandleManager { private readonly handles: Map; - private readonly paths: Map; // handle -> path private nextHandle: number; public constructor() { this.handles = new Map(); - this.paths = new Map(); this.nextHandle = 0; } - public allocate(path: string, resource: ISimulatorResourceInstance): string { + public allocate(resource: ISimulatorResourceInstance): string { const handle = `sim-${this.nextHandle++}`; this.handles.set(handle, resource); - this.paths.set(handle, path); return handle; } @@ -1066,23 +969,17 @@ class HandleManager { return this.handles.get(handle); } - public tryFindPath(handle: string): string | undefined { - return this.paths.get(handle); - } - public deallocate(handle: string): ISimulatorResourceInstance { const instance = this.handles.get(handle); if (!instance) { throw new Error(`No resource found with handle "${handle}".`); } this.handles.delete(handle); - this.paths.delete(handle); return instance; } public reset(): void { this.handles.clear(); - this.paths.clear(); this.nextHandle = 0; } } @@ -1095,7 +992,7 @@ export interface ISimulatorResourceInstance { * Perform any async initialization required by the resource. Return a map of * the resource's runtime attributes. */ - init(ctx: ISimulatorContext): Promise>; + init(): Promise>; /** * Stop the resource and clean up any physical resources it may have created @@ -1194,9 +1091,7 @@ export interface ConnectionData { * Subject to breaking changes. */ export interface SimulatorServerRequest { - /** The handle of the resource making the request. */ - readonly caller: string; - /** The target resource handle (an ID unique among resources in the simulation). */ + /** The resource handle (an ID unique among resources in the simulation). */ readonly handle: string; /** The method to call on the resource. */ readonly method: string; @@ -1214,42 +1109,3 @@ export interface SimulatorServerResponse { /** The error that occurred during the method call. */ readonly error?: any; } - -class PolicyRegistry { - private readonly policies: Record; - - constructor() { - this.policies = {}; - } - - public register(id: string, policy: PolicySchemaProps) { - if (this.policies[id]) { - throw new Error(`Policy with id ${id} already registered.`); - } - this.policies[id] = policy; - } - - public deregister(id: string) { - delete this.policies[id]; - } - - public checkPermission( - caller: string, - callee: string, - method: string - ): boolean { - for (const policy of Object.values(this.policies)) { - if (policy.principal === caller) { - for (const statement of policy.statements) { - if ( - statement.resourceHandle === callee && - statement.operation === method - ) { - return true; - } - } - } - } - return false; - } -} diff --git a/libs/wingsdk/src/simulator/util.ts b/libs/wingsdk/src/simulator/util.ts deleted file mode 100644 index 16148b3cf1b..00000000000 --- a/libs/wingsdk/src/simulator/util.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { access, constants } from "node:fs"; -import { promisify } from "node:util"; - -/** - * Check if a file exists for an specific path - * @param filePath - * @Returns Return `true` if the file exists, `false` otherwise. - */ -export async function exists(filePath: string): Promise { - try { - await promisify(access)( - filePath, - constants.F_OK | constants.R_OK | constants.W_OK //eslint-disable-line no-bitwise - ); - return true; - } catch (er) { - return false; - } -} diff --git a/libs/wingsdk/src/target-sim/api.inflight.ts b/libs/wingsdk/src/target-sim/api.inflight.ts index 6b837d2de4f..0f32fdb39ac 100644 --- a/libs/wingsdk/src/target-sim/api.inflight.ts +++ b/libs/wingsdk/src/target-sim/api.inflight.ts @@ -50,14 +50,15 @@ export class Api implements IApiClient, ISimulatorResourceInstance, IEventPublisher { private readonly routes: ApiRouteWithFunctionHandle[]; - private _context: ISimulatorContext | undefined; + private readonly context: ISimulatorContext; private readonly app: express.Application; private server: Server | undefined; private url: string | undefined; private port: number | undefined; - constructor(props: ApiSchema["props"]) { + constructor(props: ApiSchema["props"], context: ISimulatorContext) { this.routes = []; + this.context = context; const { corsHeaders } = props; // Set up an express server that handles the routes. @@ -93,15 +94,7 @@ export class Api } } - private get context(): ISimulatorContext { - if (!this._context) { - throw new Error("Cannot access context during class construction"); - } - return this._context; - } - - public async init(context: ISimulatorContext): Promise { - this._context = context; + public async init(): Promise { // Check for a previous state file to see if there was a port that was previously being used // if so, try to use it out of convenience let lastPort: number | undefined; diff --git a/libs/wingsdk/src/target-sim/api.ts b/libs/wingsdk/src/target-sim/api.ts index ea60d2ccd62..5cdb5cddc0d 100644 --- a/libs/wingsdk/src/target-sim/api.ts +++ b/libs/wingsdk/src/target-sim/api.ts @@ -3,7 +3,6 @@ import { Construct } from "constructs"; import { App } from "./app"; import { EventMapping } from "./event-mapping"; import { Function } from "./function"; -import { Policy } from "./policy"; import { ISimulatorResource } from "./resource"; import { ApiSchema, ApiRoute } from "./schema-resources"; import { simulatorAttrToken } from "./tokens"; @@ -25,7 +24,6 @@ export class Api extends cloud.Api implements ISimulatorResource { > = {}; private readonly endpoint: cloud.Endpoint; - private readonly policy: Policy; constructor(scope: Construct, id: string, props: cloud.ApiProps = {}) { super(scope, id, props); @@ -36,7 +34,6 @@ export class Api extends cloud.Api implements ISimulatorResource { simulatorAttrToken(this, "url"), { label: `Api ${this.node.path}` } ); - this.policy = new Policy(this, "Policy", { principal: this }); } protected get _endpoint(): cloud.Endpoint { @@ -119,7 +116,6 @@ export class Api extends cloud.Api implements ISimulatorResource { target: fn, name: `${method.toLowerCase()}()`, }); - this.policy.addStatement(fn, cloud.FunctionInflightMethods.INVOKE); } /** @@ -249,7 +245,7 @@ export class Api extends cloud.Api implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host, ops); + bindSimulatorResource(__filename, this, host); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/app.ts b/libs/wingsdk/src/target-sim/app.ts index 140dddb7454..8595c37bc6a 100644 --- a/libs/wingsdk/src/target-sim/app.ts +++ b/libs/wingsdk/src/target-sim/app.ts @@ -9,14 +9,13 @@ import { Endpoint } from "./endpoint"; import { EVENT_MAPPING_FQN } from "./event-mapping"; import { Function } from "./function"; import { OnDeploy } from "./on-deploy"; -import { POLICY_FQN, Policy } from "./policy"; import { Queue } from "./queue"; import { ReactApp } from "./react-app"; import { Redis } from "./redis"; import { ISimulatorResource, isSimulatorResource } from "./resource"; import { Schedule } from "./schedule"; import { Secret } from "./secret"; -import { SERVICE_HELPER_FQN, Service, ServiceHelper } from "./service"; +import { Service } from "./service"; import { STATE_FQN, State } from "./state"; import { Table } from "./table"; import { TestRunner } from "./test-runner"; @@ -60,14 +59,12 @@ const SIMULATOR_CLASS_DATA = { [EVENT_MAPPING_FQN]: "EventMapping", [FUNCTION_FQN]: "Function", [ON_DEPLOY_FQN]: "OnDeploy", - [POLICY_FQN]: "Policy", [QUEUE_FQN]: "Queue", [REACT_APP_FQN]: "ReactApp", [REDIS_FQN]: "Redis", [SCHEDULE_FQN]: "Schedule", [SECRET_FQN]: "Secret", [SERVICE_FQN]: "Service", - [SERVICE_HELPER_FQN]: "ServiceHelper", [STATE_FQN]: "State", [SIM_CONTAINER_FQN]: "Container", [TABLE_FQN]: "Table", @@ -122,9 +119,6 @@ export class App extends core.App { case ON_DEPLOY_FQN: return require.resolve("./on-deploy.inflight"); - case POLICY_FQN: - return require.resolve("./policy.inflight"); - case QUEUE_FQN: return require.resolve("./queue.inflight"); @@ -143,9 +137,6 @@ export class App extends core.App { case SERVICE_FQN: return require.resolve("./service.inflight"); - case SERVICE_HELPER_FQN: - return require.resolve("./service.inflight"); - case STATE_FQN: return require.resolve("./state.inflight"); @@ -193,9 +184,6 @@ export class App extends core.App { case ON_DEPLOY_FQN: return OnDeploy; - case POLICY_FQN: - return Policy; - case QUEUE_FQN: return Queue; @@ -214,9 +202,6 @@ export class App extends core.App { case SERVICE_FQN: return Service; - case SERVICE_HELPER_FQN: - return ServiceHelper; - case STATE_FQN: return State; diff --git a/libs/wingsdk/src/target-sim/bucket.inflight.ts b/libs/wingsdk/src/target-sim/bucket.inflight.ts index 18cb87ed8f2..f4178e6e50b 100644 --- a/libs/wingsdk/src/target-sim/bucket.inflight.ts +++ b/libs/wingsdk/src/target-sim/bucket.inflight.ts @@ -28,31 +28,23 @@ import { Datetime, Json, TraceType } from "../std"; export const METADATA_FILENAME = "metadata.json"; export class Bucket implements IBucketClient, ISimulatorResourceInstance { - private _fileDir!: string; - private _context: ISimulatorContext | undefined; + private readonly _fileDir: string; + private readonly context: ISimulatorContext; private readonly initialObjects: Record; private readonly _public: boolean; private readonly topicHandlers: Partial>; private _metadata: Map; - public constructor(props: BucketSchema["props"]) { + public constructor(props: BucketSchema["props"], context: ISimulatorContext) { + this._fileDir = join(context.statedir, "files"); + this.context = context; this.initialObjects = props.initialObjects ?? {}; this._public = props.public ?? false; this.topicHandlers = props.topics; this._metadata = new Map(); } - private get context(): ISimulatorContext { - if (!this._context) { - throw new Error("Cannot access context during class construction"); - } - return this._context; - } - - public async init(context: ISimulatorContext): Promise { - this._context = context; - this._fileDir = join(context.statedir, "files"); - + public async init(): Promise { const fileDirExists = await exists(this._fileDir); if (!fileDirExists) { await fs.promises.mkdir(this._fileDir, { recursive: true }); diff --git a/libs/wingsdk/src/target-sim/bucket.ts b/libs/wingsdk/src/target-sim/bucket.ts index 0d263dbfec1..afb13c5573b 100644 --- a/libs/wingsdk/src/target-sim/bucket.ts +++ b/libs/wingsdk/src/target-sim/bucket.ts @@ -1,6 +1,5 @@ import { join } from "path"; import { Construct } from "constructs"; -import { Policy } from "./policy"; import { ISimulatorResource } from "./resource"; import { BucketSchema } from "./schema-resources"; import { simulatorHandleToken } from "./tokens"; @@ -17,13 +16,10 @@ import { IInflightHost } from "../std"; export class Bucket extends cloud.Bucket implements ISimulatorResource { private readonly public: boolean; private readonly initialObjects: Record = {}; - private readonly policy: Policy; - constructor(scope: Construct, id: string, props: cloud.BucketProps = {}) { super(scope, id, props); this.public = props.public ?? false; - this.policy = new Policy(this, "Policy", { principal: this }); } /** @internal */ @@ -45,7 +41,6 @@ export class Bucket extends cloud.Bucket implements ISimulatorResource { cloud.BucketInflightMethods.RENAME, ]; } - /** * Iterates over the topics and supply their sim handler * @returns an object of Bucket event types (keys) and their topic handlers (values) @@ -64,46 +59,6 @@ export class Bucket extends cloud.Bucket implements ISimulatorResource { this.initialObjects[key] = body; } - public onCreate( - fn: cloud.IBucketEventHandler, - opts?: cloud.BucketOnCreateOptions | undefined - ): void { - super.onCreate(fn, opts); - const topic = this.getTopic(cloud.BucketEventType.CREATE); - this.policy.addStatement(topic, cloud.TopicInflightMethods.PUBLISH); - } - - public onDelete( - fn: cloud.IBucketEventHandler, - opts?: cloud.BucketOnDeleteOptions | undefined - ): void { - super.onDelete(fn, opts); - const topic = this.getTopic(cloud.BucketEventType.DELETE); - this.policy.addStatement(topic, cloud.TopicInflightMethods.PUBLISH); - } - - public onUpdate( - fn: cloud.IBucketEventHandler, - opts?: cloud.BucketOnUpdateOptions | undefined - ): void { - super.onUpdate(fn, opts); - const topic = this.getTopic(cloud.BucketEventType.UPDATE); - this.policy.addStatement(topic, cloud.TopicInflightMethods.PUBLISH); - } - - public onEvent( - fn: cloud.IBucketEventHandler, - opts?: cloud.BucketOnEventOptions - ): void { - super.onEvent(fn, opts); - const createTopic = this.getTopic(cloud.BucketEventType.CREATE); - this.policy.addStatement(createTopic, cloud.TopicInflightMethods.PUBLISH); - const deleteTopic = this.getTopic(cloud.BucketEventType.DELETE); - this.policy.addStatement(deleteTopic, cloud.TopicInflightMethods.PUBLISH); - const updateTopic = this.getTopic(cloud.BucketEventType.UPDATE); - this.policy.addStatement(updateTopic, cloud.TopicInflightMethods.PUBLISH); - } - protected eventHandlerLocation(): string { return join(__dirname, "bucket.onevent.inflight.js"); } @@ -124,7 +79,7 @@ export class Bucket extends cloud.Bucket implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host, ops); + bindSimulatorResource(__filename, this, host); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/container.inflight.ts b/libs/wingsdk/src/target-sim/container.inflight.ts index dd4071718f1..51f2cfd72a2 100644 --- a/libs/wingsdk/src/target-sim/container.inflight.ts +++ b/libs/wingsdk/src/target-sim/container.inflight.ts @@ -12,23 +12,27 @@ import { Util } from "../util"; export class Container implements IContainerClient, ISimulatorResourceInstance { private readonly imageTag: string; private readonly containerName: string; - private _context: ISimulatorContext | undefined; - public constructor(private readonly props: ContainerSchema["props"]) { + public constructor( + private readonly props: ContainerSchema["props"], + private readonly context: ISimulatorContext + ) { this.imageTag = props.imageTag; this.containerName = `wing-container-${Util.ulid()}`; } - private get context(): ISimulatorContext { - if (!this._context) { - throw new Error("Cannot access context during class construction"); - } - return this._context; + private log(message: string) { + this.context.addTrace({ + data: { message }, + sourcePath: this.context.resourcePath, + sourceType: "container", + timestamp: new Date().toISOString(), + type: TraceType.LOG, + }); } - public async init(context: ISimulatorContext): Promise { - this._context = context; + public async init(): Promise { // if this a reference to a local directory, build the image from a docker file if (isPath(this.props.image)) { // check if the image is already built @@ -130,16 +134,6 @@ export class Container implements IContainerClient, ISimulatorResourceInstance { public async plan() { return UpdatePlan.AUTO; } - - private log(message: string) { - this.context.addTrace({ - data: { message }, - sourcePath: this.context.resourcePath, - sourceType: "container", - timestamp: new Date().toISOString(), - type: TraceType.LOG, - }); - } } async function waitUntil(predicate: () => Promise) { diff --git a/libs/wingsdk/src/target-sim/container.ts b/libs/wingsdk/src/target-sim/container.ts index af4022f5392..947553686de 100644 --- a/libs/wingsdk/src/target-sim/container.ts +++ b/libs/wingsdk/src/target-sim/container.ts @@ -119,7 +119,7 @@ export class Container extends Resource implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host, ops); + bindSimulatorResource(__filename, this, host); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/counter.inflight.ts b/libs/wingsdk/src/target-sim/counter.inflight.ts index d4ef6ce46de..3e52273cb8a 100644 --- a/libs/wingsdk/src/target-sim/counter.inflight.ts +++ b/libs/wingsdk/src/target-sim/counter.inflight.ts @@ -14,22 +14,18 @@ const VALUES_FILENAME = "values.json"; export class Counter implements ICounterClient, ISimulatorResourceInstance { private values: Map; private initial: number; - private _context: ISimulatorContext | undefined; + private readonly context: ISimulatorContext; - public constructor(props: CounterSchema["props"]) { + public constructor( + props: CounterSchema["props"], + context: ISimulatorContext + ) { this.initial = props.initial ?? 0; this.values = new Map().set("default", this.initial); + this.context = context; } - private get context(): ISimulatorContext { - if (!this._context) { - throw new Error("Cannot access context during class construction"); - } - return this._context; - } - - public async init(context: ISimulatorContext): Promise { - this._context = context; + public async init(): Promise { const valuesFile = join(this.context.statedir, VALUES_FILENAME); const valueFilesExists = await exists(valuesFile); if (valueFilesExists) { diff --git a/libs/wingsdk/src/target-sim/counter.ts b/libs/wingsdk/src/target-sim/counter.ts index 0c9c15f5b9e..a70abfabdf6 100644 --- a/libs/wingsdk/src/target-sim/counter.ts +++ b/libs/wingsdk/src/target-sim/counter.ts @@ -43,7 +43,7 @@ export class Counter extends cloud.Counter implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host, ops); + bindSimulatorResource(__filename, this, host); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/domain.inflight.ts b/libs/wingsdk/src/target-sim/domain.inflight.ts index b04c0ae80de..22aa307a33a 100644 --- a/libs/wingsdk/src/target-sim/domain.inflight.ts +++ b/libs/wingsdk/src/target-sim/domain.inflight.ts @@ -7,8 +7,8 @@ import { } from "../simulator"; export class Domain implements IDomainClient, ISimulatorResourceInstance { - constructor(_props: DomainSchema["props"]) {} - public async init(_context: ISimulatorContext): Promise> { + constructor(_props: DomainSchema["props"], _context: ISimulatorContext) {} + public async init(): Promise> { return {}; } diff --git a/libs/wingsdk/src/target-sim/endpoint.inflight.ts b/libs/wingsdk/src/target-sim/endpoint.inflight.ts index fc3188c635a..6b6df4eaea3 100644 --- a/libs/wingsdk/src/target-sim/endpoint.inflight.ts +++ b/libs/wingsdk/src/target-sim/endpoint.inflight.ts @@ -29,19 +29,11 @@ export class Endpoint implements IEndpointClient, ISimulatorResourceInstance { private connectResponse?: ConnectResponse; private lastSubdomain?: string; private status: EndpointExposeStatus = "disconnected"; - private _context: ISimulatorContext | undefined; - - constructor(private readonly _props: EndpointSchema["props"]) {} - - private get context(): ISimulatorContext { - if (!this._context) { - throw new Error("Cannot access context during class construction"); - } - return this._context; - } - - public async init(context: ISimulatorContext): Promise { - this._context = context; + constructor( + private readonly _props: EndpointSchema["props"], + private readonly _context: ISimulatorContext + ) {} + public async init(): Promise { const state: StateFileContents = await this.loadState(); if (state.subdomain) { await this.connect(state.subdomain); @@ -89,11 +81,11 @@ export class Endpoint implements IEndpointClient, ISimulatorResourceInstance { private async loadState(): Promise { const stateFileExists = await exists( - join(this.context.statedir, STATE_FILENAME) + join(this._context.statedir, STATE_FILENAME) ); if (stateFileExists) { const stateFileContents = await readFile( - join(this.context.statedir, STATE_FILENAME), + join(this._context.statedir, STATE_FILENAME), "utf-8" ); return JSON.parse(stateFileContents); @@ -104,14 +96,14 @@ export class Endpoint implements IEndpointClient, ISimulatorResourceInstance { private async saveState(state: StateFileContents): Promise { writeFileSync( - join(this.context.statedir, STATE_FILENAME), + join(this._context.statedir, STATE_FILENAME), JSON.stringify(state) ); } private async connect(subdomain?: string) { try { - await this.context.withTrace({ + await this._context.withTrace({ message: `Creating tunnel for endpoint. ${ subdomain ? `Using subdomain: ${subdomain}` : "" }`, diff --git a/libs/wingsdk/src/target-sim/event-mapping.inflight.ts b/libs/wingsdk/src/target-sim/event-mapping.inflight.ts index d1b7239405f..c0c2b19956f 100644 --- a/libs/wingsdk/src/target-sim/event-mapping.inflight.ts +++ b/libs/wingsdk/src/target-sim/event-mapping.inflight.ts @@ -3,47 +3,34 @@ import { EventMappingAttributes, EventMappingSchema, EventSubscription, - ResourceHandle, + FunctionHandle, + PublisherHandle, } from "./schema-resources"; import { ISimulatorContext } from "../simulator"; import { ISimulatorResourceInstance, UpdatePlan } from "../simulator/simulator"; export class EventMapping implements ISimulatorResourceInstance { - private readonly publisher: ResourceHandle; - private readonly subscriber: ResourceHandle; + private readonly publisher: PublisherHandle; + private readonly subscriber: FunctionHandle; private readonly eventSubscription: EventSubscription; - private _context: ISimulatorContext | undefined; + private readonly context: ISimulatorContext; - constructor(props: EventMappingSchema["props"]) { + constructor(props: EventMappingSchema["props"], context: ISimulatorContext) { this.publisher = props.publisher; this.subscriber = props.subscriber; this.eventSubscription = props.subscriptionProps; - } - private get context(): ISimulatorContext { - if (!this._context) { - throw new Error("Cannot access context during class construction"); - } - return this._context; + this.context = context; } - public async init( - context: ISimulatorContext - ): Promise { - this._context = context; - const client = this.context.getClient( - this.publisher, - true - ) as IEventPublisher; + public async init(): Promise { + const client = this.context.getClient(this.publisher) as IEventPublisher; await client.addEventSubscription(this.subscriber, this.eventSubscription); return {}; } public async cleanup(): Promise { - const client = this.context.getClient( - this.publisher, - true - ) as IEventPublisher; + const client = this.context.getClient(this.publisher) as IEventPublisher; await client.removeEventSubscription(this.subscriber); } diff --git a/libs/wingsdk/src/target-sim/event-mapping.ts b/libs/wingsdk/src/target-sim/event-mapping.ts index 4c907613698..b2e7770523d 100644 --- a/libs/wingsdk/src/target-sim/event-mapping.ts +++ b/libs/wingsdk/src/target-sim/event-mapping.ts @@ -3,7 +3,7 @@ import { ISimulatorResource } from "./resource"; import { EventMappingSchema, EventSubscription, - ResourceHandle, + FunctionHandle, } from "./schema-resources"; import { simulatorHandleToken } from "./tokens"; import { bindSimulatorResource, makeSimulatorJsClient } from "./util"; @@ -24,7 +24,7 @@ export interface IEventPublisher extends ISimulatorResourceInstance { * @param subscriptionProps additional subscription properties */ addEventSubscription: ( - subscriber: ResourceHandle, + subscriber: FunctionHandle, subscriptionProps: EventSubscription ) => Promise; @@ -33,7 +33,7 @@ export interface IEventPublisher extends ISimulatorResourceInstance { * @param subscriber the subscriber function * @param subscriptionProps additional subscription properties */ - removeEventSubscription: (subscriber: ResourceHandle) => Promise; + removeEventSubscription: (subscriber: FunctionHandle) => Promise; } export const EVENT_MAPPING_FQN = fqnForType("sim.EventMapping"); @@ -87,7 +87,7 @@ export class EventMapping extends Resource implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host, ops); + bindSimulatorResource(__filename, this, host); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/function.inflight.ts b/libs/wingsdk/src/target-sim/function.inflight.ts index 62cd4440af3..b4d0258f3c4 100644 --- a/libs/wingsdk/src/target-sim/function.inflight.ts +++ b/libs/wingsdk/src/target-sim/function.inflight.ts @@ -11,37 +11,29 @@ import { import { TraceType } from "../std"; export class Function implements IFunctionClient, ISimulatorResourceInstance { - private readonly sourceCodeFile: string; - private originalFile!: string; + private readonly originalFile: string; private bundle: Bundle | undefined; private readonly env: Record; - private _context: ISimulatorContext | undefined; + private readonly context: ISimulatorContext; private readonly timeout: number; private readonly maxWorkers: number; private readonly workers = new Array(); - private createBundlePromise!: Promise; + private createBundlePromise: Promise; - constructor(props: FunctionSchema["props"]) { - this.sourceCodeFile = props.sourceCodeFile; + constructor(props: FunctionSchema["props"], context: ISimulatorContext) { if (props.sourceCodeLanguage !== "javascript") { throw new Error("Only JavaScript is supported"); } + this.originalFile = path.resolve(context.simdir, props.sourceCodeFile); this.env = props.environmentVariables ?? {}; + this.context = context; this.timeout = props.timeout; this.maxWorkers = props.concurrency; - } - private get context(): ISimulatorContext { - if (!this._context) { - throw new Error("Cannot access context during class construction"); - } - return this._context; + this.createBundlePromise = this.createBundle(); } - public async init(context: ISimulatorContext): Promise { - this._context = context; - this.originalFile = path.resolve(context.simdir, this.sourceCodeFile); - this.createBundlePromise = this.createBundle(); + public async init(): Promise { return {}; } @@ -91,14 +83,12 @@ export class Function implements IFunctionClient, ISimulatorResourceInstance { ); } process.nextTick(() => { + // If the call fails, we log the error and continue since we've already + // handed control back to the caller. void worker.call("handler", payload).catch((e) => { - // If the call fails, we log the error and continue since we've already - // handed control back to the caller. this.context.addTrace({ data: { - message: `InvokeAsync (payload=${JSON.stringify( - payload - )}) failure.`, + message: `InvokeAsync (payload=${JSON.stringify(payload)}).`, status: "failure", error: e, }, @@ -153,7 +143,6 @@ export class Function implements IFunctionClient, ISimulatorResourceInstance { return new Sandbox(this.bundle.entrypointPath, { env: { ...this.env, - WING_SIMULATOR_CALLER: this.context.resourceHandle, WING_SIMULATOR_URL: this.context.serverUrl, }, timeout: this.timeout, diff --git a/libs/wingsdk/src/target-sim/function.ts b/libs/wingsdk/src/target-sim/function.ts index b106cf732a4..3a77d1d7951 100644 --- a/libs/wingsdk/src/target-sim/function.ts +++ b/libs/wingsdk/src/target-sim/function.ts @@ -1,13 +1,12 @@ import { relative } from "path"; import { Construct } from "constructs"; -import { Policy } from "./policy"; -import { ISimulatorInflightHost, ISimulatorResource } from "./resource"; +import { ISimulatorResource } from "./resource"; import { FunctionSchema } from "./schema-resources"; import { bindSimulatorResource, makeSimulatorJsClient } from "./util"; import * as cloud from "../cloud"; import { App } from "../core"; import { BaseResourceSchema } from "../simulator/simulator"; -import { IInflightHost, IResource } from "../std"; +import { IInflightHost } from "../std"; import { Duration } from "../std/duration"; export const ENV_WING_SIM_INFLIGHT_RESOURCE_PATH = @@ -20,15 +19,9 @@ export const ENV_WING_SIM_INFLIGHT_RESOURCE_TYPE = * * @inflight `@winglang/sdk.cloud.IFunctionClient` */ -export class Function - extends cloud.Function - implements ISimulatorResource, ISimulatorInflightHost -{ +export class Function extends cloud.Function implements ISimulatorResource { private readonly timeout: Duration; private readonly concurrency: number; - public readonly policy: Policy; - public _liftMap = undefined; - constructor( scope: Construct, id: string, @@ -40,11 +33,6 @@ export class Function // props.memory is unused since we are not simulating it this.timeout = props.timeout ?? Duration.fromMinutes(1); this.concurrency = props.concurrency ?? 100; - this.policy = new Policy(this, "Policy", { principal: this }); - } - - public addPermission(resource: IResource, op: string): void { - this.policy.addStatement(resource, op); } public toSimulator(): BaseResourceSchema { @@ -74,7 +62,7 @@ export class Function } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host, ops); + bindSimulatorResource(__filename, this, host); super.onLift(host, ops); } @@ -83,10 +71,3 @@ export class Function return makeSimulatorJsClient(__filename, this); } } - -/** - * Simulator-specific inflight methods for `cloud.Function`. - */ -export enum FunctionInflightMethods { - HAS_AVAILABLE_WORKERS = "hasAvailableWorkers", -} diff --git a/libs/wingsdk/src/target-sim/index.ts b/libs/wingsdk/src/target-sim/index.ts index 7b8fd8ebf68..dd8a337a355 100644 --- a/libs/wingsdk/src/target-sim/index.ts +++ b/libs/wingsdk/src/target-sim/index.ts @@ -1,5 +1,4 @@ // only include here types that we want to expose in userland export * from "./container"; -export * from "./policy"; export * from "./resource"; export * from "./state"; diff --git a/libs/wingsdk/src/target-sim/on-deploy.inflight.ts b/libs/wingsdk/src/target-sim/on-deploy.inflight.ts index 2e3fe927cc6..8184d522013 100644 --- a/libs/wingsdk/src/target-sim/on-deploy.inflight.ts +++ b/libs/wingsdk/src/target-sim/on-deploy.inflight.ts @@ -8,17 +8,21 @@ import { export class OnDeploy implements IOnDeployClient, ISimulatorResourceInstance { private functionHandle: string; + private readonly context: ISimulatorContext; - public constructor(props: OnDeploySchema["props"]) { + public constructor( + props: OnDeploySchema["props"], + context: ISimulatorContext + ) { this.functionHandle = props.functionHandle; + this.context = context; } - public async init(context: ISimulatorContext): Promise { - const functionClient = context.getClient( - this.functionHandle, - true + public async init(): Promise { + const functionClient = this.context.getClient( + this.functionHandle ) as IFunctionClient; - await context.withTrace({ + await this.context.withTrace({ message: "OnDeploy invoked.", activity: async () => { return functionClient.invoke(); @@ -32,7 +36,6 @@ export class OnDeploy implements IOnDeployClient, ISimulatorResourceInstance { public async save(): Promise {} public async plan() { - // OnDeploy runs on every deployment, so always replace - return UpdatePlan.REPLACE; + return UpdatePlan.AUTO; } } diff --git a/libs/wingsdk/src/target-sim/on-deploy.ts b/libs/wingsdk/src/target-sim/on-deploy.ts index 8d55e3ff565..6ce6c767624 100644 --- a/libs/wingsdk/src/target-sim/on-deploy.ts +++ b/libs/wingsdk/src/target-sim/on-deploy.ts @@ -1,5 +1,4 @@ import { Construct } from "constructs"; -import { Function as SimFunction } from "./function"; import { OnDeploySchema } from "./schema-resources"; import { simulatorHandleToken } from "./tokens"; import { bindSimulatorResource, makeSimulatorJsClient } from "./util"; @@ -21,7 +20,6 @@ export class OnDeploy extends cloud.OnDeploy { Node.of(this.fn).sourceModule = SDK_SOURCE_MODULE; this.node.addDependency(this.fn); - this.node.addDependency((this.fn as SimFunction).policy); for (const c of props.executeBefore ?? []) { c.node.addDependency(this); @@ -46,7 +44,7 @@ export class OnDeploy extends cloud.OnDeploy { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host, ops); + bindSimulatorResource(__filename, this, host); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/policy.inflight.ts b/libs/wingsdk/src/target-sim/policy.inflight.ts deleted file mode 100644 index 7c05110d0f0..00000000000 --- a/libs/wingsdk/src/target-sim/policy.inflight.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { IPolicyClient } from "./policy"; -import { PolicySchema } from "./schema-resources"; -import { - ISimulatorContext, - ISimulatorResourceInstance, - UpdatePlan, -} from "../simulator"; - -export class Policy implements IPolicyClient, ISimulatorResourceInstance { - constructor(_props: PolicySchema["props"]) {} - public async init(_context: ISimulatorContext): Promise> { - return {}; - } - - public async cleanup(): Promise {} - - public async save(): Promise {} - - public async plan(): Promise { - return UpdatePlan.AUTO; - } -} diff --git a/libs/wingsdk/src/target-sim/policy.ts b/libs/wingsdk/src/target-sim/policy.ts deleted file mode 100644 index 7c264237e48..00000000000 --- a/libs/wingsdk/src/target-sim/policy.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Construct } from "constructs"; -import { ISimulatorResource } from "./resource"; -import { PolicySchema, PolicyStatement } from "./schema-resources"; -import { simulatorHandleToken } from "./tokens"; -import { fqnForType } from "../constants"; -import { BaseResourceSchema } from "../simulator"; -import { IResource, Node, Resource } from "../std"; - -export const POLICY_FQN = fqnForType("sim.Policy"); - -/** - * Options for `sim.Policy`. - */ -export interface PolicyProps { - /** - * The resource to which the policy is attached. - */ - readonly principal: IResource; -} - -/** - * Implementation of `sim.Policy`. - */ -export class Policy extends Resource implements ISimulatorResource { - private readonly statements: Map> = new Map(); - private readonly principal: IResource; - constructor(scope: Construct, id: string, props: PolicyProps) { - super(scope, id); - this.principal = props.principal; - Node.of(this).hidden = true; - Node.of(this).title = "Policy"; - Node.of(this).description = "A simulated resource policy"; - } - - /** - * Adds a statement to the policy. - */ - public addStatement(resource: IResource, op: string): void { - if (!this.statements.has(resource)) { - this.statements.set(resource, new Set()); - } - this.statements.get(resource)!.add(op); - } - - public toSimulator(): BaseResourceSchema { - const statements: Array = []; - for (const [resource, ops] of this.statements.entries()) { - for (const op of ops) { - statements.push({ - resourceHandle: simulatorHandleToken(resource), - operation: op, - }); - } - } - const schema: PolicySchema = { - type: POLICY_FQN, - path: this.node.path, - addr: this.node.addr, - props: { - principal: simulatorHandleToken(this.principal), - statements, - }, - attrs: {} as any, - }; - return schema; - } -} - -/** - * Inflight interface for `Policy`. - */ -export interface IPolicyClient {} diff --git a/libs/wingsdk/src/target-sim/queue.inflight.ts b/libs/wingsdk/src/target-sim/queue.inflight.ts index ecd19aa7659..3ab1683a2e9 100644 --- a/libs/wingsdk/src/target-sim/queue.inflight.ts +++ b/libs/wingsdk/src/target-sim/queue.inflight.ts @@ -5,7 +5,7 @@ import { QueueSchema, QueueSubscriber, EventSubscription, - ResourceHandle, + FunctionHandle, } from "./schema-resources"; import { IFunctionClient, IQueueClient, QUEUE_FQN } from "../cloud"; import { @@ -21,25 +21,18 @@ export class Queue private readonly messages = new Array(); private readonly subscribers = new Array(); private readonly processLoop: LoopController; - private _context: ISimulatorContext | undefined; + private readonly context: ISimulatorContext; private readonly timeoutSeconds: number; private readonly retentionPeriod: number; - constructor(props: QueueSchema["props"]) { + constructor(props: QueueSchema["props"], context: ISimulatorContext) { this.timeoutSeconds = props.timeout; this.retentionPeriod = props.retentionPeriod; this.processLoop = runEvery(100, async () => this.processMessages()); // every 0.1 seconds + this.context = context; } - private get context(): ISimulatorContext { - if (!this._context) { - throw new Error("Cannot access context during class construction"); - } - return this._context; - } - - public async init(context: ISimulatorContext): Promise { - this._context = context; + public async init(): Promise { return {}; } @@ -54,7 +47,7 @@ export class Queue } public async addEventSubscription( - subscriber: ResourceHandle, + subscriber: FunctionHandle, subscriptionProps: EventSubscription ): Promise { const s = { @@ -65,7 +58,7 @@ export class Queue } public async removeEventSubscription( - subscriber: ResourceHandle + subscriber: FunctionHandle ): Promise { const index = this.subscribers.findIndex( (s) => s.functionHandle === subscriber diff --git a/libs/wingsdk/src/target-sim/queue.ts b/libs/wingsdk/src/target-sim/queue.ts index 52077d72a30..632ea5dba0e 100644 --- a/libs/wingsdk/src/target-sim/queue.ts +++ b/libs/wingsdk/src/target-sim/queue.ts @@ -2,11 +2,7 @@ import { join } from "path"; import { Construct } from "constructs"; import { App } from "./app"; import { EventMapping } from "./event-mapping"; -import { - Function, - FunctionInflightMethods as SimFunctionInflightMethods, -} from "./function"; -import { Policy } from "./policy"; +import { Function } from "./function"; import { ISimulatorResource } from "./resource"; import { QueueSchema } from "./schema-resources"; import { bindSimulatorResource, makeSimulatorJsClient } from "./util"; @@ -24,7 +20,6 @@ import { Duration, IInflightHost, Node, SDK_SOURCE_MODULE } from "../std"; export class Queue extends cloud.Queue implements ISimulatorResource { private readonly timeout: Duration; private readonly retentionPeriod: Duration; - private readonly policy: Policy; constructor(scope: Construct, id: string, props: cloud.QueueProps = {}) { super(scope, id, props); @@ -47,8 +42,6 @@ export class Queue extends cloud.Queue implements ISimulatorResource { "Retention period must be greater than or equal to timeout" ); } - - this.policy = new Policy(this, "Policy", { principal: this }); } /** @internal */ @@ -116,12 +109,6 @@ export class Queue extends cloud.Queue implements ISimulatorResource { name: "setConsumer()", }); - this.policy.addStatement(fn, cloud.FunctionInflightMethods.INVOKE); - this.policy.addStatement( - fn, - SimFunctionInflightMethods.HAS_AVAILABLE_WORKERS - ); - return fn; } @@ -140,7 +127,7 @@ export class Queue extends cloud.Queue implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host, ops); + bindSimulatorResource(__filename, this, host); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/react-app.inflight.ts b/libs/wingsdk/src/target-sim/react-app.inflight.ts index ecbea6d853a..c0fe6c181bf 100644 --- a/libs/wingsdk/src/target-sim/react-app.inflight.ts +++ b/libs/wingsdk/src/target-sim/react-app.inflight.ts @@ -12,7 +12,7 @@ import { import { TraceType } from "../std"; export class ReactApp implements IReactAppClient, ISimulatorResourceInstance { - private _context: ISimulatorContext | undefined; + private readonly context: ISimulatorContext; private readonly startCommand: string; private readonly path: string; private readonly environmentVariables: Record; @@ -21,7 +21,8 @@ export class ReactApp implements IReactAppClient, ISimulatorResourceInstance { private childProcess?: ChildProcess; private url: string; - constructor(props: ReactAppSchema["props"]) { + constructor(props: ReactAppSchema["props"], context: ISimulatorContext) { + this.context = context; this.path = props.path; this.startCommand = props.startCommand; this.environmentVariables = props.environmentVariables; @@ -30,15 +31,7 @@ export class ReactApp implements IReactAppClient, ISimulatorResourceInstance { this.url = props.url; } - private get context(): ISimulatorContext { - if (!this._context) { - throw new Error("Cannot access context during class construction"); - } - return this._context; - } - - public async init(context: ISimulatorContext): Promise { - this._context = context; + public async init(): Promise { this.addTrace(`Executing start command: ${this.startCommand}`); writeFileSync( diff --git a/libs/wingsdk/src/target-sim/react-app.ts b/libs/wingsdk/src/target-sim/react-app.ts index 78c96c77f46..825428ec240 100644 --- a/libs/wingsdk/src/target-sim/react-app.ts +++ b/libs/wingsdk/src/target-sim/react-app.ts @@ -61,7 +61,7 @@ export class ReactApp extends ex.ReactApp implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host, ops); + bindSimulatorResource(__filename, this, host); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/redis.inflight.ts b/libs/wingsdk/src/target-sim/redis.inflight.ts index 7fc42111c57..b9d06b54cd8 100644 --- a/libs/wingsdk/src/target-sim/redis.inflight.ts +++ b/libs/wingsdk/src/target-sim/redis.inflight.ts @@ -15,11 +15,14 @@ export class Redis private connection?: IoRedis; private isCleanedUp = false; - public constructor(private readonly props: RedisSchema["props"]) { + public constructor( + private readonly props: RedisSchema["props"], + _context: ISimulatorContext + ) { super(); } - public async init(_context: ISimulatorContext): Promise { + public async init(): Promise { try { if (this.isCleanedUp) { return {}; diff --git a/libs/wingsdk/src/target-sim/redis.ts b/libs/wingsdk/src/target-sim/redis.ts index a2d3c6fe886..908ee7f9ccb 100644 --- a/libs/wingsdk/src/target-sim/redis.ts +++ b/libs/wingsdk/src/target-sim/redis.ts @@ -50,7 +50,7 @@ export class Redis extends ex.Redis implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host, ops); + bindSimulatorResource(__filename, this, host); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/resource.ts b/libs/wingsdk/src/target-sim/resource.ts index 2c861f5dc76..d3dfd03d7de 100644 --- a/libs/wingsdk/src/target-sim/resource.ts +++ b/libs/wingsdk/src/target-sim/resource.ts @@ -1,29 +1,9 @@ import { BaseResourceSchema } from "../simulator/simulator"; -import { IInflightHost, IResource } from "../std"; +import { IResource } from "../std"; /** - * Interfaces shared by all preflight classes that host inflight code. - */ -export interface ISimulatorInflightHost extends IInflightHost { - /** - * Add a simulated permission to this inflight host. - * @param resource The resource to add - * @param op The action to add - */ - addPermission(resource: IResource, op: string): void; -} - -export function isSimulatorInflightHost( - obj: any -): obj is ISimulatorInflightHost { - return ( - typeof obj == "object" && - typeof (obj as ISimulatorInflightHost).addPermission === "function" - ); -} - -/** - * Interfaces shared by all preflight classes targeting the simulator. + * Interfaces shared by all polycon implementations (preflight classes) + * targeting the simulator. */ export interface ISimulatorResource extends IResource { /** diff --git a/libs/wingsdk/src/target-sim/schedule.inflight.ts b/libs/wingsdk/src/target-sim/schedule.inflight.ts index 5c44bebbacb..b2bade5f30d 100644 --- a/libs/wingsdk/src/target-sim/schedule.inflight.ts +++ b/libs/wingsdk/src/target-sim/schedule.inflight.ts @@ -17,23 +17,17 @@ import { TraceType } from "../std"; export class Schedule implements IScheduleClient, ISimulatorResourceInstance, IEventPublisher { - private _context: ISimulatorContext | undefined; + private readonly context: ISimulatorContext; private tasks = new Array(); private interval: CronExpression; private intervalTimeout?: NodeJS.Timeout; - constructor(props: ScheduleSchema["props"]) { + constructor(props: ScheduleSchema["props"], context: ISimulatorContext) { + this.context = context; this.interval = parseExpression(props.cronExpression, { utc: true }); this.scheduleFunction(); } - private get context(): ISimulatorContext { - if (!this._context) { - throw new Error("Cannot access context during class construction"); - } - return this._context; - } - // Calculate the delay for the next execution private nextDelay(interval: CronExpression) { return interval.next().toDate().getTime() - Date.now(); @@ -47,8 +41,7 @@ export class Schedule }, this.nextDelay(this.interval)); } - public async init(context: ISimulatorContext): Promise { - this._context = context; + public async init(): Promise { return {}; } diff --git a/libs/wingsdk/src/target-sim/schedule.ts b/libs/wingsdk/src/target-sim/schedule.ts index 807f24b5c74..31289df757a 100644 --- a/libs/wingsdk/src/target-sim/schedule.ts +++ b/libs/wingsdk/src/target-sim/schedule.ts @@ -3,7 +3,6 @@ import { Construct } from "constructs"; import { App } from "./app"; import { EventMapping } from "./event-mapping"; import { Function } from "./function"; -import { Policy } from "./policy"; import { ISimulatorResource } from "./resource"; import { ScheduleSchema } from "./schema-resources"; import { @@ -23,14 +22,12 @@ import { IInflightHost, Node, SDK_SOURCE_MODULE } from "../std"; */ export class Schedule extends cloud.Schedule implements ISimulatorResource { private readonly cronExpression: string; - private readonly policy: Policy; constructor(scope: Construct, id: string, props: cloud.ScheduleProps = {}) { super(scope, id, props); const { rate, cron } = props; this.cronExpression = cron ?? convertDurationToCronExpression(rate!); - this.policy = new Policy(this, "Policy", { principal: this }); } public onTick( @@ -63,7 +60,6 @@ export class Schedule extends cloud.Schedule implements ISimulatorResource { target: fn, name: "onTick()", }); - this.policy.addStatement(fn, cloud.FunctionInflightMethods.INVOKE); return fn; } @@ -87,7 +83,7 @@ export class Schedule extends cloud.Schedule implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host, ops); + bindSimulatorResource(__filename, this, host); super.onLift(host, ops); } } diff --git a/libs/wingsdk/src/target-sim/schema-resources.ts b/libs/wingsdk/src/target-sim/schema-resources.ts index 6da7f402ace..420843f531a 100644 --- a/libs/wingsdk/src/target-sim/schema-resources.ts +++ b/libs/wingsdk/src/target-sim/schema-resources.ts @@ -1,7 +1,5 @@ import { SIM_CONTAINER_FQN } from "./container"; import { EVENT_MAPPING_FQN } from "./event-mapping"; -import { POLICY_FQN } from "./policy"; -import { SERVICE_HELPER_FQN } from "./service"; import { STATE_FQN } from "./state"; import { API_FQN, @@ -28,7 +26,8 @@ import { } from "../simulator/simulator"; import { Json, TEST_RUNNER_FQN } from "../std"; -export type ResourceHandle = string; +export type FunctionHandle = string; +export type PublisherHandle = string; /** Schema for cloud.Api */ export interface ApiSchema extends BaseResourceSchema { @@ -96,6 +95,8 @@ export interface ServiceSchema extends BaseResourceSchema { readonly props: { /** The source code of the service */ readonly sourceCodeFile: string; + /** Whether the service should start when sim starts */ + readonly autoStart: boolean; /** A map of environment variables to run the function with. */ readonly environmentVariables: Record; }; @@ -104,20 +105,6 @@ export interface ServiceSchema extends BaseResourceSchema { /** Runtime attributes for cloud.Service */ export interface ServiceAttributes {} -/** Schema for sim.ServiceHelper */ -export interface ServiceHelperSchema extends BaseResourceSchema { - readonly type: typeof SERVICE_HELPER_FQN; - readonly props: { - /** The service. */ - readonly service: ResourceHandle; - /** Whether to auto-start the service */ - readonly autoStart: boolean; - }; -} - -/** Runtime attributes for sim.ServiceHelper */ -export interface ServiceHelperAttributes {} - /** Runtime attributes for cloud.Schedule */ export interface ScheduleAttributes {} @@ -133,7 +120,7 @@ export interface ScheduleSchema extends BaseResourceSchema { /** Schema for cloud.Queue.props.subscribers */ export interface ScheduleTask extends EventSubscription { /** Function that should be called. */ - readonly functionHandle: ResourceHandle; + readonly functionHandle: FunctionHandle; } export interface EventSubscription {} @@ -143,9 +130,9 @@ export interface EventMappingSchema extends BaseResourceSchema { readonly type: typeof EVENT_MAPPING_FQN; readonly props: { /** Function handle to call for subscriber */ - subscriber: ResourceHandle; + subscriber: FunctionHandle; /** Publisher handle of the event */ - publisher: ResourceHandle; + publisher: PublisherHandle; /** Additional properties of event subscription */ subscriptionProps: EventSubscription; }; @@ -160,7 +147,7 @@ export interface QueueAttributes {} /** Schema for cloud.Queue.props.subscribers */ export interface QueueSubscriber extends EventSubscription { /** Function that should be called. */ - readonly functionHandle: ResourceHandle; + readonly functionHandle: FunctionHandle; /** Maximum number of messages that will be batched together to the subscriber. */ readonly batchSize: number; } @@ -176,7 +163,7 @@ export interface TopicAttributes {} export interface TopicSubscriber extends EventSubscription { /** Function that should be called */ - readonly functionHandle: ResourceHandle; + readonly functionHandle: FunctionHandle; } /** Runtime attributes for cloud.Table */ @@ -226,7 +213,7 @@ export interface TestRunnerSchema extends BaseResourceSchema { readonly type: typeof TEST_RUNNER_FQN; readonly props: { /** A map from test functions to their handles. */ - readonly tests: Record; + readonly tests: Record; }; } @@ -301,7 +288,7 @@ export interface OnDeploySchema extends BaseResourceSchema { readonly type: typeof ON_DEPLOY_FQN; readonly props: { /** The function to run on deploy. */ - readonly functionHandle: ResourceHandle; + readonly functionHandle: FunctionHandle; }; } @@ -348,9 +335,6 @@ export interface EndpointSchema extends BaseResourceSchema { readonly attrs: EndpointAttributes & BaseResourceAttributes; } -/** Runtime attributes for sim.Policy */ -export interface PolicyAttributes {} - /** Schema for sim.Container */ export interface ContainerSchema extends BaseResourceSchema { readonly type: typeof SIM_CONTAINER_FQN; @@ -367,22 +351,3 @@ export interface ContainerSchema extends BaseResourceSchema { /** Runtime attributes for sim.Container */ export interface ContainerAttributes {} - -/** Schema for sim.Policy */ -export interface PolicySchema extends BaseResourceSchema { - readonly type: typeof POLICY_FQN; - readonly props: PolicySchemaProps; - readonly attrs: PolicyAttributes & BaseResourceAttributes; -} - -export interface PolicySchemaProps { - /** The resource which the policy is attached to. */ - readonly principal: ResourceHandle; - /** The statements in the policy. */ - readonly statements: PolicyStatement[]; -} - -export interface PolicyStatement { - readonly operation: string; - readonly resourceHandle: ResourceHandle; -} diff --git a/libs/wingsdk/src/target-sim/secret.inflight.ts b/libs/wingsdk/src/target-sim/secret.inflight.ts index d178a7bee69..02791e12cf6 100644 --- a/libs/wingsdk/src/target-sim/secret.inflight.ts +++ b/libs/wingsdk/src/target-sim/secret.inflight.ts @@ -11,11 +11,13 @@ import { import { Json, TraceType } from "../std"; export class Secret implements ISecretClient, ISimulatorResourceInstance { - private _context: ISimulatorContext | undefined; + private readonly context: ISimulatorContext; private readonly secretsFile: string; private readonly name: string; - constructor(props: SecretSchema["props"]) { + constructor(props: SecretSchema["props"], context: ISimulatorContext) { + this.context = context; + this.secretsFile = path.join(os.homedir(), ".wing", "secrets.json"); if (!fs.existsSync(this.secretsFile)) { throw new Error( @@ -26,15 +28,7 @@ export class Secret implements ISecretClient, ISimulatorResourceInstance { this.name = props.name; } - private get context(): ISimulatorContext { - if (!this._context) { - throw new Error("Cannot access context during class construction"); - } - return this._context; - } - - public async init(context: ISimulatorContext): Promise { - this._context = context; + public async init(): Promise { return {}; } diff --git a/libs/wingsdk/src/target-sim/secret.ts b/libs/wingsdk/src/target-sim/secret.ts index 97b2a366bfd..aeee0c16a7f 100644 --- a/libs/wingsdk/src/target-sim/secret.ts +++ b/libs/wingsdk/src/target-sim/secret.ts @@ -23,7 +23,7 @@ export class Secret extends cloud.Secret implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host, ops); + bindSimulatorResource(__filename, this, host); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/service.inflight.ts b/libs/wingsdk/src/target-sim/service.inflight.ts index 4c6ced2f889..fc705431671 100644 --- a/libs/wingsdk/src/target-sim/service.inflight.ts +++ b/libs/wingsdk/src/target-sim/service.inflight.ts @@ -1,9 +1,5 @@ import { resolve } from "path"; -import { - ServiceAttributes, - ServiceHelperSchema, - ServiceSchema, -} from "./schema-resources"; +import { ServiceAttributes, ServiceSchema } from "./schema-resources"; import { IServiceClient, SERVICE_FQN } from "../cloud"; import { Bundle } from "../shared/bundling"; import { Sandbox } from "../shared/sandbox"; @@ -15,45 +11,38 @@ import { import { TraceType } from "../std"; export class Service implements IServiceClient, ISimulatorResourceInstance { - private _context: ISimulatorContext | undefined; - private readonly sourceCodeFile: string; - private resolvedSourceCodeFile!: string; + private readonly context: ISimulatorContext; + private readonly originalFile: string; + private readonly autoStart: boolean; private sandbox: Sandbox | undefined; private bundle: Bundle | undefined; + private createBundlePromise: Promise; private running: boolean = false; private environmentVariables: Record; - private createBundlePromise!: Promise; - constructor(props: ServiceSchema["props"]) { - this.sourceCodeFile = props.sourceCodeFile; + constructor(props: ServiceSchema["props"], context: ISimulatorContext) { + this.context = context; + this.originalFile = resolve(context.simdir, props.sourceCodeFile); + this.autoStart = props.autoStart; this.environmentVariables = props.environmentVariables ?? {}; - } - private get context(): ISimulatorContext { - if (!this._context) { - throw new Error("Cannot access context during class construction"); - } - return this._context; + this.createBundlePromise = this.createBundle(); } private async createBundle(): Promise { - this.bundle = await Sandbox.createBundle( - this.resolvedSourceCodeFile, - (msg) => { - this.addTrace(msg); - } - ); + this.bundle = await Sandbox.createBundle(this.originalFile, (msg) => { + this.addTrace(msg); + }); } - public async init(context: ISimulatorContext): Promise { - this._context = context; - this.resolvedSourceCodeFile = resolve(context.simdir, this.sourceCodeFile); - this.createBundlePromise = this.createBundle(); + public async init(): Promise { + if (this.autoStart) { + await this.start(); + } return {}; } public async cleanup(): Promise { - await this.createBundlePromise; await this.stop(); } @@ -82,7 +71,6 @@ export class Service implements IServiceClient, ISimulatorResourceInstance { env: { ...this.environmentVariables, WING_SIMULATOR_URL: this.context.serverUrl, - WING_SIMULATOR_CALLER: this.context.resourceHandle, }, log: (internal, _level, message) => { this.addTrace(message, internal); @@ -109,7 +97,7 @@ export class Service implements IServiceClient, ISimulatorResourceInstance { await this.sandbox.call("stop"); await this.sandbox.cleanup(); } catch (e: any) { - this.addTrace(`Failed to stop service: ${e.message} ${e.stack}`); + this.addTrace(`Failed to stop service: ${e.message}`); } } @@ -127,41 +115,3 @@ export class Service implements IServiceClient, ISimulatorResourceInstance { }); } } - -export class ServiceHelper implements ISimulatorResourceInstance { - private readonly serviceHandle: string; - private readonly autoStart: boolean; - private _context: ISimulatorContext | undefined; - - public constructor(props: ServiceHelperSchema["props"]) { - this.serviceHandle = props.service; - this.autoStart = props.autoStart; - } - - private get context(): ISimulatorContext { - if (!this._context) { - throw new Error("Cannot access context during class construction"); - } - return this._context; - } - - public async init(context: ISimulatorContext): Promise { - this._context = context; - if (this.autoStart) { - const service = context.getClient(this.serviceHandle, true) as Service; - await service.start(); - } - return {}; - } - - public async cleanup(): Promise { - const service = this.context.getClient(this.serviceHandle, true) as Service; - await service.stop(); - } - - public async save(): Promise {} - - public async plan(): Promise { - return UpdatePlan.AUTO; - } -} diff --git a/libs/wingsdk/src/target-sim/service.ts b/libs/wingsdk/src/target-sim/service.ts index 1269ab419f8..d2c21f26a2a 100644 --- a/libs/wingsdk/src/target-sim/service.ts +++ b/libs/wingsdk/src/target-sim/service.ts @@ -1,22 +1,15 @@ import { relative } from "path"; import { Construct } from "constructs"; -import { Policy } from "./policy"; -import { ISimulatorInflightHost, ISimulatorResource } from "./resource"; -import { ServiceHelperSchema, ServiceSchema } from "./schema-resources"; -import { simulatorHandleToken } from "./tokens"; +import { ISimulatorResource } from "./resource"; +import { ServiceSchema } from "./schema-resources"; import { bindSimulatorResource, makeSimulatorJsClient } from "./util"; import * as cloud from "../cloud"; -import { fqnForType } from "../constants"; import { App } from "../core"; import { BaseResourceSchema } from "../simulator"; -import { IInflightHost, IResource, Resource, Node } from "../std"; +import { IInflightHost } from "../std"; -export class Service - extends cloud.Service - implements ISimulatorResource, ISimulatorInflightHost -{ - public readonly policy: Policy; - public _liftMap = undefined; +export class Service extends cloud.Service implements ISimulatorResource { + private readonly autoStart: boolean; constructor( scope: Construct, @@ -25,18 +18,7 @@ export class Service props: cloud.ServiceProps = {} ) { super(scope, id, handler, props); - this.policy = new Policy(this, "Policy", { principal: this }); - - const helper = new ServiceHelper(this, "Helper", { - service: this, - autoStart: props.autoStart ?? true, - }); - helper.node.addDependency(this); - helper.node.addDependency(this.policy); - } - - public addPermission(resource: IResource, op: string): void { - this.policy.addStatement(resource, op); + this.autoStart = props.autoStart ?? true; } public toSimulator(): BaseResourceSchema { @@ -47,6 +29,7 @@ export class Service props: { environmentVariables: this.env, sourceCodeFile: relative(App.of(this).outdir, this.entrypoint), + autoStart: this.autoStart, }, attrs: {} as any, }; @@ -63,7 +46,7 @@ export class Service } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host, ops); + bindSimulatorResource(__filename, this, host); super.onLift(host, ops); } @@ -71,51 +54,3 @@ export class Service return makeSimulatorJsClient(__filename, this); } } - -/** @internal */ -export const SERVICE_HELPER_FQN = fqnForType("sim.ServiceHelper"); - -/** @internal */ -export interface ServiceHelperProps { - readonly service: Service; - readonly autoStart: boolean; -} - -/** - * This is a helper resource that automatically starts the service after the - * service is created in the simulator and shuts it down when the simulator - * stops. - * - * Suppose a service puts an object in a bucket when it starts. The policy - * (sim.Policy) that grants the service bucket permissions only takes effect - * after the service is created. Because of this, the service needs to be - * started after both the service and the policy are created. Vice versa, the - * service needs to be stopped before the policy is deleted. - * - * @internal - */ -export class ServiceHelper extends Resource implements ISimulatorResource { - private readonly service: Service; - private readonly autoStart: boolean; - - constructor(scope: Construct, id: string, props: ServiceHelperProps) { - super(scope, id); - this.service = props.service; - this.autoStart = props.autoStart; - Node.of(this).hidden = true; - } - - public toSimulator(): BaseResourceSchema { - const schema: ServiceHelperSchema = { - type: SERVICE_HELPER_FQN, - path: this.node.path, - addr: this.node.addr, - props: { - service: simulatorHandleToken(this.service), - autoStart: this.autoStart, - }, - attrs: {} as any, - }; - return schema; - } -} diff --git a/libs/wingsdk/src/target-sim/state.inflight.ts b/libs/wingsdk/src/target-sim/state.inflight.ts index 0472e417740..ceb4f946acd 100644 --- a/libs/wingsdk/src/target-sim/state.inflight.ts +++ b/libs/wingsdk/src/target-sim/state.inflight.ts @@ -8,18 +8,11 @@ import { import { Json } from "../std"; export class State implements IStateClient, ISimulatorResourceInstance { - private _context: ISimulatorContext | undefined; - constructor(_props: StateSchema["props"]) {} - - private get context(): ISimulatorContext { - if (!this._context) { - throw new Error("Cannot access context during class construction"); - } - return this._context; - } - - public async init(context: ISimulatorContext): Promise> { - this._context = context; + constructor( + _props: StateSchema["props"], + private readonly context: ISimulatorContext + ) {} + public async init(): Promise> { return {}; } diff --git a/libs/wingsdk/src/target-sim/state.ts b/libs/wingsdk/src/target-sim/state.ts index 3320bc50903..7f3ed33cc6e 100644 --- a/libs/wingsdk/src/target-sim/state.ts +++ b/libs/wingsdk/src/target-sim/state.ts @@ -53,7 +53,7 @@ export class State extends Resource implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host, ops); + bindSimulatorResource(__filename, this, host); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/table.inflight.ts b/libs/wingsdk/src/target-sim/table.inflight.ts index ed48673cf11..5e543fc1e7f 100644 --- a/libs/wingsdk/src/target-sim/table.inflight.ts +++ b/libs/wingsdk/src/target-sim/table.inflight.ts @@ -13,26 +13,19 @@ export class Table implements ITableClient, ISimulatorResourceInstance { private columns: { [key: string]: ColumnType }; private primaryKey: string; private table: Map; - private _context: ISimulatorContext | undefined; + private readonly context: ISimulatorContext; private readonly initialRows: Record; - public constructor(props: TableSchema["props"]) { + public constructor(props: TableSchema["props"], context: ISimulatorContext) { this.name = props.name; this.columns = props.columns; this.primaryKey = props.primaryKey; this.table = new Map(); + this.context = context; this.initialRows = props.initialRows ?? {}; } - private get context(): ISimulatorContext { - if (!this._context) { - throw new Error("Cannot access context during class construction"); - } - return this._context; - } - - public async init(context: ISimulatorContext): Promise { - this._context = context; + public async init(): Promise { for (const [key, row] of Object.entries(this.initialRows)) { await this.context.withTrace({ message: `Adding initial row (key=${key}).`, diff --git a/libs/wingsdk/src/target-sim/table.ts b/libs/wingsdk/src/target-sim/table.ts index 58ed24b5f64..6663052eeed 100644 --- a/libs/wingsdk/src/target-sim/table.ts +++ b/libs/wingsdk/src/target-sim/table.ts @@ -51,7 +51,7 @@ export class Table extends ex.Table implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host, ops); + bindSimulatorResource(__filename, this, host); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/test-runner.inflight.ts b/libs/wingsdk/src/target-sim/test-runner.inflight.ts index 5e4406a2f2f..d04bde496f0 100644 --- a/libs/wingsdk/src/target-sim/test-runner.inflight.ts +++ b/libs/wingsdk/src/target-sim/test-runner.inflight.ts @@ -12,21 +12,14 @@ export class TestRunner { // A map from test paths to their corresponding function handles. private readonly tests: Map; - private _context: ISimulatorContext | undefined; + private readonly context: ISimulatorContext; - constructor(props: TestRunnerSchema["props"]) { + constructor(props: TestRunnerSchema["props"], context: ISimulatorContext) { this.tests = new Map(Object.entries(props.tests)); + this.context = context; } - private get context(): ISimulatorContext { - if (!this._context) { - throw new Error("Cannot access context during class construction"); - } - return this._context; - } - - public async init(context: ISimulatorContext): Promise { - this._context = context; + public async init(): Promise { return {}; } @@ -49,10 +42,7 @@ export class TestRunner if (!functionHandle) { throw new Error(`No test found at path "${path}"`); } - const fnClient = this.context.getClient( - functionHandle, - true - ) as IFunctionClient; + const fnClient = this.context.getClient(functionHandle) as IFunctionClient; let pass = false; let error: string | undefined; const previousTraces = this.context.listTraces().length; diff --git a/libs/wingsdk/src/target-sim/test-runner.ts b/libs/wingsdk/src/target-sim/test-runner.ts index f2ebda594e7..edab23072ea 100644 --- a/libs/wingsdk/src/target-sim/test-runner.ts +++ b/libs/wingsdk/src/target-sim/test-runner.ts @@ -32,7 +32,7 @@ export class TestRunner extends std.TestRunner implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource("test-runner", this, host, ops); + bindSimulatorResource("test-runner", this, host); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/topic.inflight.ts b/libs/wingsdk/src/target-sim/topic.inflight.ts index cd532b343ef..4efffd0e1a0 100644 --- a/libs/wingsdk/src/target-sim/topic.inflight.ts +++ b/libs/wingsdk/src/target-sim/topic.inflight.ts @@ -4,7 +4,7 @@ import { TopicSchema, TopicSubscriber, EventSubscription, - ResourceHandle, + FunctionHandle, } from "./schema-resources"; import { IFunctionClient, ITopicClient, TOPIC_FQN } from "../cloud"; import { @@ -18,19 +18,14 @@ export class Topic implements ITopicClient, ISimulatorResourceInstance, IEventPublisher { private readonly subscribers = new Array(); - private _context: ISimulatorContext | undefined; + private readonly context: ISimulatorContext; - constructor(_props: TopicSchema["props"]) {} - - private get context(): ISimulatorContext { - if (!this._context) { - throw new Error("Cannot access context during class construction"); - } - return this._context; + constructor(props: TopicSchema["props"], context: ISimulatorContext) { + this.context = context; + props; } - public async init(context: ISimulatorContext): Promise { - this._context = context; + public async init(): Promise { return {}; } @@ -62,7 +57,7 @@ export class Topic } public async addEventSubscription( - subscriber: ResourceHandle, + subscriber: FunctionHandle, subscriptionProps: EventSubscription ): Promise { let s = { diff --git a/libs/wingsdk/src/target-sim/topic.ts b/libs/wingsdk/src/target-sim/topic.ts index d2d63deb758..39d0ba00ae4 100644 --- a/libs/wingsdk/src/target-sim/topic.ts +++ b/libs/wingsdk/src/target-sim/topic.ts @@ -3,7 +3,6 @@ import { Construct } from "constructs"; import { App } from "./app"; import { EventMapping } from "./event-mapping"; import { Function } from "./function"; -import { Policy } from "./policy"; import { ISimulatorResource } from "./resource"; import { TopicSchema } from "./schema-resources"; import { bindSimulatorResource, makeSimulatorJsClient } from "./util"; @@ -18,10 +17,8 @@ import { IInflightHost, Node, SDK_SOURCE_MODULE } from "../std"; * @inflight `@winglang/sdk.cloud.ITopicClient` */ export class Topic extends cloud.Topic implements ISimulatorResource { - public readonly policy: Policy; constructor(scope: Construct, id: string, props: cloud.TopicProps = {}) { super(scope, id, props); - this.policy = new Policy(this, "Policy", { principal: this }); } public onMessage( @@ -55,13 +52,11 @@ export class Topic extends cloud.Topic implements ISimulatorResource { name: "onMessage()", }); - this.policy.addStatement(fn, cloud.FunctionInflightMethods.INVOKE_ASYNC); - return fn; } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host, ops); + bindSimulatorResource(__filename, this, host); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/util.ts b/libs/wingsdk/src/target-sim/util.ts index e31dfce9f47..17074dec81b 100644 --- a/libs/wingsdk/src/target-sim/util.ts +++ b/libs/wingsdk/src/target-sim/util.ts @@ -2,7 +2,6 @@ import { access, constants } from "fs"; import { basename } from "path"; import { promisify } from "util"; import { IConstruct } from "constructs"; -import { isSimulatorInflightHost } from "./resource"; import { simulatorHandleToken } from "./tokens"; import { Duration, IInflightHost, Resource } from "../std"; @@ -32,23 +31,13 @@ function makeEnvVarName(type: string, resource: IConstruct): string { export function bindSimulatorResource( filename: string, resource: Resource, - host: IInflightHost, - ops: string[] + host: IInflightHost ) { - // Check if host implements ISimulatorInflightHost - if (!isSimulatorInflightHost(host)) { - throw new Error( - "Host resource must implement sim.ISimulatorInflightHost to bind simulator resources" - ); - } const type = basename(filename).split(".")[0]; const env = makeEnvVarName(type, resource); const handle = simulatorHandleToken(resource); host.addEnvironment(env, handle); host.node.addDependency(resource); - for (const op of ops) { - host.addPermission(resource, op); - } } export function makeSimulatorJsClient(filename: string, resource: Resource) { @@ -63,11 +52,7 @@ export function makeSimulatorJsClient(filename: string, resource: Resource) { if (!simulatorUrl) { throw new Error("Missing environment variable: WING_SIMULATOR_URL"); } - const caller = process.env.WING_SIMULATOR_CALLER; - if (!caller) { - throw new Error("Missing environment variable: WING_SIMULATOR_CALLER"); - } - return require("@winglang/sdk/lib/simulator/client").makeSimulatorClient(simulatorUrl, handle, caller); + return require("@winglang/sdk/lib/simulator/client").makeSimulatorClient(simulatorUrl, handle); })()`; } diff --git a/libs/wingsdk/src/target-sim/website.inflight.ts b/libs/wingsdk/src/target-sim/website.inflight.ts index f25472134e6..aa11fe4eeff 100644 --- a/libs/wingsdk/src/target-sim/website.inflight.ts +++ b/libs/wingsdk/src/target-sim/website.inflight.ts @@ -14,12 +14,14 @@ import { TraceType } from "../std"; const LOCALHOST_ADDRESS = "127.0.0.1"; export class Website implements IWebsiteClient, ISimulatorResourceInstance { - private _context: ISimulatorContext | undefined; + private readonly context: ISimulatorContext; private readonly app: express.Application; private server?: Server; private url?: string; - constructor(props: WebsiteSchema["props"]) { + constructor(props: WebsiteSchema["props"], context: ISimulatorContext) { + this.context = context; + // Set up an express server that handles the routes. this.app = express(); @@ -46,15 +48,7 @@ export class Website implements IWebsiteClient, ISimulatorResourceInstance { } } - private get context(): ISimulatorContext { - if (!this._context) { - throw new Error("Cannot access context during class construction"); - } - return this._context; - } - - public async init(context: ISimulatorContext): Promise { - this._context = context; + public async init(): Promise { // `server.address()` returns `null` until the server is listening // on a port. We use a promise to wait for the server to start // listening before returning the URL. diff --git a/libs/wingsdk/src/target-sim/website.ts b/libs/wingsdk/src/target-sim/website.ts index 4e4ca6accfb..8e90e25e231 100644 --- a/libs/wingsdk/src/target-sim/website.ts +++ b/libs/wingsdk/src/target-sim/website.ts @@ -63,7 +63,7 @@ export class Website extends cloud.Website implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host, ops); + bindSimulatorResource(__filename, this, host); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/util/enhanced-error.ts b/libs/wingsdk/src/util/enhanced-error.ts index ba8a541e4a5..e3dbe7a37ca 100644 --- a/libs/wingsdk/src/util/enhanced-error.ts +++ b/libs/wingsdk/src/util/enhanced-error.ts @@ -79,7 +79,8 @@ export async function prettyPrintError( ) // special: remove the handler wrapper (See `cloud.Function` entrypoint for where this comes from) .filter( - (item) => !normalPath(item.file).match(/\.wing\/\w+(\.sandbox)?\.js$/) + (item) => + !normalPath(item.file).match(/\.wing\/handler_\w+(\.sandbox)?\.js$/) ) .withSourcesAsync(); diff --git a/libs/wingsdk/test/core/__snapshots__/connections.test.ts.snap b/libs/wingsdk/test/core/__snapshots__/connections.test.ts.snap index df0506ae6ec..94c737a6e30 100644 --- a/libs/wingsdk/test/core/__snapshots__/connections.test.ts.snap +++ b/libs/wingsdk/test/core/__snapshots__/connections.test.ts.snap @@ -42,16 +42,6 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Bucket", }, - { - "addr": "c8b5ba55132964ee19331fb9f46241560e67fed76b", - "attrs": {}, - "path": "root/my_bucket/Policy", - "props": { - "principal": "\${wsim#root/my_bucket#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c85c4e0e66bf385ab6b159bab34fb32dd81aad0a1d", "attrs": {}, @@ -65,16 +55,6 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c8d421ed6ca2ddf857d835791bcde9240c8682a8d9", - "attrs": {}, - "path": "root/my_function/Policy", - "props": { - "principal": "\${wsim#root/my_function#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -150,14 +130,6 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -172,21 +144,6 @@ return class Handler { "tree": { "children": { "my_bucket": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_bucket/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -199,21 +156,6 @@ return class Handler { "path": "root/my_bucket", }, "my_function": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_function/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", diff --git a/libs/wingsdk/test/simulator/cleanup.test.ts b/libs/wingsdk/test/simulator/cleanup.test.ts index 2304889be27..770d27715f6 100644 --- a/libs/wingsdk/test/simulator/cleanup.test.ts +++ b/libs/wingsdk/test/simulator/cleanup.test.ts @@ -19,7 +19,7 @@ async function main() { console.log("Simulator started"); process.on("SIGTERM", async () => { - console.log("SIGTERM received, stopping simulator.."); + console.log("SIGTERM received, stopping simulator..."); await sim.stop(); process.exit(1); }); @@ -43,9 +43,7 @@ async handle() { // and that process has code set up for gracefully shutting down the simulator, // then the simulator will be stopped correctly (including child processes // like services). -// -// TODO: failing in CI... :-( -test.skip("simulator cleanup", async () => { +test("simulator cleanup", async () => { // Synthesize configuration for the simulator to use in the test const app = new SimApp({ isTestEnvironment: true }); const handler = Testing.makeHandler(code); diff --git a/libs/wingsdk/test/simulator/on-trace.test.ts b/libs/wingsdk/test/simulator/on-trace.test.ts index cee2e130f88..ffab782d4ef 100644 --- a/libs/wingsdk/test/simulator/on-trace.test.ts +++ b/libs/wingsdk/test/simulator/on-trace.test.ts @@ -27,5 +27,5 @@ test("onTrace", async () => { await s.stop(); // THEN - expect(numTraces).toBeGreaterThanOrEqual(3); // create resources, put operation, delete resources + expect(numTraces).toEqual(3); // create resources, put operation, delete resources }); diff --git a/libs/wingsdk/test/simulator/simulator.test.ts b/libs/wingsdk/test/simulator/simulator.test.ts index 422bd103ae3..7d8fb866fd6 100644 --- a/libs/wingsdk/test/simulator/simulator.test.ts +++ b/libs/wingsdk/test/simulator/simulator.test.ts @@ -214,15 +214,9 @@ describe("in-place updates", () => { new Bucket(app, "Bucket1"); const sim = await app.startSimulator(stateDir); - expect(sim.listResources()).toEqual([ - "root/Bucket1", - "root/Bucket1/Policy", - ]); + expect(sim.listResources()).toEqual(["root/Bucket1"]); - expect(simTraces(sim)).toStrictEqual([ - "root/Bucket1 started", - "root/Bucket1/Policy started", - ]); + expect(simTraces(sim)).toStrictEqual(["root/Bucket1 started"]); const app2 = new SimApp(); new Bucket(app2, "Bucket1"); @@ -238,14 +232,10 @@ describe("in-place updates", () => { expect(simTraces(sim)).toStrictEqual([ "root/Bucket1 started", - "root/Bucket1/Policy started", "Update: 0 added, 0 updated, 0 deleted", ]); - expect(sim.listResources()).toEqual([ - "root/Bucket1", - "root/Bucket1/Policy", - ]); + expect(sim.listResources()).toEqual(["root/Bucket1"]); await sim.stop(); }); @@ -256,14 +246,8 @@ describe("in-place updates", () => { new Bucket(app, "Bucket1"); const sim = await app.startSimulator(stateDir); - expect(sim.listResources()).toEqual([ - "root/Bucket1", - "root/Bucket1/Policy", - ]); - expect(simTraces(sim)).toStrictEqual([ - "root/Bucket1 started", - "root/Bucket1/Policy started", - ]); + expect(sim.listResources()).toEqual(["root/Bucket1"]); + expect(simTraces(sim)).toStrictEqual(["root/Bucket1 started"]); const app2 = new SimApp(); new Bucket(app2, "Bucket1"); @@ -272,23 +256,16 @@ describe("in-place updates", () => { const app2Dir = app2.synth(); await sim.update(app2Dir); expect(updateTrace(sim)).toStrictEqual({ - added: ["root/Bucket2", "root/Bucket2/Policy"], + added: ["root/Bucket2"], deleted: [], updated: [], }); - expect(sim.listResources()).toEqual([ - "root/Bucket1", - "root/Bucket1/Policy", - "root/Bucket2", - "root/Bucket2/Policy", - ]); + expect(sim.listResources()).toEqual(["root/Bucket1", "root/Bucket2"]); expect(simTraces(sim)).toStrictEqual([ "root/Bucket1 started", - "root/Bucket1/Policy started", - "Update: 2 added, 0 updated, 0 deleted", + "Update: 1 added, 0 updated, 0 deleted", "root/Bucket2 started", - "root/Bucket2/Policy started", ]); await sim.stop(); @@ -301,17 +278,10 @@ describe("in-place updates", () => { new Bucket(app, "Bucket1"); new Bucket(app, "Bucket2"); const sim = await app.startSimulator(stateDir); - expect(sim.listResources()).toEqual([ - "root/Bucket1", - "root/Bucket1/Policy", - "root/Bucket2", - "root/Bucket2/Policy", - ]); + expect(sim.listResources()).toEqual(["root/Bucket1", "root/Bucket2"]); expect(simTraces(sim)).toStrictEqual([ "root/Bucket1 started", - "root/Bucket1/Policy started", "root/Bucket2 started", - "root/Bucket2/Policy started", ]); const app2 = new SimApp(); @@ -321,22 +291,16 @@ describe("in-place updates", () => { await sim.update(app2Dir); expect(updateTrace(sim)).toStrictEqual({ added: [], - deleted: ["root/Bucket2", "root/Bucket2/Policy"], + deleted: ["root/Bucket2"], updated: [], }); - expect(sim.listResources()).toEqual([ - "root/Bucket1", - "root/Bucket1/Policy", - ]); + expect(sim.listResources()).toEqual(["root/Bucket1"]); expect(simTraces(sim)).toStrictEqual([ "root/Bucket1 started", - "root/Bucket1/Policy started", "root/Bucket2 started", - "root/Bucket2/Policy started", - "Update: 0 added, 0 updated, 2 deleted", - "root/Bucket2/Policy stopped", + "Update: 0 added, 0 updated, 1 deleted", "root/Bucket2 stopped", ]); @@ -349,15 +313,9 @@ describe("in-place updates", () => { const app = new SimApp(); new Bucket(app, "Bucket1"); const sim = await app.startSimulator(stateDir); - expect(sim.listResources()).toEqual([ - "root/Bucket1", - "root/Bucket1/Policy", - ]); + expect(sim.listResources()).toEqual(["root/Bucket1"]); expect(sim.getResourceConfig("root/Bucket1").props.public).toBeFalsy(); - expect(simTraces(sim)).toStrictEqual([ - "root/Bucket1 started", - "root/Bucket1/Policy started", - ]); + expect(simTraces(sim)).toStrictEqual(["root/Bucket1 started"]); const app2 = new SimApp(); new Bucket(app2, "Bucket1", { public: true }); @@ -370,19 +328,13 @@ describe("in-place updates", () => { updated: ["root/Bucket1"], }); - expect(sim.listResources()).toEqual([ - "root/Bucket1", - "root/Bucket1/Policy", - ]); + expect(sim.listResources()).toEqual(["root/Bucket1"]); expect(simTraces(sim)).toStrictEqual([ "root/Bucket1 started", - "root/Bucket1/Policy started", "Update: 0 added, 1 updated, 0 deleted", - "root/Bucket1/Policy stopped", "root/Bucket1 stopped", "root/Bucket1 started", - "root/Bucket1/Policy started", ]); expect(sim.getResourceConfig("root/Bucket1").props.public).toBeTruthy(); @@ -398,15 +350,9 @@ describe("in-place updates", () => { const sim = await app.startSimulator(stateDir); - expect(simTraces(sim)).toStrictEqual([ - "root/Bucket1 started", - "root/Bucket1/Policy started", - ]); + expect(simTraces(sim)).toStrictEqual(["root/Bucket1 started"]); - expect(sim.listResources()).toEqual([ - "root/Bucket1", - "root/Bucket1/Policy", - ]); + expect(sim.listResources()).toEqual(["root/Bucket1"]); expect(sim.getResourceConfig("root/Bucket1").props.public).toBeFalsy(); const app2 = new SimApp(); @@ -423,40 +369,26 @@ describe("in-place updates", () => { await sim.update(app2Dir); expect(updateTrace(sim)).toStrictEqual({ - added: [ - "root/Api", - "root/Api/Endpoint", - "root/Api/Policy", - "root/Function", - "root/Function/Policy", - ], + added: ["root/Api", "root/Api/Endpoint", "root/Function"], deleted: [], updated: ["root/Bucket1"], }); expect(simTraces(sim)).toStrictEqual([ "root/Bucket1 started", - "root/Bucket1/Policy started", - "Update: 5 added, 1 updated, 0 deleted", - "root/Bucket1/Policy stopped", + "Update: 3 added, 1 updated, 0 deleted", "root/Bucket1 stopped", "root/Api started", "root/Bucket1 started", - "root/Bucket1/Policy started", "root/Api/Endpoint started", - "root/Api/Policy started", "root/Function started", - "root/Function/Policy started", ]); expect(sim.listResources()).toEqual([ "root/Api", "root/Api/Endpoint", - "root/Api/Policy", "root/Bucket1", - "root/Bucket1/Policy", "root/Function", - "root/Function/Policy", ]); const bucketClient = sim.getResource("root/Bucket1") as IBucketClient; @@ -511,12 +443,15 @@ describe("in-place updates", () => { const stateDir = mkdtemp(); const sim = await app.startSimulator(stateDir); + const urlBeforeUpdate = await sim + .getResource("root/Bucket1") + .get("url.txt"); + expect(urlBeforeUpdate.startsWith("http://127.0.0")).toBeTruthy(); + expect(simTraces(sim)).toEqual([ "root/Api1 started", "root/Api1/Endpoint started", - "root/Api1/Policy started", "root/Bucket1 started", - "root/Bucket1/Policy started", ]); // now lets change some configuration of Api1. we expect the bucket to be replaced as well @@ -526,35 +461,35 @@ describe("in-place updates", () => { const myBucket2 = new Bucket(app2, "Bucket1"); myBucket2.addObject("url.txt", myApi2.url); + // clear the state directory + fs.rmdirSync(stateDir, { recursive: true }); + const app2Dir = app2.synth(); await sim.update(app2Dir); expect(updateTrace(sim)).toStrictEqual({ added: [], deleted: [], - updated: ["root/Api1"], // TODO: shouldn't Bucket also be listed here? + updated: ["root/Api1"], }); expect(simTraces(sim)).toEqual([ "root/Api1 started", "root/Api1/Endpoint started", - "root/Api1/Policy started", "root/Bucket1 started", - "root/Bucket1/Policy started", "Update: 0 added, 1 updated, 0 deleted", "root/Api1/Endpoint stopped", - "root/Api1/Policy stopped", - "root/Bucket1/Policy stopped", "root/Bucket1 stopped", "root/Api1 stopped", "root/Api1 started", "root/Api1/Endpoint started", - "root/Api1/Policy started", "root/Bucket1 started", - "root/Bucket1/Policy started", ]); - await sim.stop(); + const urlAfterUpdate = await ( + sim.getResource("root/Bucket1") as IBucketClient + ).get("url.txt"); + expect(urlAfterUpdate).not.toEqual(urlBeforeUpdate); }); test("token value is changed across an update", async () => { @@ -616,24 +551,15 @@ describe("in-place updates", () => { expect(simTraces(sim)).toEqual([ "root/State started", - "root/Service started", - "root/Service/Policy started", "root/State.my_value = bang", - "root/Service/Helper started", + "root/Service started", "root/Function started", - "root/Function/Policy started", "Update: 0 added, 2 updated, 0 deleted", - "root/Service/Helper stopped", - "root/Service/Policy stopped", "root/Service stopped", - "root/Function/Policy stopped", "root/Function stopped", - "root/Service started", - "root/Service/Policy started", "root/State.my_value = bing", - "root/Service/Helper started", + "root/Service started", "root/Function started", - "root/Function/Policy started", ]); }); @@ -658,21 +584,15 @@ describe("in-place updates", () => { await sim.update(app2Dir); expect(simTraces(sim)).toEqual([ - "root/Bucket1 started", - "root/Bucket1/Policy started", "root/OnDeploy/Function started", - "root/OnDeploy/Function/Policy started", + "root/Bucket1 started", "root/OnDeploy started", - "Update: 0 added, 3 updated, 0 deleted", + "Update: 0 added, 2 updated, 0 deleted", "root/OnDeploy stopped", - "root/OnDeploy/Function/Policy stopped", "root/OnDeploy/Function stopped", - "root/Bucket1/Policy stopped", "root/Bucket1 stopped", - "root/Bucket1 started", - "root/Bucket1/Policy started", "root/OnDeploy/Function started", - "root/OnDeploy/Function/Policy started", + "root/Bucket1 started", "root/OnDeploy started", ]); }); @@ -692,12 +612,9 @@ describe("in-place updates", () => { expect(simTraces(sim)).toEqual([ "root/Function started", - "root/Function/Policy started", "Update: 0 added, 1 updated, 0 deleted", - "root/Function/Policy stopped", "root/Function stopped", "root/Function started", - "root/Function/Policy started", ]); }); @@ -716,42 +633,9 @@ describe("in-place updates", () => { expect(simTraces(sim)).toEqual([ "root/Service started", - "root/Service/Policy started", - "root/Service/Helper started", "Update: 0 added, 1 updated, 0 deleted", - "root/Service/Helper stopped", - "root/Service/Policy stopped", "root/Service stopped", "root/Service started", - "root/Service/Policy started", - "root/Service/Helper started", - ]); - }); - - test("cloud.OnDeploy is always replaced", async () => { - const app = new SimApp(); - const handler = Testing.makeHandler(`async handle() {}`); - new OnDeploy(app, "OnDeploy", handler); - - const sim = await app.startSimulator(); - - const app2 = new SimApp(); - new OnDeploy(app2, "OnDeploy", handler); - - const app2Dir = app2.synth(); - await sim.update(app2Dir); - - expect(simTraces(sim)).toEqual([ - "root/OnDeploy/Function started", - "root/OnDeploy/Function/Policy started", - "root/OnDeploy started", - "Update: 0 added, 2 updated, 0 deleted", - "root/OnDeploy stopped", - "root/OnDeploy/Function/Policy stopped", - "root/OnDeploy/Function stopped", - "root/OnDeploy/Function started", - "root/OnDeploy/Function/Policy started", - "root/OnDeploy started", ]); }); }); diff --git a/libs/wingsdk/test/target-sim/__snapshots__/api.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/api.test.ts.snap index d0341d9c345..ba00408b0af 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/api.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/api.test.ts.snap @@ -47,31 +47,6 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, - { - "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", - "attrs": {}, - "path": "root/my_api/Policy", - "props": { - "principal": "\${wsim#root/my_api#attrs.handle}", - "statements": [ - { - "operation": "invoke", - "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - }, - ], - }, - "type": "@winglang/sdk.sim.Policy", - }, - { - "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", - "attrs": {}, - "path": "root/my_api/OnRequestHandler0/Policy", - "props": { - "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -221,14 +196,6 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -268,21 +235,6 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/OnRequestHandler0/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -296,19 +248,6 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/Policy", - }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -340,15 +279,11 @@ exports[`api handler can read the request params 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", - "root/my_api/Policy started", - "root/my_api/OnRequestHandler0/Policy started", "root/my_api/ApiEventMapping0 started", "Processing "GET /hello" params={}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/hello\\",\\"query\\":{\\"foo\\":\\"bar\\",\\"bar\\":\\"baz\\"},\\"vars\\":{}}").", "GET /hello - 200.", "root/my_api/Endpoint stopped", - "root/my_api/Policy stopped", - "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "Closing server on http://127.0.0.1:", @@ -398,31 +333,6 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, - { - "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", - "attrs": {}, - "path": "root/my_api/Policy", - "props": { - "principal": "\${wsim#root/my_api#attrs.handle}", - "statements": [ - { - "operation": "invoke", - "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - }, - ], - }, - "type": "@winglang/sdk.sim.Policy", - }, - { - "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", - "attrs": {}, - "path": "root/my_api/OnRequestHandler0/Policy", - "props": { - "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -558,14 +468,6 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -605,21 +507,6 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/OnRequestHandler0/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -633,19 +520,6 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/Policy", - }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -677,15 +551,11 @@ exports[`api handler can read the request path 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", - "root/my_api/Policy started", - "root/my_api/OnRequestHandler0/Policy started", "root/my_api/ApiEventMapping0 started", "Processing "GET /hello" params={}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/hello\\",\\"query\\":{},\\"vars\\":{}}").", "GET /hello - 200.", "root/my_api/Endpoint stopped", - "root/my_api/Policy stopped", - "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "Closing server on http://127.0.0.1:", @@ -735,31 +605,6 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, - { - "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", - "attrs": {}, - "path": "root/my_api/Policy", - "props": { - "principal": "\${wsim#root/my_api#attrs.handle}", - "statements": [ - { - "operation": "invoke", - "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - }, - ], - }, - "type": "@winglang/sdk.sim.Policy", - }, - { - "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", - "attrs": {}, - "path": "root/my_api/OnRequestHandler0/Policy", - "props": { - "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -895,14 +740,6 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -942,21 +779,6 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/OnRequestHandler0/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -970,19 +792,6 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/Policy", - }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -1014,15 +823,11 @@ exports[`api handler can set response headers 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", - "root/my_api/Policy started", - "root/my_api/OnRequestHandler0/Policy started", "root/my_api/ApiEventMapping0 started", "Processing "GET /hello" params={}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"foo\\":\\"bar\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/hello\\",\\"query\\":{},\\"vars\\":{}}").", "GET /hello - 200.", "root/my_api/Endpoint stopped", - "root/my_api/Policy stopped", - "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "Closing server on http://127.0.0.1:", @@ -1072,31 +877,6 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, - { - "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", - "attrs": {}, - "path": "root/my_api/Policy", - "props": { - "principal": "\${wsim#root/my_api#attrs.handle}", - "statements": [ - { - "operation": "invoke", - "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - }, - ], - }, - "type": "@winglang/sdk.sim.Policy", - }, - { - "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", - "attrs": {}, - "path": "root/my_api/OnRequestHandler0/Policy", - "props": { - "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -1232,14 +1012,6 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1279,21 +1051,6 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/OnRequestHandler0/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1307,19 +1064,6 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/Policy", - }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -1351,15 +1095,11 @@ exports[`api response returns Content-Type header from inflight 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", - "root/my_api/Policy started", - "root/my_api/OnRequestHandler0/Policy started", "root/my_api/ApiEventMapping0 started", "Processing "GET /hello" params={}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/hello\\",\\"query\\":{},\\"vars\\":{}}").", "GET /hello - 200.", "root/my_api/Endpoint stopped", - "root/my_api/Policy stopped", - "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "Closing server on http://127.0.0.1:", @@ -1409,31 +1149,6 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, - { - "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", - "attrs": {}, - "path": "root/my_api/Policy", - "props": { - "principal": "\${wsim#root/my_api#attrs.handle}", - "statements": [ - { - "operation": "invoke", - "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - }, - ], - }, - "type": "@winglang/sdk.sim.Policy", - }, - { - "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", - "attrs": {}, - "path": "root/my_api/OnRequestHandler0/Policy", - "props": { - "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -1569,14 +1284,6 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1616,21 +1323,6 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/OnRequestHandler0/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1644,19 +1336,6 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/Policy", - }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -1688,15 +1367,11 @@ exports[`api response returns default Content-Type header 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", - "root/my_api/Policy started", - "root/my_api/OnRequestHandler0/Policy started", "root/my_api/ApiEventMapping0 started", "Processing "GET /hello" params={}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/hello\\",\\"query\\":{},\\"vars\\":{}}").", "GET /hello - 200.", "root/my_api/Endpoint stopped", - "root/my_api/Policy stopped", - "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "Closing server on http://127.0.0.1:", @@ -1746,31 +1421,6 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, - { - "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", - "attrs": {}, - "path": "root/my_api/Policy", - "props": { - "principal": "\${wsim#root/my_api#attrs.handle}", - "statements": [ - { - "operation": "invoke", - "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - }, - ], - }, - "type": "@winglang/sdk.sim.Policy", - }, - { - "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", - "attrs": {}, - "path": "root/my_api/OnRequestHandler0/Policy", - "props": { - "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -1906,14 +1556,6 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1953,21 +1595,6 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/OnRequestHandler0/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1981,19 +1608,6 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/Policy", - }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -2025,8 +1639,6 @@ exports[`api supports every method type 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", - "root/my_api/Policy started", - "root/my_api/OnRequestHandler0/Policy started", "root/my_api/ApiEventMapping0 started", "Processing "GET /hello" params={}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/hello\\",\\"query\\":{},\\"vars\\":{}}").", @@ -2050,8 +1662,6 @@ exports[`api supports every method type 1`] = ` "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\",\\"content-length\\":\\"0\\"},\\"body\\":\\"\\",\\"method\\":\\"PATCH\\",\\"path\\":\\"/hello\\",\\"query\\":{},\\"vars\\":{}}").", "PATCH /hello - 200.", "root/my_api/Endpoint stopped", - "root/my_api/Policy stopped", - "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "Closing server on http://127.0.0.1:", @@ -2131,31 +1741,6 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, - { - "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", - "attrs": {}, - "path": "root/my_api/Policy", - "props": { - "principal": "\${wsim#root/my_api#attrs.handle}", - "statements": [ - { - "operation": "invoke", - "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - }, - ], - }, - "type": "@winglang/sdk.sim.Policy", - }, - { - "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", - "attrs": {}, - "path": "root/my_api/OnRequestHandler0/Policy", - "props": { - "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -2375,14 +1960,6 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -2422,21 +1999,6 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/OnRequestHandler0/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -2450,19 +2012,6 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/Policy", - }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -2494,15 +2043,11 @@ exports[`api with 'name' & 'age' parameter 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", - "root/my_api/Policy started", - "root/my_api/OnRequestHandler0/Policy started", "root/my_api/ApiEventMapping0 started", "Processing "GET /:name/:age" params={"name":"akhil","age":"23"}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/akhil/23\\",\\"query\\":{},\\"vars\\":{\\"name\\":\\"akhil\\",\\"age\\":\\"23\\"}}").", "GET /:name/:age - 200.", "root/my_api/Endpoint stopped", - "root/my_api/Policy stopped", - "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "Closing server on http://127.0.0.1:", @@ -2552,31 +2097,6 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, - { - "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", - "attrs": {}, - "path": "root/my_api/Policy", - "props": { - "principal": "\${wsim#root/my_api#attrs.handle}", - "statements": [ - { - "operation": "invoke", - "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - }, - ], - }, - "type": "@winglang/sdk.sim.Policy", - }, - { - "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", - "attrs": {}, - "path": "root/my_api/OnRequestHandler0/Policy", - "props": { - "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -2729,14 +2249,6 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -2776,21 +2288,6 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/OnRequestHandler0/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -2804,19 +2301,6 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/Policy", - }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -2848,15 +2332,11 @@ exports[`api with 'name' parameter 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", - "root/my_api/Policy started", - "root/my_api/OnRequestHandler0/Policy started", "root/my_api/ApiEventMapping0 started", "Processing "GET /:name" params={"name":"akhil"}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/akhil\\",\\"query\\":{},\\"vars\\":{\\"name\\":\\"akhil\\"}}").", "GET /:name - 200.", "root/my_api/Endpoint stopped", - "root/my_api/Policy stopped", - "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "Closing server on http://127.0.0.1:", @@ -2906,31 +2386,6 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, - { - "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", - "attrs": {}, - "path": "root/my_api/Policy", - "props": { - "principal": "\${wsim#root/my_api#attrs.handle}", - "statements": [ - { - "operation": "invoke", - "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - }, - ], - }, - "type": "@winglang/sdk.sim.Policy", - }, - { - "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", - "attrs": {}, - "path": "root/my_api/OnRequestHandler0/Policy", - "props": { - "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -3075,14 +2530,6 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -3122,21 +2569,6 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/OnRequestHandler0/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -3150,19 +2582,6 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/Policy", - }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -3230,31 +2649,6 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, - { - "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", - "attrs": {}, - "path": "root/my_api/Policy", - "props": { - "principal": "\${wsim#root/my_api#attrs.handle}", - "statements": [ - { - "operation": "invoke", - "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - }, - ], - }, - "type": "@winglang/sdk.sim.Policy", - }, - { - "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", - "attrs": {}, - "path": "root/my_api/OnRequestHandler0/Policy", - "props": { - "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -3406,14 +2800,6 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -3453,21 +2839,6 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/OnRequestHandler0/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -3481,19 +2852,6 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/Policy", - }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -3525,11 +2883,8 @@ exports[`api with multiple methods on same route 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", - "root/my_api/OnRequestHandler1 started", - "root/my_api/Policy started", - "root/my_api/OnRequestHandler0/Policy started", "root/my_api/ApiEventMapping0 started", - "root/my_api/OnRequestHandler1/Policy started", + "root/my_api/OnRequestHandler1 started", "root/my_api/ApiEventMapping1 started", "Processing "GET /hello" params={}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/hello\\",\\"query\\":{},\\"vars\\":{}}").", @@ -3538,14 +2893,11 @@ exports[`api with multiple methods on same route 1`] = ` "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\",\\"content-length\\":\\"0\\"},\\"body\\":\\"\\",\\"method\\":\\"POST\\",\\"path\\":\\"/hello\\",\\"query\\":{},\\"vars\\":{}}").", "POST /hello - 200.", "root/my_api/Endpoint stopped", - "root/my_api/Policy stopped", - "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "root/my_api/ApiEventMapping1 stopped", "Closing server on http://127.0.0.1:", "root/my_api stopped", - "root/my_api/OnRequestHandler1/Policy stopped", "root/my_api/OnRequestHandler1 stopped", ] `; @@ -3614,35 +2966,6 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, - { - "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", - "attrs": {}, - "path": "root/my_api/Policy", - "props": { - "principal": "\${wsim#root/my_api#attrs.handle}", - "statements": [ - { - "operation": "invoke", - "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - }, - { - "operation": "invoke", - "resourceHandle": "\${wsim#root/my_api/OnRequestHandler1#attrs.handle}", - }, - ], - }, - "type": "@winglang/sdk.sim.Policy", - }, - { - "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", - "attrs": {}, - "path": "root/my_api/OnRequestHandler0/Policy", - "props": { - "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -3713,16 +3036,6 @@ return class Handler { }, "type": "@winglang/sdk.sim.EventMapping", }, - { - "addr": "c8603fc16b367fc8cb05634fbb47b4a1e7f873b298", - "attrs": {}, - "path": "root/my_api/OnRequestHandler1/Policy", - "props": { - "principal": "\${wsim#root/my_api/OnRequestHandler1#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c84819d7712e30f38cf7731fcfbe96cbc39c7e75d3", "attrs": {}, @@ -3833,14 +3146,6 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -3891,21 +3196,6 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/OnRequestHandler0/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -3920,21 +3210,6 @@ return class Handler { "path": "root/my_api/OnRequestHandler0", }, "OnRequestHandler1": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/OnRequestHandler1/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -3948,19 +3223,6 @@ return class Handler { "id": "OnRequestHandler1", "path": "root/my_api/OnRequestHandler1", }, - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/Policy", - }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -3992,11 +3254,8 @@ exports[`api with multiple routes 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", - "root/my_api/OnRequestHandler1 started", - "root/my_api/Policy started", - "root/my_api/OnRequestHandler0/Policy started", "root/my_api/ApiEventMapping0 started", - "root/my_api/OnRequestHandler1/Policy started", + "root/my_api/OnRequestHandler1 started", "root/my_api/ApiEventMapping1 started", "Processing "GET /hello/world" params={}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/hello/world\\",\\"query\\":{},\\"vars\\":{}}").", @@ -4005,14 +3264,11 @@ exports[`api with multiple routes 1`] = ` "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/hello/wingnuts\\",\\"query\\":{},\\"vars\\":{}}").", "GET /hello/wingnuts - 200.", "root/my_api/Endpoint stopped", - "root/my_api/Policy stopped", - "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "root/my_api/ApiEventMapping1 stopped", "Closing server on http://127.0.0.1:", "root/my_api stopped", - "root/my_api/OnRequestHandler1/Policy stopped", "root/my_api/OnRequestHandler1 stopped", ] `; @@ -4081,35 +3337,6 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, - { - "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", - "attrs": {}, - "path": "root/my_api/Policy", - "props": { - "principal": "\${wsim#root/my_api#attrs.handle}", - "statements": [ - { - "operation": "invoke", - "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - }, - { - "operation": "invoke", - "resourceHandle": "\${wsim#root/my_api/OnRequestHandler1#attrs.handle}", - }, - ], - }, - "type": "@winglang/sdk.sim.Policy", - }, - { - "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", - "attrs": {}, - "path": "root/my_api/OnRequestHandler0/Policy", - "props": { - "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -4182,16 +3409,6 @@ return class Handler { }, "type": "@winglang/sdk.sim.EventMapping", }, - { - "addr": "c8603fc16b367fc8cb05634fbb47b4a1e7f873b298", - "attrs": {}, - "path": "root/my_api/OnRequestHandler1/Policy", - "props": { - "principal": "\${wsim#root/my_api/OnRequestHandler1#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c84819d7712e30f38cf7731fcfbe96cbc39c7e75d3", "attrs": {}, @@ -4302,14 +3519,6 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -4360,21 +3569,6 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/OnRequestHandler0/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -4389,21 +3583,6 @@ return class Handler { "path": "root/my_api/OnRequestHandler0", }, "OnRequestHandler1": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/OnRequestHandler1/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -4417,19 +3596,6 @@ return class Handler { "id": "OnRequestHandler1", "path": "root/my_api/OnRequestHandler1", }, - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/Policy", - }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -4461,15 +3627,11 @@ exports[`api with one GET route 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", - "root/my_api/Policy started", - "root/my_api/OnRequestHandler0/Policy started", "root/my_api/ApiEventMapping0 started", "Processing "GET /hello" params={}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/hello\\",\\"query\\":{},\\"vars\\":{}}").", "GET /hello - 200.", "root/my_api/Endpoint stopped", - "root/my_api/Policy stopped", - "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "Closing server on http://127.0.0.1:", @@ -4519,31 +3681,6 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, - { - "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", - "attrs": {}, - "path": "root/my_api/Policy", - "props": { - "principal": "\${wsim#root/my_api#attrs.handle}", - "statements": [ - { - "operation": "invoke", - "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - }, - ], - }, - "type": "@winglang/sdk.sim.Policy", - }, - { - "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", - "attrs": {}, - "path": "root/my_api/OnRequestHandler0/Policy", - "props": { - "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -4679,14 +3816,6 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -4726,21 +3855,6 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/OnRequestHandler0/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -4754,19 +3868,6 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/Policy", - }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -4798,15 +3899,11 @@ exports[`api with one GET route with request params 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", - "root/my_api/Policy started", - "root/my_api/OnRequestHandler0/Policy started", "root/my_api/ApiEventMapping0 started", "Processing "GET /users/:name" params={"name":"tsuf"}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/users/tsuf\\",\\"query\\":{},\\"vars\\":{\\"name\\":\\"tsuf\\"}}").", "GET /users/:name - 200.", "root/my_api/Endpoint stopped", - "root/my_api/Policy stopped", - "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "Closing server on http://127.0.0.1:", @@ -4856,31 +3953,6 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, - { - "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", - "attrs": {}, - "path": "root/my_api/Policy", - "props": { - "principal": "\${wsim#root/my_api#attrs.handle}", - "statements": [ - { - "operation": "invoke", - "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - }, - ], - }, - "type": "@winglang/sdk.sim.Policy", - }, - { - "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", - "attrs": {}, - "path": "root/my_api/OnRequestHandler0/Policy", - "props": { - "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -5025,14 +4097,6 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -5072,21 +4136,6 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/OnRequestHandler0/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -5100,19 +4149,6 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/Policy", - }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -5144,15 +4180,11 @@ exports[`api with one POST route, with body 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", - "root/my_api/Policy started", - "root/my_api/OnRequestHandler0/Policy started", "root/my_api/ApiEventMapping0 started", "Processing "POST /hello" params={}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"content-type\\":\\"application/json\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\",\\"content-length\\":\\"25\\"},\\"body\\":\\"{\\\\\\"message\\\\\\":\\\\\\"hello world\\\\\\"}\\",\\"method\\":\\"POST\\",\\"path\\":\\"/hello\\",\\"query\\":{},\\"vars\\":{}}").", "POST /hello - 200.", "root/my_api/Endpoint stopped", - "root/my_api/Policy stopped", - "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "Closing server on http://127.0.0.1:", @@ -5202,31 +4234,6 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, - { - "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", - "attrs": {}, - "path": "root/my_api/Policy", - "props": { - "principal": "\${wsim#root/my_api#attrs.handle}", - "statements": [ - { - "operation": "invoke", - "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - }, - ], - }, - "type": "@winglang/sdk.sim.Policy", - }, - { - "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", - "attrs": {}, - "path": "root/my_api/OnRequestHandler0/Policy", - "props": { - "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -5362,14 +4369,6 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -5409,21 +4408,6 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/OnRequestHandler0/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -5437,19 +4421,6 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/Policy", - }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -5506,16 +4477,6 @@ exports[`create an api 1`] = ` }, "type": "@winglang/sdk.cloud.Endpoint", }, - { - "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", - "attrs": {}, - "path": "root/my_api/Policy", - "props": { - "principal": "\${wsim#root/my_api#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -5591,14 +4552,6 @@ exports[`create an api 1`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -5626,19 +4579,6 @@ exports[`create an api 1`] = ` "id": "Endpoint", "path": "root/my_api/Endpoint", }, - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_api/Policy", - }, }, "constructInfo": { "fqn": "constructs.Construct", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/bucket.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/bucket.test.ts.snap index 56c148f70d8..a1f5c77fefd 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/bucket.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/bucket.test.ts.snap @@ -6,60 +6,44 @@ exports[`bucket on event creates 3 topics, and sends the right event and key in "root/my_bucket/onupdate started", "root/my_bucket/ondelete started", "root/my_bucket started", - "root/my_bucket/Policy started", "root/log_bucket started", "root/my_bucket/oncreate/OnMessage0 started", - "root/my_bucket/oncreate/Policy started", - "root/my_bucket/oncreate/OnMessage0/Policy started", "root/my_bucket/oncreate/TopicEventMapping0 started", "root/my_bucket/onupdate/OnMessage0 started", - "root/my_bucket/onupdate/Policy started", - "root/my_bucket/onupdate/OnMessage0/Policy started", "root/my_bucket/onupdate/TopicEventMapping0 started", "root/my_bucket/ondelete/OnMessage0 started", - "root/my_bucket/ondelete/Policy started", - "root/my_bucket/ondelete/OnMessage0/Policy started", "root/my_bucket/ondelete/TopicEventMapping0 started", - "root/log_bucket/Policy started", "Publish (message=a).", - "Sending message (message=a, subscriber=sim-6).", + "Sending message (message=a, subscriber=sim-5).", "InvokeAsync (payload="a").", "Put (key=a).", "Put (key=a).", "I am done", "Get (key=a).", "Publish (message=a).", - "Sending message (message=a, subscriber=sim-10).", + "Sending message (message=a, subscriber=sim-7).", "InvokeAsync (payload="a").", "Put (key=a).", "Put (key=a).", "I am done", "Get (key=a).", "Publish (message=a).", - "Sending message (message=a, subscriber=sim-14).", + "Sending message (message=a, subscriber=sim-9).", "InvokeAsync (payload="a").", "Delete (key=a).", "Put (key=a).", "I am done", "Get (key=a).", - "root/my_bucket/Policy stopped", "root/my_bucket stopped", - "root/my_bucket/oncreate/Policy stopped", "root/my_bucket/oncreate/TopicEventMapping0 stopped", "root/my_bucket/oncreate stopped", - "root/my_bucket/onupdate/Policy stopped", "root/my_bucket/onupdate/TopicEventMapping0 stopped", "root/my_bucket/onupdate stopped", - "root/my_bucket/ondelete/Policy stopped", "root/my_bucket/ondelete/TopicEventMapping0 stopped", "root/my_bucket/ondelete stopped", - "root/my_bucket/oncreate/OnMessage0/Policy stopped", "root/my_bucket/oncreate/OnMessage0 stopped", - "root/my_bucket/onupdate/OnMessage0/Policy stopped", "root/my_bucket/onupdate/OnMessage0 stopped", - "root/my_bucket/ondelete/OnMessage0/Policy stopped", "root/my_bucket/ondelete/OnMessage0 stopped", - "root/log_bucket/Policy stopped", "root/log_bucket stopped", ] `; @@ -68,11 +52,9 @@ exports[`can add file in preflight 1`] = ` [ "Adding object from preflight (key=test.txt).", "root/my_bucket started", - "root/my_bucket/Policy started", "Get (key=test.txt).", "Get (key=test.txt).", "List (prefix=null).", - "root/my_bucket/Policy stopped", "root/my_bucket stopped", ] `; @@ -98,16 +80,6 @@ exports[`can add file in preflight 2`] = ` }, "type": "@winglang/sdk.cloud.Bucket", }, - { - "addr": "c8b5ba55132964ee19331fb9f46241560e67fed76b", - "attrs": {}, - "path": "root/my_bucket/Policy", - "props": { - "principal": "\${wsim#root/my_bucket#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -183,14 +155,6 @@ exports[`can add file in preflight 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -205,21 +169,6 @@ exports[`can add file in preflight 2`] = ` "tree": { "children": { "my_bucket": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_bucket/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -248,11 +197,9 @@ exports[`can add object in preflight 1`] = ` [ "Adding object from preflight (key=greeting.txt).", "root/my_bucket started", - "root/my_bucket/Policy started", "Get (key=greeting.txt).", "Get (key=greeting.txt).", "List (prefix=null).", - "root/my_bucket/Policy stopped", "root/my_bucket stopped", ] `; @@ -278,16 +225,6 @@ exports[`can add object in preflight 2`] = ` }, "type": "@winglang/sdk.cloud.Bucket", }, - { - "addr": "c8b5ba55132964ee19331fb9f46241560e67fed76b", - "attrs": {}, - "path": "root/my_bucket/Policy", - "props": { - "principal": "\${wsim#root/my_bucket#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -363,14 +300,6 @@ exports[`can add object in preflight 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -385,21 +314,6 @@ exports[`can add object in preflight 2`] = ` "tree": { "children": { "my_bucket": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_bucket/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -443,16 +357,6 @@ exports[`create a bucket 1`] = ` }, "type": "@winglang/sdk.cloud.Bucket", }, - { - "addr": "c8b5ba55132964ee19331fb9f46241560e67fed76b", - "attrs": {}, - "path": "root/my_bucket/Policy", - "props": { - "principal": "\${wsim#root/my_bucket#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -528,14 +432,6 @@ exports[`create a bucket 1`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -550,21 +446,6 @@ exports[`create a bucket 1`] = ` "tree": { "children": { "my_bucket": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_bucket/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -592,9 +473,7 @@ exports[`create a bucket 1`] = ` exports[`get invalid object throws an error 1`] = ` [ "root/my_bucket started", - "root/my_bucket/Policy started", "Get (key=unknown.txt).", - "root/my_bucket/Policy stopped", "root/my_bucket stopped", ] `; @@ -618,16 +497,6 @@ exports[`get invalid object throws an error 2`] = ` }, "type": "@winglang/sdk.cloud.Bucket", }, - { - "addr": "c8b5ba55132964ee19331fb9f46241560e67fed76b", - "attrs": {}, - "path": "root/my_bucket/Policy", - "props": { - "principal": "\${wsim#root/my_bucket#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -703,14 +572,6 @@ exports[`get invalid object throws an error 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -725,21 +586,6 @@ exports[`get invalid object throws an error 2`] = ` "tree": { "children": { "my_bucket": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_bucket/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -767,14 +613,12 @@ exports[`get invalid object throws an error 2`] = ` exports[`list respects prefixes 1`] = ` [ "root/my_bucket started", - "root/my_bucket/Policy started", "Put (key=path/dir1/file1.txt).", "Put (key=path/dir2/file2.txt).", "List (prefix=null).", "List (prefix=path).", "List (prefix=path/dir1).", "List (prefix=path/dir2).", - "root/my_bucket/Policy stopped", "root/my_bucket stopped", ] `; @@ -782,7 +626,6 @@ exports[`list respects prefixes 1`] = ` exports[`objects can have keys that look like directories 1`] = ` [ "root/my_bucket started", - "root/my_bucket/Policy started", "Put (key=foo).", "Put (key=foo/).", "Put (key=foo/bar).", @@ -794,7 +637,6 @@ exports[`objects can have keys that look like directories 1`] = ` "List (prefix=foo/bar).", "List (prefix=foo/bar/).", "List (prefix=foo/bar/baz).", - "root/my_bucket/Policy stopped", "root/my_bucket stopped", ] `; @@ -802,14 +644,12 @@ exports[`objects can have keys that look like directories 1`] = ` exports[`put and get metadata of objects from bucket 1`] = ` [ "root/my_bucket started", - "root/my_bucket/Policy started", "Put (key=file1.main.w).", "Put (key=file2.txt).", "Put (key=file3.txt).", "Metadata (key=file1.main.w).", "Metadata (key=file2.txt).", "Metadata (key=file3.txt).", - "root/my_bucket/Policy stopped", "root/my_bucket stopped", ] `; @@ -817,10 +657,8 @@ exports[`put and get metadata of objects from bucket 1`] = ` exports[`put and get object from bucket 1`] = ` [ "root/my_bucket started", - "root/my_bucket/Policy started", "Put (key=greeting.txt).", "Get (key=greeting.txt).", - "root/my_bucket/Policy stopped", "root/my_bucket stopped", ] `; @@ -828,12 +666,10 @@ exports[`put and get object from bucket 1`] = ` exports[`put multiple json objects and list all from bucket 1`] = ` [ "root/my_bucket started", - "root/my_bucket/Policy started", "Put Json (key=greeting1.json).", "Put Json (key=greeting2.json).", "Put Json (key=greeting3.json).", "List (prefix=null).", - "root/my_bucket/Policy stopped", "root/my_bucket stopped", ] `; @@ -841,12 +677,10 @@ exports[`put multiple json objects and list all from bucket 1`] = ` exports[`put multiple objects and list all from bucket 1`] = ` [ "root/my_bucket started", - "root/my_bucket/Policy started", "Put (key=greeting1.txt).", "Put (key=greeting2.txt).", "Put (key=greeting3.txt).", "List (prefix=null).", - "root/my_bucket/Policy stopped", "root/my_bucket stopped", ] `; @@ -854,10 +688,8 @@ exports[`put multiple objects and list all from bucket 1`] = ` exports[`remove object from a bucket 1`] = ` [ "root/my_bucket started", - "root/my_bucket/Policy started", "Put (key=unknown.txt).", "Delete (key=unknown.txt).", - "root/my_bucket/Policy stopped", "root/my_bucket stopped", ] `; @@ -865,10 +697,8 @@ exports[`remove object from a bucket 1`] = ` exports[`remove object from a bucket with mustExist as option 1`] = ` [ "root/my_bucket started", - "root/my_bucket/Policy started", "Put (key=unknown.txt).", "Delete (key=unknown.txt).", - "root/my_bucket/Policy stopped", "root/my_bucket stopped", ] `; @@ -877,23 +707,17 @@ exports[`removing a key will call onDelete method 1`] = ` [ "root/my_bucket/ondelete started", "root/my_bucket started", - "root/my_bucket/Policy started", "root/my_bucket/ondelete/OnMessage0 started", - "root/my_bucket/ondelete/Policy started", - "root/my_bucket/ondelete/OnMessage0/Policy started", "root/my_bucket/ondelete/TopicEventMapping0 started", "Put (key=unknown.txt).", "Publish (message=unknown.txt).", - "Sending message (message=unknown.txt, subscriber=sim-3).", + "Sending message (message=unknown.txt, subscriber=sim-2).", "InvokeAsync (payload="unknown.txt").", "Delete (key=unknown.txt).", "Received unknown.txt", - "root/my_bucket/Policy stopped", "root/my_bucket stopped", - "root/my_bucket/ondelete/Policy stopped", "root/my_bucket/ondelete/TopicEventMapping0 stopped", "root/my_bucket/ondelete stopped", - "root/my_bucket/ondelete/OnMessage0/Policy stopped", "root/my_bucket/ondelete/OnMessage0 stopped", ] `; @@ -902,23 +726,12 @@ exports[`update an object in bucket 1`] = ` [ "root/my_bucket/oncreate started", "root/my_bucket started", - "root/my_bucket/Policy started", "root/my_bucket/oncreate/OnMessage0 started", - "root/my_bucket/oncreate/Policy started", - "root/my_bucket/oncreate/OnMessage0/Policy started", "root/my_bucket/oncreate/TopicEventMapping0 started", "Publish (message=1.txt).", - "Sending message (message=1.txt, subscriber=sim-3).", + "Sending message (message=1.txt, subscriber=sim-2).", "InvokeAsync (payload="1.txt").", "Put (key=1.txt).", "Put (key=1.txt).", - "I am done", - "root/my_bucket/Policy stopped", - "root/my_bucket stopped", - "root/my_bucket/oncreate/Policy stopped", - "root/my_bucket/oncreate/TopicEventMapping0 stopped", - "root/my_bucket/oncreate stopped", - "root/my_bucket/oncreate/OnMessage0/Policy stopped", - "root/my_bucket/oncreate/OnMessage0 stopped", ] `; diff --git a/libs/wingsdk/test/target-sim/__snapshots__/counter.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/counter.test.ts.snap index 6b2d6b9b8cc..0d77770e98b 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/counter.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/counter.test.ts.snap @@ -92,14 +92,6 @@ exports[`create a counter 1`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -241,14 +233,6 @@ exports[`dec 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -390,14 +374,6 @@ exports[`inc 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -539,14 +515,6 @@ exports[`key dec 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -688,14 +656,6 @@ exports[`key inc 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -835,14 +795,6 @@ exports[`key set to new value 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -982,14 +934,6 @@ exports[`set to new value 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/file-counter.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/file-counter.test.ts.snap index 9d11f3f638d..6371f1c2e57 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/file-counter.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/file-counter.test.ts.snap @@ -28,11 +28,7 @@ counter: (function() { if (!simulatorUrl) { throw new Error("Missing environment variable: WING_SIMULATOR_URL"); } - const caller = process.env.WING_SIMULATOR_CALLER; - if (!caller) { - throw new Error("Missing environment variable: WING_SIMULATOR_CALLER"); - } - return require("@winglang/sdk/lib/simulator/client").makeSimulatorClient(simulatorUrl, handle, caller); + return require("@winglang/sdk/lib/simulator/client").makeSimulatorClient(simulatorUrl, handle); })(), bucket: (function() { let handle = process.env.BUCKET_HANDLE_5f2a41c8; @@ -43,11 +39,7 @@ bucket: (function() { if (!simulatorUrl) { throw new Error("Missing environment variable: WING_SIMULATOR_URL"); } - const caller = process.env.WING_SIMULATOR_CALLER; - if (!caller) { - throw new Error("Missing environment variable: WING_SIMULATOR_CALLER"); - } - return require("@winglang/sdk/lib/simulator/client").makeSimulatorClient(simulatorUrl, handle, caller); + return require("@winglang/sdk/lib/simulator/client").makeSimulatorClient(simulatorUrl, handle); })() }), args: {} })); return await $handler.handle(event); @@ -74,54 +66,6 @@ bucket: (function() { }, "simulator.json": { "resources": [ - { - "addr": "c86eb36bbe6e764a632afaaea5db2d4bd693c92624", - "attrs": {}, - "path": "root/HelloWorld/Bucket/Policy", - "props": { - "principal": "\${wsim#root/HelloWorld/Bucket#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, - { - "addr": "c86b009930462795eeb90e647a56dbfc5356d9ea80", - "attrs": {}, - "path": "root/HelloWorld/Queue/Policy", - "props": { - "principal": "\${wsim#root/HelloWorld/Queue#attrs.handle}", - "statements": [ - { - "operation": "invoke", - "resourceHandle": "\${wsim#root/HelloWorld/Queue/SetConsumer0#attrs.handle}", - }, - { - "operation": "hasAvailableWorkers", - "resourceHandle": "\${wsim#root/HelloWorld/Queue/SetConsumer0#attrs.handle}", - }, - ], - }, - "type": "@winglang/sdk.sim.Policy", - }, - { - "addr": "c88f4eae8103e33f1cf696aa3dad78ce4f1e5a2caa", - "attrs": {}, - "path": "root/HelloWorld/Queue/SetConsumer0/Policy", - "props": { - "principal": "\${wsim#root/HelloWorld/Queue/SetConsumer0#attrs.handle}", - "statements": [ - { - "operation": "inc", - "resourceHandle": "\${wsim#root/HelloWorld/Counter#attrs.handle}", - }, - { - "operation": "put", - "resourceHandle": "\${wsim#root/HelloWorld/Bucket#attrs.handle}", - }, - ], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c87855e817fa3df0d5ce8ae290bf53c8ce4ecd8d46", "attrs": {}, @@ -264,14 +208,6 @@ bucket: (function() { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -288,21 +224,6 @@ bucket: (function() { "HelloWorld": { "children": { "Bucket": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/HelloWorld/Bucket/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -328,19 +249,6 @@ bucket: (function() { }, "Queue": { "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/HelloWorld/Queue/Policy", - }, "QueueEventMapping0": { "constructInfo": { "fqn": "constructs.Construct", @@ -353,21 +261,6 @@ bucket: (function() { "path": "root/HelloWorld/Queue/QueueEventMapping0", }, "SetConsumer0": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/HelloWorld/Queue/SetConsumer0/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/function.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/function.test.ts.snap index 685cdcef273..f15ffe22fb8 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/function.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/function.test.ts.snap @@ -1,5 +1,16 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`__dirname and __filename cannot be used within inflight code 1`] = ` +[ + "root/Function.0 started", + "root/Function.1 started", + "Warning: __dirname and __filename cannot be used within bundled cloud functions. There may be unexpected behavior.", + "Warning: __dirname and __filename cannot be used within bundled cloud functions. There may be unexpected behavior.", + "Invoke (payload=undefined).", + "Invoke (payload=undefined).", +] +`; + exports[`create a function 1`] = ` { ".wing/my_function_c85c4e0e.js": ""use strict"; @@ -53,16 +64,6 @@ async handle(event) { }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c8d421ed6ca2ddf857d835791bcde9240c8682a8d9", - "attrs": {}, - "path": "root/my_function/Policy", - "props": { - "principal": "\${wsim#root/my_function#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -138,14 +139,6 @@ async handle(event) { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -160,21 +153,6 @@ async handle(event) { "tree": { "children": { "my_function": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_function/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -202,9 +180,7 @@ async handle(event) { exports[`invoke function fails 1`] = ` [ "root/my_function started", - "root/my_function/Policy started", "Invoke (payload="{\\"name\\":\\"alice\\"}").", - "root/my_function/Policy stopped", "root/my_function stopped", ] `; @@ -260,16 +236,6 @@ async handle(event) { }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c8d421ed6ca2ddf857d835791bcde9240c8682a8d9", - "attrs": {}, - "path": "root/my_function/Policy", - "props": { - "principal": "\${wsim#root/my_function#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -345,14 +311,6 @@ async handle(event) { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -367,21 +325,6 @@ async handle(event) { "tree": { "children": { "my_function": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_function/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -409,9 +352,7 @@ async handle(event) { exports[`invoke function succeeds 1`] = ` [ "root/my_function started", - "root/my_function/Policy started", "Invoke (payload="{\\"name\\":\\"Alice\\"}").", - "root/my_function/Policy stopped", "root/my_function stopped", ] `; @@ -467,16 +408,6 @@ async handle(event) { }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c8d421ed6ca2ddf857d835791bcde9240c8682a8d9", - "attrs": {}, - "path": "root/my_function/Policy", - "props": { - "principal": "\${wsim#root/my_function#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -552,14 +483,6 @@ async handle(event) { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -574,21 +497,6 @@ async handle(event) { "tree": { "children": { "my_function": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_function/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -616,9 +524,7 @@ async handle(event) { exports[`invoke function with environment variables 1`] = ` [ "root/my_function started", - "root/my_function/Policy started", "Invoke (payload="{\\"name\\":\\"Alice\\"}").", - "root/my_function/Policy stopped", "root/my_function stopped", ] `; @@ -676,16 +582,6 @@ async handle(event) { }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c8d421ed6ca2ddf857d835791bcde9240c8682a8d9", - "attrs": {}, - "path": "root/my_function/Policy", - "props": { - "principal": "\${wsim#root/my_function#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -761,14 +657,6 @@ async handle(event) { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -783,21 +671,6 @@ async handle(event) { "tree": { "children": { "my_function": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_function/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -825,9 +698,7 @@ async handle(event) { exports[`invoke function with process.exit(1) 1`] = ` [ "root/my_function started", - "root/my_function/Policy started", "Invoke (payload="{}").", - "root/my_function/Policy stopped", "root/my_function stopped", ] `; @@ -873,16 +744,6 @@ async handle() { }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c8d421ed6ca2ddf857d835791bcde9240c8682a8d9", - "attrs": {}, - "path": "root/my_function/Policy", - "props": { - "principal": "\${wsim#root/my_function#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -958,14 +819,6 @@ async handle() { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -980,21 +833,6 @@ async handle() { "tree": { "children": { "my_function": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_function/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1128,16 +966,6 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c80ba70b2cdb9a19bee761f329d38a2f8fe60dfd96", - "attrs": {}, - "path": "root/Function.0/Policy", - "props": { - "principal": "\${wsim#root/Function.0#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c89ed254f66166d83153cc0a4952a15be63d47b0d2", "attrs": {}, @@ -1151,16 +979,6 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c82b947659316c604ceae225ba418b0d37542a5ba9", - "attrs": {}, - "path": "root/Function.1/Policy", - "props": { - "principal": "\${wsim#root/Function.1#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c8cd6c39da22910102d0cfeb2cb96f2160fa79e517", "attrs": {}, @@ -1174,16 +992,6 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c84e1c1344ab5edfebbe25048f337b36bf0c9aed39", - "attrs": {}, - "path": "root/Function.2/Policy", - "props": { - "principal": "\${wsim#root/Function.2#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c8badafa75a67ff66740e0c5fbbb392ab574b52b3c", "attrs": {}, @@ -1197,16 +1005,6 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c808a620b5341fa15dc763e8b6ba15ff0ebfcc6240", - "attrs": {}, - "path": "root/Function.3/Policy", - "props": { - "principal": "\${wsim#root/Function.3#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -1282,14 +1080,6 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1304,21 +1094,6 @@ return class Handler { "tree": { "children": { "Function.0": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/Function.0/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1331,21 +1106,6 @@ return class Handler { "path": "root/Function.0", }, "Function.1": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/Function.1/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1358,21 +1118,6 @@ return class Handler { "path": "root/Function.1", }, "Function.2": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/Function.2/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1385,21 +1130,6 @@ return class Handler { "path": "root/Function.2", }, "Function.3": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/Function.3/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/immutable-capture.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/immutable-capture.test.ts.snap index afd9b0a28a7..048de7a441c 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/immutable-capture.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/immutable-capture.test.ts.snap @@ -43,16 +43,6 @@ my_capture: ["hello","dude"] }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", - "attrs": {}, - "path": "root/Function/Policy", - "props": { - "principal": "\${wsim#root/Function#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -128,14 +118,6 @@ my_capture: ["hello","dude"] "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -150,21 +132,6 @@ my_capture: ["hello","dude"] "tree": { "children": { "Function": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/Function/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -232,16 +199,6 @@ my_array: [(new (require("[REDACTED]/wingsdk/src/std/duration.js").Duration)(600 }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", - "attrs": {}, - "path": "root/Function/Policy", - "props": { - "principal": "\${wsim#root/Function#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -317,14 +274,6 @@ my_array: [(new (require("[REDACTED]/wingsdk/src/std/duration.js").Duration)(600 "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -339,21 +288,6 @@ my_array: [(new (require("[REDACTED]/wingsdk/src/std/duration.js").Duration)(600 "tree": { "children": { "Function": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/Function/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -420,16 +354,6 @@ my_array: [new Map([["foo",1],["bar",2]]),new Map([["foo",3],["bar",4]])] }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", - "attrs": {}, - "path": "root/Function/Policy", - "props": { - "principal": "\${wsim#root/Function#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -505,14 +429,6 @@ my_array: [new Map([["foo",1],["bar",2]]),new Map([["foo",3],["bar",4]])] "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -527,21 +443,6 @@ my_array: [new Map([["foo",1],["bar",2]]),new Map([["foo",3],["bar",4]])] "tree": { "children": { "Function": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/Function/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -607,16 +508,6 @@ my_capture: false }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", - "attrs": {}, - "path": "root/Function/Policy", - "props": { - "principal": "\${wsim#root/Function#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -692,14 +583,6 @@ my_capture: false "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -714,21 +597,6 @@ my_capture: false "tree": { "children": { "Function": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/Function/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -796,16 +664,6 @@ my_capture: (new (require("[REDACTED]/wingsdk/src/std/duration.js").Duration)(72 }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", - "attrs": {}, - "path": "root/Function/Policy", - "props": { - "principal": "\${wsim#root/Function#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -881,14 +739,6 @@ my_capture: (new (require("[REDACTED]/wingsdk/src/std/duration.js").Duration)(72 "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -903,21 +753,6 @@ my_capture: (new (require("[REDACTED]/wingsdk/src/std/duration.js").Duration)(72 "tree": { "children": { "Function": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/Function/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -987,16 +822,6 @@ my_capture: new Map([["foo",123],["bar",456]]) }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", - "attrs": {}, - "path": "root/Function/Policy", - "props": { - "principal": "\${wsim#root/Function#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -1072,14 +897,6 @@ my_capture: new Map([["foo",123],["bar",456]]) "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1094,21 +911,6 @@ my_capture: new Map([["foo",123],["bar",456]]) "tree": { "children": { "Function": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/Function/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1180,16 +982,6 @@ my_map: new Map([["foo",[1,2]],["bar",[3,4]]]) }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", - "attrs": {}, - "path": "root/Function/Policy", - "props": { - "principal": "\${wsim#root/Function#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -1265,14 +1057,6 @@ my_map: new Map([["foo",[1,2]],["bar",[3,4]]]) "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1287,21 +1071,6 @@ my_map: new Map([["foo",[1,2]],["bar",[3,4]]]) "tree": { "children": { "Function": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/Function/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1370,16 +1139,6 @@ my_map: new Map([["foo",[(new (require("[REDACTED]/wingsdk/src/std/duration.js") }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", - "attrs": {}, - "path": "root/Function/Policy", - "props": { - "principal": "\${wsim#root/Function#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -1455,14 +1214,6 @@ my_map: new Map([["foo",[(new (require("[REDACTED]/wingsdk/src/std/duration.js") "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1477,21 +1228,6 @@ my_map: new Map([["foo",[(new (require("[REDACTED]/wingsdk/src/std/duration.js") "tree": { "children": { "Function": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/Function/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1557,16 +1293,6 @@ my_capture: 123 }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", - "attrs": {}, - "path": "root/Function/Policy", - "props": { - "principal": "\${wsim#root/Function#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -1642,14 +1368,6 @@ my_capture: 123 "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1664,21 +1382,6 @@ my_capture: 123 "tree": { "children": { "Function": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/Function/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1747,16 +1450,6 @@ my_capture: new Set(["boom","bam","bang"]) }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", - "attrs": {}, - "path": "root/Function/Policy", - "props": { - "principal": "\${wsim#root/Function#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -1832,14 +1525,6 @@ my_capture: new Set(["boom","bam","bang"]) "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1854,21 +1539,6 @@ my_capture: new Set(["boom","bam","bang"]) "tree": { "children": { "Function": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/Function/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1936,16 +1606,6 @@ my_set: new Set([(new (require("[REDACTED]/wingsdk/src/std/duration.js").Duratio }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", - "attrs": {}, - "path": "root/Function/Policy", - "props": { - "principal": "\${wsim#root/Function#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -2021,14 +1681,6 @@ my_set: new Set([(new (require("[REDACTED]/wingsdk/src/std/duration.js").Duratio "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -2043,21 +1695,6 @@ my_set: new Set([(new (require("[REDACTED]/wingsdk/src/std/duration.js").Duratio "tree": { "children": { "Function": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/Function/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -2124,16 +1761,6 @@ my_capture: "bam bam bam" }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", - "attrs": {}, - "path": "root/Function/Policy", - "props": { - "principal": "\${wsim#root/Function#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -2209,14 +1836,6 @@ my_capture: "bam bam bam" "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -2231,21 +1850,6 @@ my_capture: "bam bam bam" "tree": { "children": { "Function": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/Function/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -2314,16 +1918,6 @@ my_capture: {"hello": "dude","world": "cup","foo": "bar",} }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", - "attrs": {}, - "path": "root/Function/Policy", - "props": { - "principal": "\${wsim#root/Function#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -2399,14 +1993,6 @@ my_capture: {"hello": "dude","world": "cup","foo": "bar",} "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -2421,21 +2007,6 @@ my_capture: {"hello": "dude","world": "cup","foo": "bar",} "tree": { "children": { "Function": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/Function/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -2504,16 +2075,6 @@ my_struct: {"foo": new Map([["foo",1],["bar",2]]),"bar": new Map([["foo",3],["ba }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", - "attrs": {}, - "path": "root/Function/Policy", - "props": { - "principal": "\${wsim#root/Function#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -2589,14 +2150,6 @@ my_struct: {"foo": new Map([["foo",1],["bar",2]]),"bar": new Map([["foo",3],["ba "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -2611,21 +2164,6 @@ my_struct: {"foo": new Map([["foo",1],["bar",2]]),"bar": new Map([["foo",3],["ba "tree": { "children": { "Function": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/Function/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/on-deploy.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/on-deploy.test.ts.snap index 8f0db48a5f3..c8e80855916 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/on-deploy.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/on-deploy.test.ts.snap @@ -38,22 +38,11 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c84ce37dba3dd1bd3d5c4ab27cb72c54e2b1a75821", - "attrs": {}, - "path": "root/my_on_deploy/Function/Policy", - "props": { - "principal": "\${wsim#root/my_on_deploy/Function#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c8e2618b976544550a8396a3817f0bad07099f7050", "attrs": {}, "deps": [ "root/my_on_deploy/Function", - "root/my_on_deploy/Function/Policy", ], "path": "root/my_on_deploy", "props": { @@ -136,14 +125,6 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -160,21 +141,6 @@ return class Handler { "my_on_deploy": { "children": { "Function": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_on_deploy/Function/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -215,13 +181,11 @@ return class Handler { exports[`create an OnDeploy 2`] = ` [ "root/my_on_deploy/Function started", - "root/my_on_deploy/Function/Policy started", "super duper success", "Invoke (payload=undefined).", "OnDeploy invoked.", "root/my_on_deploy started", "root/my_on_deploy stopped", - "root/my_on_deploy/Function/Policy stopped", "root/my_on_deploy/Function stopped", ] `; diff --git a/libs/wingsdk/test/target-sim/__snapshots__/queue.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/queue.test.ts.snap index cef3a1a4097..642f485ebdc 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/queue.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/queue.test.ts.snap @@ -18,16 +18,6 @@ exports[`create a queue 1`] = ` }, "type": "@winglang/sdk.cloud.Queue", }, - { - "addr": "c88a4c68047871c2d322479c886423828e8119d85c", - "attrs": {}, - "path": "root/my_queue/Policy", - "props": { - "principal": "\${wsim#root/my_queue#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -103,14 +93,6 @@ exports[`create a queue 1`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -125,21 +107,6 @@ exports[`create a queue 1`] = ` "tree": { "children": { "my_queue": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_queue/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -618,9 +585,7 @@ async handle(message) { exports[`push rejects empty message 1`] = ` [ "root/my_queue started", - "root/my_queue/Policy started", "Push (messages=).", - "root/my_queue/Policy stopped", "root/my_queue stopped", ] `; @@ -643,16 +608,6 @@ exports[`push rejects empty message 2`] = ` }, "type": "@winglang/sdk.cloud.Queue", }, - { - "addr": "c88a4c68047871c2d322479c886423828e8119d85c", - "attrs": {}, - "path": "root/my_queue/Policy", - "props": { - "principal": "\${wsim#root/my_queue#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -728,14 +683,6 @@ exports[`push rejects empty message 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -750,21 +697,6 @@ exports[`push rejects empty message 2`] = ` "tree": { "children": { "my_queue": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_queue/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -792,13 +724,11 @@ exports[`push rejects empty message 2`] = ` exports[`queue batch size of 2, purge the queue 1`] = ` [ "root/my_queue started", - "root/my_queue/Policy started", "Push (messages=A).", "Push (messages=B).", "ApproxSize ().", "Purge ().", "ApproxSize ().", - "root/my_queue/Policy stopped", "root/my_queue stopped", ] `; @@ -821,16 +751,6 @@ exports[`queue batch size of 2, purge the queue 2`] = ` }, "type": "@winglang/sdk.cloud.Queue", }, - { - "addr": "c88a4c68047871c2d322479c886423828e8119d85c", - "attrs": {}, - "path": "root/my_queue/Policy", - "props": { - "principal": "\${wsim#root/my_queue#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -906,14 +826,6 @@ exports[`queue batch size of 2, purge the queue 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -928,21 +840,6 @@ exports[`queue batch size of 2, purge the queue 2`] = ` "tree": { "children": { "my_queue": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_queue/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -998,11 +895,7 @@ queue: (function() { if (!simulatorUrl) { throw new Error("Missing environment variable: WING_SIMULATOR_URL"); } - const caller = process.env.WING_SIMULATOR_CALLER; - if (!caller) { - throw new Error("Missing environment variable: WING_SIMULATOR_CALLER"); - } - return require("@winglang/sdk/lib/simulator/client").makeSimulatorClient(simulatorUrl, handle, caller); + return require("@winglang/sdk/lib/simulator/client").makeSimulatorClient(simulatorUrl, handle); })() })); return await $handler.handle(event); @@ -1046,35 +939,6 @@ async handle(message) { }, "simulator.json": { "resources": [ - { - "addr": "c88a4c68047871c2d322479c886423828e8119d85c", - "attrs": {}, - "path": "root/my_queue/Policy", - "props": { - "principal": "\${wsim#root/my_queue#attrs.handle}", - "statements": [ - { - "operation": "invoke", - "resourceHandle": "\${wsim#root/my_queue/SetConsumer0#attrs.handle}", - }, - { - "operation": "hasAvailableWorkers", - "resourceHandle": "\${wsim#root/my_queue/SetConsumer0#attrs.handle}", - }, - ], - }, - "type": "@winglang/sdk.sim.Policy", - }, - { - "addr": "c850ec3b050199141fa07ce182e2e0711e60d2d193", - "attrs": {}, - "path": "root/my_queue/SetConsumer0/Policy", - "props": { - "principal": "\${wsim#root/my_queue/SetConsumer0#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c8e33b9b91c909e579b9d3d703146eb66c2a657ffc", "attrs": {}, @@ -1133,27 +997,11 @@ async handle(message) { }, "type": "@winglang/sdk.cloud.Function", }, - { - "addr": "c8a0157ce3fdc8f4da43f974ef4b722745f359650f", - "attrs": {}, - "path": "root/my_queue_messages/Function/Policy", - "props": { - "principal": "\${wsim#root/my_queue_messages/Function#attrs.handle}", - "statements": [ - { - "operation": "push", - "resourceHandle": "\${wsim#root/my_queue#attrs.handle}", - }, - ], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c8e2354407fd3536187725c2b37c5327f47bb841e9", "attrs": {}, "deps": [ "root/my_queue_messages/Function", - "root/my_queue_messages/Function/Policy", ], "path": "root/my_queue_messages", "props": { @@ -1236,14 +1084,6 @@ async handle(message) { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1259,19 +1099,6 @@ async handle(message) { "children": { "my_queue": { "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_queue/Policy", - }, "QueueEventMapping0": { "constructInfo": { "fqn": "constructs.Construct", @@ -1284,21 +1111,6 @@ async handle(message) { "path": "root/my_queue/QueueEventMapping0", }, "SetConsumer0": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_queue/SetConsumer0/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1326,21 +1138,6 @@ async handle(message) { "my_queue_messages": { "children": { "Function": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_queue_messages/Function/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1414,35 +1211,6 @@ async handle(message) { }, "simulator.json": { "resources": [ - { - "addr": "c88a4c68047871c2d322479c886423828e8119d85c", - "attrs": {}, - "path": "root/my_queue/Policy", - "props": { - "principal": "\${wsim#root/my_queue#attrs.handle}", - "statements": [ - { - "operation": "invoke", - "resourceHandle": "\${wsim#root/my_queue/SetConsumer0#attrs.handle}", - }, - { - "operation": "hasAvailableWorkers", - "resourceHandle": "\${wsim#root/my_queue/SetConsumer0#attrs.handle}", - }, - ], - }, - "type": "@winglang/sdk.sim.Policy", - }, - { - "addr": "c850ec3b050199141fa07ce182e2e0711e60d2d193", - "attrs": {}, - "path": "root/my_queue/SetConsumer0/Policy", - "props": { - "principal": "\${wsim#root/my_queue/SetConsumer0#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c8e33b9b91c909e579b9d3d703146eb66c2a657ffc", "attrs": {}, @@ -1558,14 +1326,6 @@ async handle(message) { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1581,19 +1341,6 @@ async handle(message) { "children": { "my_queue": { "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_queue/Policy", - }, "QueueEventMapping0": { "constructInfo": { "fqn": "constructs.Construct", @@ -1606,21 +1353,6 @@ async handle(message) { "path": "root/my_queue/QueueEventMapping0", }, "SetConsumer0": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_queue/SetConsumer0/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/redis.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/redis.test.ts.snap index 69133a45443..f20b4825304 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/redis.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/redis.test.ts.snap @@ -104,14 +104,6 @@ exports[`create a Redis resource 1`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/schedule.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/schedule.test.ts.snap index 1b3ff0eaf05..c845a045772 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/schedule.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/schedule.test.ts.snap @@ -17,16 +17,6 @@ exports[`create a schedule 1`] = ` }, "type": "@winglang/sdk.cloud.Schedule", }, - { - "addr": "c8c7f555c253f79a2cdcd8a13c6772cfd654e2bf0b", - "attrs": {}, - "path": "root/my_schedule/Policy", - "props": { - "principal": "\${wsim#root/my_schedule#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -102,14 +92,6 @@ exports[`create a schedule 1`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -124,21 +106,6 @@ exports[`create a schedule 1`] = ` "tree": { "children": { "my_schedule": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_schedule/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -197,31 +164,6 @@ console.log("Hello from schedule!"); }, "simulator.json": { "resources": [ - { - "addr": "c8c7f555c253f79a2cdcd8a13c6772cfd654e2bf0b", - "attrs": {}, - "path": "root/my_schedule/Policy", - "props": { - "principal": "\${wsim#root/my_schedule#attrs.handle}", - "statements": [ - { - "operation": "invoke", - "resourceHandle": "\${wsim#root/my_schedule/OnTick0#attrs.handle}", - }, - ], - }, - "type": "@winglang/sdk.sim.Policy", - }, - { - "addr": "c8d61fcab25f1c27fcb0f0ba29e4888a7041c8029f", - "attrs": {}, - "path": "root/my_schedule/OnTick0/Policy", - "props": { - "principal": "\${wsim#root/my_schedule/OnTick0#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c83eddbe8512d15b84969a611d4b5ca9ce55e1f808", "attrs": {}, @@ -334,14 +276,6 @@ console.log("Hello from schedule!"); "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -358,21 +292,6 @@ console.log("Hello from schedule!"); "my_schedule": { "children": { "OnTick0": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_schedule/OnTick0/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -396,19 +315,6 @@ console.log("Hello from schedule!"); "id": "OnTickMapping0", "path": "root/my_schedule/OnTickMapping0", }, - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_schedule/Policy", - }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -468,31 +374,6 @@ console.log("Hello from schedule!"); }, "simulator.json": { "resources": [ - { - "addr": "c8c7f555c253f79a2cdcd8a13c6772cfd654e2bf0b", - "attrs": {}, - "path": "root/my_schedule/Policy", - "props": { - "principal": "\${wsim#root/my_schedule#attrs.handle}", - "statements": [ - { - "operation": "invoke", - "resourceHandle": "\${wsim#root/my_schedule/OnTick0#attrs.handle}", - }, - ], - }, - "type": "@winglang/sdk.sim.Policy", - }, - { - "addr": "c8d61fcab25f1c27fcb0f0ba29e4888a7041c8029f", - "attrs": {}, - "path": "root/my_schedule/OnTick0/Policy", - "props": { - "principal": "\${wsim#root/my_schedule/OnTick0#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c83eddbe8512d15b84969a611d4b5ca9ce55e1f808", "attrs": {}, @@ -605,14 +486,6 @@ console.log("Hello from schedule!"); "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -629,21 +502,6 @@ console.log("Hello from schedule!"); "my_schedule": { "children": { "OnTick0": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_schedule/OnTick0/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -667,19 +525,6 @@ console.log("Hello from schedule!"); "id": "OnTickMapping0", "path": "root/my_schedule/OnTickMapping0", }, - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_schedule/Policy", - }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -739,31 +584,6 @@ console.log("Hello from schedule!"); }, "simulator.json": { "resources": [ - { - "addr": "c8c7f555c253f79a2cdcd8a13c6772cfd654e2bf0b", - "attrs": {}, - "path": "root/my_schedule/Policy", - "props": { - "principal": "\${wsim#root/my_schedule#attrs.handle}", - "statements": [ - { - "operation": "invoke", - "resourceHandle": "\${wsim#root/my_schedule/OnTick0#attrs.handle}", - }, - ], - }, - "type": "@winglang/sdk.sim.Policy", - }, - { - "addr": "c8d61fcab25f1c27fcb0f0ba29e4888a7041c8029f", - "attrs": {}, - "path": "root/my_schedule/OnTick0/Policy", - "props": { - "principal": "\${wsim#root/my_schedule/OnTick0#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, { "addr": "c83eddbe8512d15b84969a611d4b5ca9ce55e1f808", "attrs": {}, @@ -876,14 +696,6 @@ console.log("Hello from schedule!"); "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -900,21 +712,6 @@ console.log("Hello from schedule!"); "my_schedule": { "children": { "OnTick0": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_schedule/OnTick0/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -938,19 +735,6 @@ console.log("Hello from schedule!"); "id": "OnTickMapping0", "path": "root/my_schedule/OnTickMapping0", }, - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_schedule/Policy", - }, }, "constructInfo": { "fqn": "constructs.Construct", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/secret.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/secret.test.ts.snap index debe797f8d9..50ee1bf1a06 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/secret.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/secret.test.ts.snap @@ -92,14 +92,6 @@ exports[`create a secret 1`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/service.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/service.test.ts.snap index f47c105b1ca..8ec8e96fba0 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/service.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/service.test.ts.snap @@ -45,35 +45,12 @@ return class Handler { "attrs": {}, "path": "root/my_service", "props": { + "autoStart": true, "environmentVariables": {}, "sourceCodeFile": ".wing/my_service_c815f66e.js", }, "type": "@winglang/sdk.cloud.Service", }, - { - "addr": "c845f08fe23811b5ba949f822a6bc3077a050f801b", - "attrs": {}, - "path": "root/my_service/Policy", - "props": { - "principal": "\${wsim#root/my_service#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, - { - "addr": "c810e24e6e3ab8b88ceddbbe1ac7323d46de30a969", - "attrs": {}, - "deps": [ - "root/my_service", - "root/my_service/Policy", - ], - "path": "root/my_service/Helper", - "props": { - "autoStart": true, - "service": "\${wsim#root/my_service#attrs.handle}", - }, - "type": "@winglang/sdk.sim.ServiceHelper", - }, ], "sdkVersion": "0.0.0", "types": { @@ -149,14 +126,6 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -171,32 +140,6 @@ return class Handler { "tree": { "children": { "my_service": { - "children": { - "Helper": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "hidden": true, - }, - "id": "Helper", - "path": "root/my_service/Helper", - }, - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_service/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/table.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/table.test.ts.snap index 470f510adec..4ac0d3b25cd 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/table.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/table.test.ts.snap @@ -113,14 +113,6 @@ exports[`can add row in preflight 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -257,14 +249,6 @@ exports[`create a table 1`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -411,14 +395,6 @@ exports[`get row 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -563,14 +539,6 @@ exports[`insert row 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -717,14 +685,6 @@ exports[`list table 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -870,14 +830,6 @@ exports[`tryGet row 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1026,14 +978,6 @@ exports[`update row 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/test.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/test.test.ts.snap index 05c7d3fded0..9fa84c5ea50 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/test.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/test.test.ts.snap @@ -55,16 +55,6 @@ async handle(event) { }, "type": "@winglang/sdk.std.TestRunner", }, - { - "addr": "c8e9f1ae266f81e04ffcbb951317b09fa72e8ad7cb", - "attrs": {}, - "path": "root/env0/test:my_test/Handler/Policy", - "props": { - "principal": "\${wsim#root/env0/test:my_test/Handler#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -140,14 +130,6 @@ async handle(event) { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -179,21 +161,6 @@ async handle(event) { "test:my_test": { "children": { "Handler": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/env0/test:my_test/Handler/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/topic-producer.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/topic-producer.test.ts.snap index 56a208842d6..22c43627674 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/topic-producer.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/topic-producer.test.ts.snap @@ -2,23 +2,16 @@ exports[`publishing messages to topic 1`] = ` [ - "root/TopicTester/MyTopic started", "root/TopicTester/MyTopic/OnMessage0 started", - "root/TopicTester/MyTopic/Policy started", - "root/TopicTester/MyTopic/OnMessage0/Policy started", + "root/TopicTester/MyTopic started", "root/TopicTester/MyTopic/TopicEventMapping0 started", "root/TopicTester/Function started", - "root/TopicTester/Function/Policy started", "Publish (message=ABC).", - "Sending message (message=ABC, subscriber=sim-1).", + "Sending message (message=ABC, subscriber=sim-0).", "InvokeAsync (payload="ABC").", "Invoke (payload="ABC").", - "Message received", - "root/TopicTester/MyTopic/Policy stopped", - "root/TopicTester/MyTopic/OnMessage0/Policy stopped", "root/TopicTester/MyTopic/TopicEventMapping0 stopped", "root/TopicTester/MyTopic/OnMessage0 stopped", - "root/TopicTester/Function/Policy stopped", "root/TopicTester/Function stopped", "root/TopicTester/MyTopic stopped", ] diff --git a/libs/wingsdk/test/target-sim/__snapshots__/topic.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/topic.test.ts.snap index be384dbb3fb..f846cbccf14 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/topic.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/topic.test.ts.snap @@ -15,16 +15,6 @@ exports[`create a topic 1`] = ` "props": {}, "type": "@winglang/sdk.cloud.Topic", }, - { - "addr": "c8635ef174eab9aa010e5bed09a712307a6b70e731", - "attrs": {}, - "path": "root/my_topic/Policy", - "props": { - "principal": "\${wsim#root/my_topic#attrs.handle}", - "statements": [], - }, - "type": "@winglang/sdk.sim.Policy", - }, ], "sdkVersion": "0.0.0", "types": { @@ -100,14 +90,6 @@ exports[`create a topic 1`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, - "@winglang/sdk.sim.Policy": { - "className": "Policy", - "sourcePath": "/policy.inflight.js", - }, - "@winglang/sdk.sim.ServiceHelper": { - "className": "ServiceHelper", - "sourcePath": "/service.inflight.js", - }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -122,21 +104,6 @@ exports[`create a topic 1`] = ` "tree": { "children": { "my_topic": { - "children": { - "Policy": { - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0", - }, - "display": { - "description": "A simulated resource policy", - "hidden": true, - "title": "Policy", - }, - "id": "Policy", - "path": "root/my_topic/Policy", - }, - }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", diff --git a/libs/wingsdk/test/target-sim/app.test.ts b/libs/wingsdk/test/target-sim/app.test.ts index b071c6f0526..13ddf565a43 100644 --- a/libs/wingsdk/test/target-sim/app.test.ts +++ b/libs/wingsdk/test/target-sim/app.test.ts @@ -48,10 +48,7 @@ test("tests do not synthesize functions when test mode is off", async () => { await s.stop(); // THEN - expect(resources.sort()).toEqual([ - "root/Default/my_bucket", - "root/Default/my_bucket/Policy", - ]); + expect(resources.sort()).toEqual(["root/Default/my_bucket"]); }); test("tests are synthesized into individual environments when test mode is on", async () => { @@ -76,12 +73,8 @@ test("tests are synthesized into individual environments when test mode is on", expect(resources.sort()).toEqual([ "root/cloud.TestRunner", "root/env0/my_bucket", - "root/env0/my_bucket/Policy", "root/env0/test:my_test1/Handler", - "root/env0/test:my_test1/Handler/Policy", "root/env1/my_bucket", - "root/env1/my_bucket/Policy", "root/env1/test:my_test2/Handler", - "root/env1/test:my_test2/Handler/Policy", ]); }); diff --git a/libs/wingsdk/test/target-sim/bucket.test.ts b/libs/wingsdk/test/target-sim/bucket.test.ts index 5d07e2f1a34..959449fac72 100644 --- a/libs/wingsdk/test/target-sim/bucket.test.ts +++ b/libs/wingsdk/test/target-sim/bucket.test.ts @@ -39,9 +39,7 @@ test("update an object in bucket", async () => { // GIVEN const app = new SimApp(); const bucket = new cloud.Bucket(app, "my_bucket"); - const testInflight = Testing.makeHandler( - "async handle() { console.log('I am done'); }" - ); + const testInflight = Testing.makeHandler("async handle() {}"); bucket.onCreate(testInflight); const s = await app.startSimulator(); @@ -50,17 +48,13 @@ test("update an object in bucket", async () => { // WHEN await client.put(KEY, JSON.stringify({ msg: "Hello world 1!" })); + await waitUntilTraceCount(s, 4, (trace) => trace.data.message.includes(KEY)); await client.put(KEY, JSON.stringify({ msg: "Hello world 2!" })); - await waitUntilTraceCount(s, 1, (trace) => - trace.data.message.includes(`I am done`) - ); + await waitUntilTraceCount(s, 5, (trace) => trace.data.message.includes(KEY)); // THEN - await s.stop(); expect(listMessages(s)).toMatchSnapshot(); - // The bucket notification topic should only publish one message, since the - // second put() call counts as an update, not a create. - expect(listMessages(s).filter((m) => m.includes(`Publish`))).toHaveLength(1); + await s.stop(); }); test("bucket on event creates 3 topics, and sends the right event and key in the event handlers", async () => { @@ -337,7 +331,7 @@ test("get invalid object throws an error", async () => { await s.stop(); expect(listMessages(s)).toMatchSnapshot(); - expect(s.listTraces()[2].data.status).toEqual("failure"); + expect(s.listTraces()[1].data.status).toEqual("failure"); expect(app.snapshot()).toMatchSnapshot(); }); diff --git a/libs/wingsdk/test/target-sim/function.test.ts b/libs/wingsdk/test/target-sim/function.test.ts index d791254362c..a140e353e37 100644 --- a/libs/wingsdk/test/target-sim/function.test.ts +++ b/libs/wingsdk/test/target-sim/function.test.ts @@ -130,7 +130,7 @@ test("invoke function fails", async () => { await s.stop(); expect(listMessages(s)).toMatchSnapshot(); - expect(s.listTraces()[2].data.error).toMatchObject({ + expect(s.listTraces()[1].data.error).toMatchObject({ message: "Name must start with uppercase letter", }); expect(app.snapshot()).toMatchSnapshot(); @@ -190,13 +190,13 @@ test("invoke function with process.exit(1)", async () => { // WHEN const PAYLOAD = {}; await expect(client.invoke(JSON.stringify(PAYLOAD))).rejects.toThrow( - "Process exited with code 1, signal null" + "Process exited with code 1" ); // THEN await s.stop(); expect(listMessages(s)).toMatchSnapshot(); - expect(s.listTraces()[2].data.error).toMatchObject({ - message: "Process exited with code 1, signal null", + expect(s.listTraces()[1].data.error).toMatchObject({ + message: "Process exited with code 1", }); expect(app.snapshot()).toMatchSnapshot(); }); @@ -247,13 +247,5 @@ test("__dirname and __filename cannot be used within inflight code", async () => await dirnameInvoker(s); await filenameInvoker(s); - await s.stop(); - - expect( - listMessages(s).filter((m) => - m.includes( - "Warning: __dirname and __filename cannot be used within bundled cloud functions." - ) - ) - ).toHaveLength(2); + expect(listMessages(s)).toMatchSnapshot(); }); diff --git a/libs/wingsdk/test/target-sim/on-deploy.test.ts b/libs/wingsdk/test/target-sim/on-deploy.test.ts index a2df5e6042e..1aa9077b3fe 100644 --- a/libs/wingsdk/test/target-sim/on-deploy.test.ts +++ b/libs/wingsdk/test/target-sim/on-deploy.test.ts @@ -18,7 +18,7 @@ test("create an OnDeploy", async () => { attrs: { handle: expect.any(String), }, - deps: ["root/my_on_deploy/Function", "root/my_on_deploy/Function/Policy"], + deps: ["root/my_on_deploy/Function"], path: "root/my_on_deploy", addr: expect.any(String), props: { diff --git a/libs/wingsdk/test/target-sim/queue.test.ts b/libs/wingsdk/test/target-sim/queue.test.ts index 047e5ee6b4d..8941c55c0bc 100644 --- a/libs/wingsdk/test/target-sim/queue.test.ts +++ b/libs/wingsdk/test/target-sim/queue.test.ts @@ -369,6 +369,6 @@ test("push rejects empty message", async () => { await s.stop(); expect(listMessages(s)).toMatchSnapshot(); - expect(s.listTraces()[2].data.status).toEqual("failure"); + expect(s.listTraces()[1].data.status).toEqual("failure"); expect(app.snapshot()).toMatchSnapshot(); }); diff --git a/libs/wingsdk/test/target-sim/service.test.ts b/libs/wingsdk/test/target-sim/service.test.ts index 7848eacad36..b783cc91e63 100644 --- a/libs/wingsdk/test/target-sim/service.test.ts +++ b/libs/wingsdk/test/target-sim/service.test.ts @@ -32,6 +32,7 @@ test("create a service with on start method", async () => { props: { sourceCodeFile: expect.any(String), environmentVariables: {}, + autoStart: true, }, type: cloud.SERVICE_FQN, }); @@ -62,6 +63,7 @@ test("create a service with a on stop method", async () => { props: { sourceCodeFile: expect.any(String), environmentVariables: {}, + autoStart: true, }, type: cloud.SERVICE_FQN, }); @@ -74,8 +76,8 @@ test("create a service with a on stop method", async () => { .filter((v) => v.sourceType == cloud.SERVICE_FQN) .map((trace) => trace.data.message) ).toEqual([ - "root/my_service started", "start!", + "root/my_service started", "stop!", "root/my_service stopped", ]); @@ -104,6 +106,7 @@ test("create a service without autostart", async () => { props: { sourceCodeFile: expect.any(String), environmentVariables: {}, + autoStart: false, }, type: cloud.SERVICE_FQN, }); diff --git a/libs/wingsdk/test/target-sim/topic-producer.test.ts b/libs/wingsdk/test/target-sim/topic-producer.test.ts index afe43c76cb4..168ee5e95e7 100644 --- a/libs/wingsdk/test/target-sim/topic-producer.test.ts +++ b/libs/wingsdk/test/target-sim/topic-producer.test.ts @@ -1,6 +1,6 @@ import { Construct } from "constructs"; import { test, expect } from "vitest"; -import { listMessages, waitUntilTraceCount } from "./util"; +import { listMessages } from "./util"; import * as cloud from "../../src/cloud"; import { Testing } from "../../src/simulator"; import { SimApp } from "../sim-app"; @@ -27,7 +27,6 @@ test("publishing messages to topic", async () => { const processor = Testing.makeHandler(`async handle(event) { if (event.message === "") throw new Error("No message recieved"); - console.log("Message received"); }`); topic.onMessage(processor); } @@ -45,10 +44,6 @@ test("publishing messages to topic", async () => { // WHEN await publisher.invoke("ABC"); - await waitUntilTraceCount(s, 1, (trace) => - trace.data.message.includes("Message received") - ); - // THEN await s.stop(); diff --git a/libs/wingsdk/test/target-sim/util.ts b/libs/wingsdk/test/target-sim/util.ts index 07aab70729f..de8c41ed6fb 100644 --- a/libs/wingsdk/test/target-sim/util.ts +++ b/libs/wingsdk/test/target-sim/util.ts @@ -29,7 +29,7 @@ export interface IScopeCallback { (scope: Construct): void; } -export function listMessages(s: Simulator): string[] { +export function listMessages(s: Simulator) { const message = s.listTraces().map((trace) => trace.data.message); // Redact any messages containing port numbers return message.map((m) => diff --git a/libs/wingsdk/test/ui/__snapshots__/ui.test.ts.snap b/libs/wingsdk/test/ui/__snapshots__/ui.test.ts.snap index 8fb72eef1b3..013056fac0d 100644 --- a/libs/wingsdk/test/ui/__snapshots__/ui.test.ts.snap +++ b/libs/wingsdk/test/ui/__snapshots__/ui.test.ts.snap @@ -3,14 +3,10 @@ exports[`can obtain ui components 1`] = ` [ "root/MyClass/Button/Handler started", - "root/MyClass/Button/Handler/Policy started", "root/MyClass/Field/Handler started", - "root/MyClass/Field/Handler/Policy started", "Invoke (payload="").", "Invoke (payload="").", - "root/MyClass/Button/Handler/Policy stopped", "root/MyClass/Button/Handler stopped", - "root/MyClass/Field/Handler/Policy stopped", "root/MyClass/Field/Handler stopped", ] `; diff --git a/tools/hangar/__snapshots__/invalid.ts.snap b/tools/hangar/__snapshots__/invalid.ts.snap index b702359f151..c8bad3498a1 100644 --- a/tools/hangar/__snapshots__/invalid.ts.snap +++ b/tools/hangar/__snapshots__/invalid.ts.snap @@ -3546,32 +3546,6 @@ Test Files 1 failed (1) Duration " `; -exports[`simulator_permissions.test.w 1`] = ` -"fail ┌ simulator_permissions.test.wsim » root/env0/test:incorrect resource permission - │ Error: Resource \\"root/env0/test:incorrect resource permission/Handler\\" does not have permission to perform operation \\"put\\" on resource \\"root/env0/b1\\". - │ --> ../../../examples/tests/invalid/simulator_permissions.test.w:15:3 - │ | while i > 0 { - │ | i -= 1; - │ | } - │ 15 | buckets.at(i).put(\\"key\\", \\"value\\"); - │ | ^ - └ at /simulator_permissions.test.w:15:3 -fail ┌ simulator_permissions.test.wsim » root/env1/test:incorrect permission operation - │ Error: Resource \\"root/env1/test:incorrect permission operation/Handler\\" does not have permission to perform operation \\"put\\" on resource \\"root/env1/b1\\". - │ --> ../../../examples/tests/invalid/simulator_permissions.test.w:25:3 - │ | while i > 0 { - │ | i -= 1; - │ | } - │ 25 | buckets.at(i).put(\\"key\\", \\"value\\"); - │ | ^ - └ at /simulator_permissions.test.w:25:3 - - -Tests 2 failed (2) -Test Files 1 failed (1) -Duration " -`; - exports[`sorted_errors_no_span.test.w 1`] = ` "error: Expected type to be \\"num\\", but got \\"str\\" instead --> ../../../examples/tests/invalid/sorted_errors_no_span.test.w:1:14 From 988593554b6b9f41666c0e7854920071e80a85b4 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Wed, 3 Apr 2024 14:01:27 +0300 Subject: [PATCH 02/16] rfc: cloud snapshot tests (#6044) An RFC for https://github.com/winglang/wing/issues/5958. A proposal for a feature that will capture a snapshot of the synthesis output from `wing test` to reduce regressions in cloud implementations. *By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*. --- .../999-rfcs/2024-03-24-snapshot-tests.md | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 docs/contributing/999-rfcs/2024-03-24-snapshot-tests.md diff --git a/docs/contributing/999-rfcs/2024-03-24-snapshot-tests.md b/docs/contributing/999-rfcs/2024-03-24-snapshot-tests.md new file mode 100644 index 00000000000..13ea703c6b1 --- /dev/null +++ b/docs/contributing/999-rfcs/2024-03-24-snapshot-tests.md @@ -0,0 +1,75 @@ +--- +title: "#5958 Cloud Snapshot Tests" +description: Spec and design for adding cloud snapshots to the Wing test framework +--- + +# Cloud Snapshot Tests + +- **Author(s)**: @eladb +- **Submission Date**: 2024-03-24 +- **Stage**: Approved +- **Stage Date**: 2024-04-03 + +## Requirements + +We would like to be able to capture a snapshot of the synthesized output when compiling to cloud +targets, and use it to protect against regressions in CI, without having to deploy to the cloud. + +For example, let's say I am creating a Wing library with a resource that supports both `sim` and +`tf-aws`. I am writing a bunch of tests for it. + +I can run these tests in the simulator (`wing test`) and can also run them on AWS through `wing test +-t tf-aws`. + +As my code **or its dependencies** are updated, I'd like to continuously run all these tests to make +sure my library is not broken. Running the tests against `sim` is easy (I can just run `wing test` +in my CI build environment), but it's not realistic to run all these tests against the real cloud +target, given it could take a very long time and could also be very expensive. + +In some scenarios (such as the Wing SDK tests), users will prefer to setup a continuous integration +workflow and run tests in the cloud, but for the most part running all my tests on the cloud for +every commit is too expensive and requires a complicated setup (i.e. an AWS account), so I'd like to +use a more lightweight approach... + +> NOTE: This is not https://github.com/winglang/wing/issues/1214 (which is about using snapshots for +> assertions). + +## Design + +We propose to add a feature to `wing test` which will capture a snapshot of the synthesized output +of every `.test.w` file and store them in the repository. + +> This is a similar approach used successfully and scalably in the AWS CDK. See +> [docs](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md) for details. The main +> difference is that `cdk-integ` there was no way to add assertions to tests, so this is so much +> cooler. + +When I run `wing test -t tf-aws foo.test.w` in my dev environment, if the test succeeds (e.g. +deploys and all test cases pass), the test framework will create `foo.test.w.tfaws.snap` which will +include a nicely formatted (markdown?) snapshot of all the synthesis output from this test. + +> In a future version we can add support for placing all snapshots in an adjacent subdirectory. + +Now, when `wing test -t tf-aws foo.test.w` is executed in CI (`CI=1`), by default it won't actually +go and deploy to the cloud. Instead, it will just synthesize the output and compare it to the +committed `.snap` file. If the output is not the same, the test will fail with a nice diff +indicating that there was an unexpected regression. + +The `--snapshots` or `-s` switch can be used to control behavior: + + * `--snapshots=auto` - auto-detect based on CI flag (described above) + * `--snapshots=never` - disables snapshots altogether + * `--snapshots=update` - skips deployment and only update the snapshots. + * `--snapshots=deploy` - forces a deployment even if `CI=1`. + * `--snapshots=assert` - only asserts that the snapshots have not changed + +## Implementation Notes + +* We need to decide if we want the inflight JavaScript code to also be included or just trust the + fact that if inflight code has changed, it should be reflected somehow in the asset names + referenced from the IAC model. +* Ideally this shouldn't be Terraform-specific. `app.synth()` should return something that can be + used to capture the snapshots. +* The output will need to be sanitized somehow so that it will be deterministic (e.g. paths should + not be included). + From 8a88d30ea4f4ace694c18b0c54a8c38e5fa8351c Mon Sep 17 00:00:00 2001 From: Chris Rybicki Date: Wed, 3 Apr 2024 22:17:15 -0400 Subject: [PATCH 03/16] chore: archive proposed examples (#6140) Archived to... git history. Related to https://github.com/winglang/wing/issues/5992 ## Checklist - [ ] Title matches [Winglang's style guide](https://www.winglang.io/contributing/start-here/pull_requests#how-are-pull-request-titles-formatted) - [ ] Description explains motivation and solution - [ ] Tests added (always) - [ ] Docs updated (only required for features) - [ ] Added `pr/e2e-full` label if this feature requires end-to-end testing *By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*. --- .../01-start-here/01-contributing-to-wing.md | 2 +- docs/contributing/01-start-here/08-docs.md | 12 -- examples/README.md | 52 +------ examples/proposed/cacheable-function.w | 29 ---- examples/proposed/counting-semaphore.w | 76 ----------- examples/proposed/in-memory-search.w | 81 ----------- examples/proposed/lock.w | 83 ------------ examples/proposed/replayable-queue.w | 59 -------- examples/proposed/task-manager.w | 108 --------------- examples/proposed/url-shortener.main.w | 127 ------------------ 10 files changed, 3 insertions(+), 626 deletions(-) delete mode 100644 examples/proposed/cacheable-function.w delete mode 100644 examples/proposed/counting-semaphore.w delete mode 100644 examples/proposed/in-memory-search.w delete mode 100644 examples/proposed/lock.w delete mode 100644 examples/proposed/replayable-queue.w delete mode 100644 examples/proposed/task-manager.w delete mode 100644 examples/proposed/url-shortener.main.w diff --git a/docs/contributing/01-start-here/01-contributing-to-wing.md b/docs/contributing/01-start-here/01-contributing-to-wing.md index eef48d5c160..dd5eab93de0 100644 --- a/docs/contributing/01-start-here/01-contributing-to-wing.md +++ b/docs/contributing/01-start-here/01-contributing-to-wing.md @@ -12,7 +12,7 @@ There are many ways to contribute to Wing: * Contributing to the [Wing SDK (standard library)](/contributing/start-here/wingsdk) * Reporting bugs through a [GitHub issue](https://github.com/winglang/wing/issues) -* Writing [documentation and guides](https://github.com/winglang/wing/issues?q=is%3Aissue+is%3Aopen+label%3A%22%F0%9F%93%9A+documentation%22) or adding [examples](/contributing/start-here/docs#%EF%B8%8F-how-do-i-add-an-example) +* Writing [documentation and guides](https://github.com/winglang/wing/issues?q=is%3Aissue+is%3Aopen+label%3A%22%F0%9F%93%9A+documentation%22) or adding [examples](https://github.com/winglang/examples) * Setting up your [development environment](/contributing/start-here/development) and working on the code * Submitting [pull requests](/contributing/start-here/pull_requests) for new features or helping with [reviews](https://github.com/winglang/wing/pulls) * Picking up a [good first issue](https://github.com/winglang/wing/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22+no%3Aassignee+sort%3Aupdated-desc+) to work on diff --git a/docs/contributing/01-start-here/08-docs.md b/docs/contributing/01-start-here/08-docs.md index 7c9747ec830..3844146250f 100644 --- a/docs/contributing/01-start-here/08-docs.md +++ b/docs/contributing/01-start-here/08-docs.md @@ -24,15 +24,3 @@ pnpm docs This magical script will clone the [winglang/docsite](https://github.com/winglang/docsite) repository into `~/.winglang-docsite`, symlink your local copy into it and start a browser with the site. - -## 🖼️ How do I add an example? - -Adding a code example is a great way to contribute to Wing. Here's how to do it: - -* Fork this repository on GitHub. -* Create a new branch for your example. -* Add your Wing code to the `examples` directory. - * If your example involves multiple files, create a dedicated directory for it. -* Add a link to your example to the `examples/README.md` file. -* Commit your changes and push them to your fork. -* Open a pull request. A Wing maintainer will review it as soon as possible! diff --git a/examples/README.md b/examples/README.md index dc843d66106..ba855a7333b 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,53 +1,5 @@ # Wing Examples -This directory contains a collection of Wing examples of the kinds of apps you can build in Wing! Check out the [Wing Contributor's Handbook](https://www.winglang.io/contributing/start-here/docs#%EF%B8%8F-how-do-i-add-an-example) for a guide on on how to add your own example. +This directory contains Wing examples used for testing the Wing compiler and standard library. -The examples in the `tests` directory are examples specifically used for testing the compiler. `tests/valid` are examples that should compile successfully, and `tests/invalid` are examples that should fail. - -The examples in `proposed` are examples that may not yet work in the current version of Wing, but we want to make them work in the future! - -## Examples - -_Add yours here!_ - -### Cacheable function - -* **Source code:** [./proposed/cacheable-function.w](./proposed/cacheable-function.w) -* **Description:** A Wing resource where a FaaS is augmented to cache input/output pairs using a object storage bucket. -* **Author:** [@Chriscbr](https://github.com/Chriscbr) - -### In-memory search engine - -* **Source code:** [./proposed/in-memory-search.w](./proposed/in-memory-search.w) -* **Description:** This is a concept for a Wing app where cloud functions are used to create a search engine where the entire search index exists in-memory, spread across many lambda functions. -* **Author:** [@Chriscbr](https://github.com/Chriscbr) - -### Lock - -* **Source code:** [./proposed/lock.w](./proposed/lock.w) -* **Description:** A naive distributed lock implementation. This lock uses the atomicity of `Counter` internally to guarantee that it can only be acquired by a single inflight function at a time, even if they are on different machines. -* **Author:** [@Chriscbr](https://github.com/Chriscbr) - -### Counting semaphore - -* **Source code:** [./proposed/counting-semaphore.w](./proposed/counting-semaphore.w) -* **Description:** A Wing resource that helps access control for a common resource in a cloud environment. -* **Author:** [@flyingImer](https://github.com/flyingImer) - -### Replayable Queue - -* **Source code:** [./proposed/replayable-queue.w](./proposed/replayable-queue.w) -* **Description:** A Wing Queue that saves all the messages sent to it on a bucket and allow you to replay all messages -* **Author:** [@ekeren](https://github.com/ekeren) - -### Task Manager - -* **Source code:** [./proposed/task-manager.w](./proposed/task-manager.w) -* **Description:** A task manager that lets you create background tasks asynchronously, and check their status at any point in time. -* **Author:** [@Chriscbr](https://github.com/Chriscbr) - -### URL Shortener - -* **Source code:** [./proposed/url-shortener.w](./proposed/url-shortener.w) -* **Description:** A URL shortener consisting of two API endpoints, `/create` and `/u/:id`. IDs are managed using buckets, but could be swapped with a table or other stateful storage mechanism. Requires installing `node-fetch@2` from npm. -* **Author:** [@Chriscbr](https://github.com/Chriscbr) +`tests/valid` has examples that should compile successfully, and `tests/invalid` has examples that should fail. diff --git a/examples/proposed/cacheable-function.w b/examples/proposed/cacheable-function.w deleted file mode 100644 index 144b97b860c..00000000000 --- a/examples/proposed/cacheable-function.w +++ /dev/null @@ -1,29 +0,0 @@ -bring cloud; - -class CachableFunction extends cloud.Function { - _func: cloud.Function; - _cache: cloud.Bucket; - - new(inflight: inflight (event: any) => any, props: cloud.FunctionProps) { - super(inflight, props); - this._cache = new cloud.Bucket(); - } - - pub inflight invoke(event: any): any { - let key = hashof(event); - let cached = this._cache.try_get(key); - if cached { - return cached; - } - let result = super.invoke(event); - this._cache.set(key, result); - return result; - } -} - -let handler = inflight (arg1: num): num => { - // do expensive computations - return arg1 * 2; -}; - -let cachedHandler = new CachableFunction(handler); diff --git a/examples/proposed/counting-semaphore.w b/examples/proposed/counting-semaphore.w deleted file mode 100644 index d88068f288c..00000000000 --- a/examples/proposed/counting-semaphore.w +++ /dev/null @@ -1,76 +0,0 @@ -bring cloud; - -struct CountingSemaphoreProps { - availableResources: num; -} - -class CountingSemaphore { - pub limit: num; - _counter: cloud.Counter; - - // need some ttl solution here, - // probably in-house once replaced with a key-value store - new(props: CountingSemaphoreProps) { - // pseudocode: input validation - this.limit = props.availableResources; - this._counter = new cloud.Counter(); - } - - // some stable unique instance id is wanted in the inflight context - // so that a resource instance can be properly claimed and later released - // when used in conjunction with a key-value store - pub inflight try_acquire(): bool { - if this.is_at_capacity() { - return false; - } - - let post_acquired_capacity = this._counter.inc(); - if post_acquired_capacity <= this.limit { - return true; - } - this.release(); - return false; - } - - // probably key-value store is wanted, - // so that a specific resource instance can be released - // rather than naively releasing a count - pub inflight release() { - if this._counter.peek() <= 0 { - return; - } - - this._counter.dec(); - } - - pub inflight is_at_capacity(): bool { - return this._counter.peek() >= this.limit; - } -} - -let resource_1 = new CountingSemaphore({ availableResources: 2 }); -let resource_2 = new CountingSemaphore({ availableResources: 3 }); - -let queue = new cloud.Queue(); -/** - * An example handler to work with two shared resources. - */ -queue.add_consumer(inflight (message: str) => { - let is_resource_1_acquired = resource_1.try_acquire(); - if !is_resource_1_acquired { - // brutally error out to re-enqueue - throw "Failed to acquire resource 1"; - } - let is_resource_2_acquired = resource_2.try_acquire(); - if !is_resource_2_acquired { - resource_1.release(); - // brutally error out to re-enqueue - throw "Failed to acquire resource 2"; - } - - // real work - log("all resources are acquired, processing message: {message}"); - - resource_1.release(); - resource_2.release(); -}); diff --git a/examples/proposed/in-memory-search.w b/examples/proposed/in-memory-search.w deleted file mode 100644 index 92020c6ead3..00000000000 --- a/examples/proposed/in-memory-search.w +++ /dev/null @@ -1,81 +0,0 @@ -bring cloud; - -// high level concept: -// generate a large search index at compile time, and spread the search index -// data (and the work of processing through it) across N cloud functions. -// when a request to the search engine is made, all N cloud functions are -// called, and their results are joined. -// -// inspiration: https://boyter.org/posts/abusing-aws-to-make-a-search-engine/ - -let search_index_1: Map> = { - "apple": ["fruits.com"], - "banana": ["fruits.com", "dole.com"], -}; -let search_index_2: Map> = { - "cherry": ["fruits.com"], - "donut": ["krispykreme.com", "bakery.com"], -}; -let search_index_3: Map> = { - "eclair": ["bakery.com"], - "fruit": ["fruits.com"], -}; - -let search_index_chunks = [ - search_index_1, - search_index_2, - search_index_3, - // ... -]; - -struct WebsiteSummary { - url: str; - title: str; - description: str; -} - -let lookup_website = inflight (url: str): WebsiteSummary => { - // pseudocode: - // - fetch url - // - extract title from tag - // - extract description from <meta name="description"> tag -}; - -let make_worker = (chunk: Map<Array<str>>): cloud.Function => { - return new cloud.Function(inflight (terms: Array<str>): Array<str> => { - let website_urls = new MutSet<str>(); - for term in terms { - if chunk.has(term) { - for url in chunk[term] { - website_urls.add(url); - } - } - } - return website_urls.to_arr(); // converts MutSet<str> to Array<str> - }); -}; - -let workers = search_index_chunks.map(search_index_chunks); // inferred: Array<cloud.Function> - -let api = new cloud.Api(); -api.on_post("/search", inflight (request: cloud.ApiRequest): cloud.ApiResponse => { - let terms_str = request.query_params.get("terms"); // "cherry,donut" - let terms = terms_str.split(","); - let worker_calls = new MutArray<Promise<Array<str>>>(); - for worker in workers { - worker_calls.append(defer worker.invoke(terms)); - } - - // wait for all promises in the array to resolve - // `worker_results` is inferred as Array<Array<str>> - let worker_results = Promise.all(worker_calls); - let website_urls = new Set<str>(worker_results.flatten()); - let summaries = new MutArray<WebsiteSummary>(); - for url in website_urls { - summaries.append(lookup_website(url)); - } - return { - status_code: 200, - payload: summaries.to_json(), - }; -}); diff --git a/examples/proposed/lock.w b/examples/proposed/lock.w deleted file mode 100644 index c74ceb29a6c..00000000000 --- a/examples/proposed/lock.w +++ /dev/null @@ -1,83 +0,0 @@ -bring cloud; - -/** - * A lock that can only be acquired by one inflight at a time. - * - * Internally, this uses a cloud.Counter to keep track of a number. - * If the number is 0, the lock is free. If the number is 1, the lock - * is acquired. - * - * This is a very simple lock, and it has a number of limitations: - * - It is not reentrant. If a single inflight tries to acquire the lock - * twice, it may block forever. - * - It is not fair. If multiple inflights are waiting to acquire the lock, - * there is no guarantee that they will acquire the lock in the order - * that they requested it. - * - It is not stable. If an inflight crashes while holding the lock, the - * lock will be permanently stuck in the acquired state. - */ -resource Lock { - counter: cloud.Counter; - new() { - this.counter = new cloud.Counter(); - } - - pub inflight var is_locked: bool; - - inflight new() { - this.is_locked = false; - } - - /** - * Try to acquire the lock. If the lock is already acquired, return false. - * Otherwise, return true. - */ - inflight try_lock(): bool { - // If the lock is already acquired by the current inflight, throw an error. - if this.is_locked { - throw "Lock is already acquired by this inflight"; - } - - // The lock is already acquired by another inflight - too bad. :( - if this.counter.peek() > 0 { - return false; - } - - let value = this.counter.inc(); - if value == 1 { - // We successfully acquired the lock. - this.is_locked = true; - return true; - } else { - // Someone else acquired the lock between the time we checked and - // the time we tried to acquire it. Undo our increment. - this.counter.dec(); - return false; - } - } - - /** - * Acquire the lock. If the lock is already acquired by another inflight, - * block until it is released. - */ - inflight lock() { - // If the lock is already acquired by the current inflight, throw an error. - if this.is_locked { - throw "Lock is already acquired by this inflight"; - } - - while !this.try_lock() { - cloud.sleep(1); - } - } - - /** - * Release the lock. If the lock is not held by this inflight, this is a no-op. - */ - inflight unlock() { - if !this.is_locked { - return; - } - this.counter.dec(); - } -} diff --git a/examples/proposed/replayable-queue.w b/examples/proposed/replayable-queue.w deleted file mode 100644 index 06affb6f723..00000000000 --- a/examples/proposed/replayable-queue.w +++ /dev/null @@ -1,59 +0,0 @@ -bring cloud; - -/** - * A queue that can replay all messages - */ -class ReplayableQueue { - queue: cloud.Queue; - bucket: cloud.Bucket; - counter: cloud.Counter; - - new() { - this.queue = new cloud.Queue(); - this.bucket = new cloud.Bucket(); - this.counter = new cloud.Counter(); - } - - setConsumer(fn: inflight (str): str){ - this.queue.setConsumer(fn); - } - - inflight push(m: str) { - this.queue.push(m); - this.bucket.put("messages/{this.counter.inc()}", m); - } - - inflight replay(){ - for i in this.bucket.list() { - this.queue.push(this.bucket.get(i)); - } - } -} - - -// how to use the queue -class RemoteControl { - new(q: ReplayableQueue){ - let f = inflight (m: str): str => { - log("setConsumer got triggered with {m}"); - }; - - q.setConsumer(f); - - new cloud.Function(inflight (m: str) => { - q.push(m); - }) as "push"; - - new cloud.Function(inflight () => { - q.replay(); - }) as "replay"; - } -} - -let q = new ReplayableQueue(); -new RemoteControl(q); - -// Exercises for the curious reader: -// - Add some time retention for keeping messages -// - Add some max messages to keep property -// - Make sure that messages are replayed in order (currenlty it relies on the bucket.list() order) diff --git a/examples/proposed/task-manager.w b/examples/proposed/task-manager.w deleted file mode 100644 index f5a37846d66..00000000000 --- a/examples/proposed/task-manager.w +++ /dev/null @@ -1,108 +0,0 @@ -bring cloud; - -resource Utils { - extern "./helpers.js" static inflight uuid(): str; - extern "./helpers.js" static inflight sleep(ms: num): void; -} - -/** - * A resource that allows you to run background tasks asynchronously, - * and check their status at any point in time. - * - * The function of the background task must be passed to the - * constructor so that its code and permissions can be deployed to - * the cloud when the TaskManager is created. - */ -resource TaskManager { - fn: cloud.Function; - state: cloud.Bucket; - - new(handler: inflight (str): void) { - this.bucket = new cloud.Bucket(); - - let wrapper = inflight (id: str, input: str) => { - try { - let result = handler.invoke(input); - this.bucket.put("{id}/status", "done"); - this.bucket.put("{id}/result", result); - } catch e { - this.bucket.put("{id}/status", "failed"); - this.bucket.put("{id}/result", e); - } - }; - - this.fn = new cloud.Function(wrapper); - } - - /** - * Starts a background task with the given input, and returns an id - * that can be used to check the status of the task. - */ - inflight start(input: str) { - let id = Utils.uuid(); - this.fn.invoke_async(id, input); - this.bucket.put("{id}/status", "pending"); - } - - /** - * Returns the status of the background task with the given id. - * If the task is still running, this will return "pending". - * If the task has completed, this will return "done". - * If the task has failed, this will return "failed". - */ - inflight check(id: str): str { - try { - return this.bucket.get("{id}/status"); - } catch e { - throw "no such key: {id}"; - } - } - - /** - * Returns the result of the background task with the given id. - */ - inflight get_result(id: str): str { - try { - return this.bucket.get("{id}/result"); - } catch e { - throw "no such id: {id}"; - } - } - - /** - * Returns a list of all running tasks. - */ - inflight list_running_tasks(): Array<str> { - let keys = this.bucket.list(); - let running = MutArray<str>[]; - for key in keys { - if key.ends_with("/status") && this.bucket.get(key) == "pending" { - running.push(id.split("/")[0]); - } - } - return running.copy(); - } -} - -let import_contacts = new TaskManager(inflight (input: str) => { - // pretend to do some work - Utils.sleep(5s); - log(input); -}); - -// Tests - -test "import_contacts_work" { - let key = import_contacts.start("hello"); - Utils.sleep(1s); - assert(import_contacts.check(key) == "pending"); - Utils.sleep(5s); - assert(import_contacts.check(key) == "done"); - assert(import_contacts.get_result(key) == "hello"); -} - -// Exercises for the curious reader: -// - Add a timeout to the background task. -// - Add a way to cancel a background task. -// - Add a way to configure the number of retries. -// - Return a Task object from start() that can be used to check the status of the task. diff --git a/examples/proposed/url-shortener.main.w b/examples/proposed/url-shortener.main.w deleted file mode 100644 index 0ce3ccfb22e..00000000000 --- a/examples/proposed/url-shortener.main.w +++ /dev/null @@ -1,127 +0,0 @@ -bring cloud; -bring math; -bring http; - -class UrlShortener { - lookup: cloud.Bucket; - - new() { - // map from ids to urls - this.lookup = new cloud.Bucket() as "IdLookup"; - } - - // Generates a short id for the given url. - pub inflight getId(url: str): str { - let id = this._makeId(); - this.lookup.put(id, url); - return id; - } - - // Get the url for the given id. Returns nil if the id is invalid. - pub inflight getUrl(id: str): str? { - return this.lookup.tryGet(id); - } - - inflight _makeId(): str { - let ALPHANUMERIC_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - let var id = ""; - for i in 0..5 { - let randomIndex = math.floor(math.random() * ALPHANUMERIC_CHARS.length); - id = id + ALPHANUMERIC_CHARS.at(randomIndex); - } - return id; - } -} - -class UrlShortenerApi { - pub api: cloud.Api; - shortener: UrlShortener; - - new(shortener: UrlShortener) { - this.shortener = shortener; - this.api = new cloud.Api(); - - this.api.post("/create", inflight (req: cloud.ApiRequest): cloud.ApiResponse => { - let var requestUrl = ""; - try { - requestUrl = str.fromJson(Json.parse(req.body).get("url")); - } catch e { - log(e); - return cloud.ApiResponse { - status: 400, - body: Json.stringify(Json { - "error": "missing url field", - }), - }; - } - log("Generating shortened URL for {requestUrl}"); - - let id = this.shortener.getId(requestUrl); - - // return the shortened url - let shortenedUrl = "{this.api.url}/u/\{id}"; - log("Shortened URL: {shortenedUrl}"); - return cloud.ApiResponse { - status: 200, - body: Json.stringify(Json { - "shortenedUrl": shortenedUrl, - }), - }; - }); - - this.api.get("/u/\{id}", inflight (req: cloud.ApiRequest): cloud.ApiResponse => { - let id = req.vars.get("id"); - let fullUrl = this.shortener.getUrl(id); - - if let fullUrl = fullUrl { - return cloud.ApiResponse { - status: 302, - headers: Map<str>{ - "Content-Type" => "text/xml", - "Location" => fullUrl - } - }; - } else { - return cloud.ApiResponse { - status: 404, - body: Json.stringify(Json { - "error": "url not found", - }), - }; - } - }); - } -} - -let urlShortener = new UrlShortener(); -let urlShortenerApi = new UrlShortenerApi(urlShortener); - -// --- tests --- - -let TEST_URL = "https://news.ycombinator.com/"; - -test "shorten url" { - let response = http.post("{urlShortenerApi.api.url}/create", body: Json.stringify({ url: TEST_URL })); - let newUrl = str.fromJson(Json.parse(response.body).get("shortenedUrl")); - assert(newUrl.startsWith(urlShortenerApi.api.url)); -} - -test "shorten same url twice" { - let response1 = http.post("{urlShortenerApi.api.url}/create", body: Json.stringify({ url: TEST_URL })); - let newUrl1 = Json.parse(response1.body).get("shortenedUrl").asStr(); - let response2 = http.post("{urlShortenerApi.api.url}/create", body: Json.stringify({ url: TEST_URL })); - let newUrl2 = Json.parse(response2.body).get("shortenedUrl").asStr(); - assert(newUrl1 != newUrl2); -} - -test "redirect sends to correct page" { - let createResponse = http.post("{urlShortenerApi.api.url}/create", body: Json.stringify({ url: TEST_URL })); - let newUrl = Json.parse(createResponse.body).get("shortenedUrl").asStr(); - let redirectedResponse = http.get(newUrl); - assert(redirectedResponse.body.contains("<title>Hacker News")); -} - -test "invalid short url" { - let response = http.get("{urlShortenerApi.api.url}/u/invalid"); - assert(response.body.contains("url not found")); -} From 4f51239d35644b642601f07193c48e78805c138f Mon Sep 17 00:00:00 2001 From: Tsuf Cohen <39455181+tsuf239@users.noreply.github.com> Date: Thu, 4 Apr 2024 14:22:45 +0300 Subject: [PATCH 04/16] fix(sdk): `cloud.service` logs are not shown in cli simulator tests (#6143) ## Checklist fixes: #4995 I added Traces of type "log" to be included in the test result traces. I haven't written a ts test since it's better to test via the snapshots image image - [x] Title matches [Winglang's style guide](https://www.winglang.io/contributing/start-here/pull_requests#how-are-pull-request-titles-formatted) - [x] Description explains motivation and solution - [ ] Tests added (always) - [ ] Docs updated (only required for features) - [ ] Added `pr/e2e-full` label if this feature requires end-to-end testing *By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*. --- apps/wing/src/commands/test/test.ts | 5 +++-- libs/wingsdk/src/target-sim/container.inflight.ts | 2 +- libs/wingsdk/src/target-sim/test-runner.inflight.ts | 11 +++++++++-- .../sdk_tests/container/container.test.w_test_sim.md | 2 ++ .../sdk_tests/function/invoke.test.w_test_sim.md | 3 +++ .../function/invoke_async.test.w_test_sim.md | 1 + .../sdk_tests/http/fetch.test.w_test_sim.md | 3 ++- .../sdk_tests/service/http-server.test.w_test_sim.md | 9 +++++++++ .../sdk_tests/service/minimal.test.w_test_sim.md | 1 + .../sdk_tests/service/stateful.test.w_test_sim.md | 3 ++- .../inflight_handler_singleton.test.w_test_sim.md | 3 ++- .../test_corpus/valid/print.test.w_test_sim.md | 2 ++ .../test_corpus/valid/resource.test.w_test_sim.md | 3 ++- tools/hangar/src/utils.ts | 2 ++ 14 files changed, 41 insertions(+), 9 deletions(-) diff --git a/apps/wing/src/commands/test/test.ts b/apps/wing/src/commands/test/test.ts index 891f273a917..d6709b752a7 100644 --- a/apps/wing/src/commands/test/test.ts +++ b/apps/wing/src/commands/test/test.ts @@ -4,6 +4,7 @@ import { basename, join, relative, resolve, sep } from "path"; import { promisify } from "util"; import { BuiltinPlatform, determineTargetFromPlatforms } from "@winglang/compiler"; import { std, simulator } from "@winglang/sdk"; +import { TraceType } from "@winglang/sdk/lib/std"; import { Util } from "@winglang/sdk/lib/util"; import { prettyPrintError } from "@winglang/sdk/lib/util/enhanced-error"; import chalk from "chalk"; @@ -199,10 +200,10 @@ export async function renderTestReport( // add any log messages that were emitted during the test for (const trace of result.traces) { // only show detailed traces if we are in debug mode - if (trace.type === "resource" && process.env.DEBUG) { + if (trace.type === TraceType.RESOURCE && process.env.DEBUG) { details.push(chalk.gray("[trace] " + trace.data.message)); } - if (trace.type === "log") { + if (trace.type === TraceType.LOG) { details.push(chalk.gray(trace.data.message)); } } diff --git a/libs/wingsdk/src/target-sim/container.inflight.ts b/libs/wingsdk/src/target-sim/container.inflight.ts index 51f2cfd72a2..2edab95d93c 100644 --- a/libs/wingsdk/src/target-sim/container.inflight.ts +++ b/libs/wingsdk/src/target-sim/container.inflight.ts @@ -28,7 +28,7 @@ export class Container implements IContainerClient, ISimulatorResourceInstance { sourcePath: this.context.resourcePath, sourceType: "container", timestamp: new Date().toISOString(), - type: TraceType.LOG, + type: TraceType.RESOURCE, //system messages that will be displayed on debug mode only }); } diff --git a/libs/wingsdk/src/target-sim/test-runner.inflight.ts b/libs/wingsdk/src/target-sim/test-runner.inflight.ts index d04bde496f0..f17fd067c60 100644 --- a/libs/wingsdk/src/target-sim/test-runner.inflight.ts +++ b/libs/wingsdk/src/target-sim/test-runner.inflight.ts @@ -5,7 +5,7 @@ import { ISimulatorResourceInstance, UpdatePlan, } from "../simulator"; -import { ITestRunnerClient, TestResult } from "../std"; +import { ITestRunnerClient, TestResult, TraceType } from "../std"; export class TestRunner implements ITestRunnerClient, ISimulatorResourceInstance @@ -54,11 +54,18 @@ export class TestRunner } // only return traces that were added after the test was run const newTraces = this.context.listTraces().slice(previousTraces); + + // as well as any log trace prior to that- https://github.com/winglang/wing/issues/4995 + const logTraces = this.context + .listTraces() + .slice(0, previousTraces) + .filter((trace) => trace.type === TraceType.LOG); + return { path, pass, error, - traces: newTraces, + traces: [...logTraces, ...newTraces], }; } } diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/container/container.test.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/container/container.test.w_test_sim.md index 7b32bca71ae..d7e2965be98 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/container/container.test.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/container/container.test.w_test_sim.md @@ -6,6 +6,8 @@ pass ┌ container.test.wsim » root/env0/test:get echo │ bang └ pass ┌ container.test.wsim » root/env1/test:get app + │ bang + │ └ Hello, Wingnuts! diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/function/invoke.test.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/function/invoke.test.w_test_sim.md index f46ae02feeb..89cd3cf6fdf 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/function/invoke.test.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/function/invoke.test.w_test_sim.md @@ -9,6 +9,9 @@ pass ┌ invoke.test.wsim » root/env0/test:invoke │ log inside function └ contains 2 lines pass ┌ invoke.test.wsim » root/env1/test:invoke without inputs and outputs + │ log inside test + │ log inside function + │ contains 2 lines │ no event, no return! └ bang! diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/function/invoke_async.test.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/function/invoke_async.test.w_test_sim.md index 85d0a902992..daa749fa461 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/function/invoke_async.test.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/function/invoke_async.test.w_test_sim.md @@ -5,6 +5,7 @@ pass ┌ invoke_async.test.wsim » root/env0/test:invoke() waits for function to finish └ log inside fn pass ┌ invoke_async.test.wsim » root/env1/test:invokeAsync() returns without waiting for the function finishes + │ log inside fn └ log inside fn diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/http/fetch.test.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/http/fetch.test.w_test_sim.md index 130ce79848c..4a000a529ad 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/http/fetch.test.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/http/fetch.test.w_test_sim.md @@ -4,7 +4,8 @@ ```log pass ┌ fetch.test.wsim » root/env0/test:redirect is 'follow' by default └ I am the target -pass ─ fetch.test.wsim » root/env1/test:redirect 'manual' +pass ┌ fetch.test.wsim » root/env1/test:redirect 'manual' + └ I am the target Tests 2 passed (2) diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/service/http-server.test.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/service/http-server.test.w_test_sim.md index efe67e37b7b..7ab0a7e8013 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/service/http-server.test.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/service/http-server.test.w_test_sim.md @@ -3,8 +3,17 @@ ## stdout.log ```log pass ┌ http-server.test.wsim » root/env0/test:http server is started with the service + │ starting service + │ listening on port + │ starting service + │ listening on port └ bang bang! pass ┌ http-server.test.wsim » root/env1/test:service.stop() closes the http server + │ starting service + │ listening on port + │ starting service + │ listening on port + │ bang bang! └ closing server... diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/service/minimal.test.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/service/minimal.test.w_test_sim.md index 7064a4c25b5..7e9af6719d7 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/service/minimal.test.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/service/minimal.test.w_test_sim.md @@ -3,6 +3,7 @@ ## stdout.log ```log pass ┌ minimal.test.wsim » root/env0/test:start and stop + │ hello, service! └ stopping! diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/service/stateful.test.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/service/stateful.test.w_test_sim.md index 04a2a2d4289..804f7ab4735 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/service/stateful.test.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/service/stateful.test.w_test_sim.md @@ -2,7 +2,8 @@ ## stdout.log ```log -pass ─ stateful.test.wsim » root/env0/test:service is ready only after onStart finishes +pass ┌ stateful.test.wsim » root/env0/test:service is ready only after onStart finishes + └ starting service Tests 1 passed (1) diff --git a/tools/hangar/__snapshots__/test_corpus/valid/inflight_handler_singleton.test.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/inflight_handler_singleton.test.w_test_sim.md index 3bd3576e346..b3d2fa0df48 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/inflight_handler_singleton.test.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/inflight_handler_singleton.test.w_test_sim.md @@ -4,7 +4,8 @@ ```log pass ┌ inflight_handler_singleton.test.wsim » root/env0/test:single instance of Foo └ client has been reused -pass ─ inflight_handler_singleton.test.wsim » root/env1/test:Foo state is not shared between function invocations +pass ┌ inflight_handler_singleton.test.wsim » root/env1/test:Foo state is not shared between function invocations + └ client has been reused Tests 2 passed (2) diff --git a/tools/hangar/__snapshots__/test_corpus/valid/print.test.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/print.test.w_test_sim.md index 95971eb96ae..b83317dbe39 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/print.test.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/print.test.w_test_sim.md @@ -8,6 +8,8 @@ pass ┌ print.test.wsim » root/env0/test:log1 │ inflight log 1.1 └ inflight log 1.2 pass ┌ print.test.wsim » root/env1/test:log2 + │ inflight log 1.1 + │ inflight log 1.2 │ inflight log 2.1 └ inflight log 2.2 diff --git a/tools/hangar/__snapshots__/test_corpus/valid/resource.test.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/resource.test.w_test_sim.md index 5352c15aca0..0f0148a28ae 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/resource.test.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/resource.test.w_test_sim.md @@ -4,7 +4,8 @@ ```log pass ┌ resource.test.wsim » root/env0/test:test └ counter is: 201 -pass ─ resource.test.wsim » root/env1/test:dependency cycles +pass ┌ resource.test.wsim » root/env1/test:dependency cycles + └ counter is: 201 Tests 2 passed (2) diff --git a/tools/hangar/src/utils.ts b/tools/hangar/src/utils.ts index 7b436dd18da..186a0543dde 100644 --- a/tools/hangar/src/utils.ts +++ b/tools/hangar/src/utils.ts @@ -69,6 +69,8 @@ export function sanitizeOutput(output: string) { .replace(/\/.state\/[^ '"]+/g, "/.state/") // Remove duration from test results .replace(/Duration \d+m[\d.]+s/g, "Duration ") + // remove changing ports + .replace(/port \d+/g, "port ") ); } From ab692055f04525b198e1fc96bd5cf98095746c19 Mon Sep 17 00:00:00 2001 From: Ainvoner <2538825+ainvoner@users.noreply.github.com> Date: Thu, 4 Apr 2024 15:09:51 +0300 Subject: [PATCH 05/16] feat(console): hide simulator updates feature behind a feature flag (#6144) Simulator updates feature is not fully ready yet... By default, open the Console without the new simulator update feature. Enable users to use this feature by setting the following env var: `ENABLE_SIM_UPDATES=true` ## Checklist - [ ] Title matches [Winglang's style guide](https://www.winglang.io/contributing/start-here/pull_requests#how-are-pull-request-titles-formatted) - [ ] Description explains motivation and solution - [ ] Tests added (always) - [ ] Docs updated (only required for features) - [ ] Added `pr/e2e-full` label if this feature requires end-to-end testing *By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*. --- apps/wing-console/console/server/src/index.ts | 11 +++++++-- .../console/server/src/utils/simulator.ts | 24 ++++++++++++++----- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/apps/wing-console/console/server/src/index.ts b/apps/wing-console/console/server/src/index.ts index cfda7c98258..18b56b7d9df 100644 --- a/apps/wing-console/console/server/src/index.ts +++ b/apps/wing-console/console/server/src/index.ts @@ -59,6 +59,10 @@ export type RouteNames = keyof inferRouterInputs | undefined; export { isTermsAccepted } from "./utils/terms-and-conditions.js"; +const enableSimUpdates = + process.env.WING_ENABLE_INPLACE_UPDATES === "true" || + process.env.WING_ENABLE_INPLACE_UPDATES === "1"; + export interface CreateConsoleServerOptions { wingfile: string; log: LogInterface; @@ -134,7 +138,10 @@ export const createConsoleServer = async ({ let isStarting = false; let isStopping = false; - const simulator = createSimulator({ stateDir }); + const simulator = createSimulator({ + stateDir, + enableSimUpdates, + }); if (onTrace) { simulator.on("trace", onTrace); } @@ -150,7 +157,7 @@ export const createConsoleServer = async ({ platform, testing: true, }); - const testSimulator = createSimulator(); + const testSimulator = createSimulator({ enableSimUpdates }); testCompiler.on("compiled", ({ simfile }) => { testSimulator.start(simfile); }); diff --git a/apps/wing-console/console/server/src/utils/simulator.ts b/apps/wing-console/console/server/src/utils/simulator.ts index f995ea72d61..40a5abe5dfa 100644 --- a/apps/wing-console/console/server/src/utils/simulator.ts +++ b/apps/wing-console/console/server/src/utils/simulator.ts @@ -25,6 +25,7 @@ export interface Simulator { export interface CreateSimulatorProps { stateDir?: string; + enableSimUpdates?: boolean; } const stopSilently = async (simulator: simulator.Simulator) => { @@ -45,13 +46,25 @@ const stopSilently = async (simulator: simulator.Simulator) => { export const createSimulator = (props?: CreateSimulatorProps): Simulator => { const events = new Emittery(); let instance: simulator.Simulator | undefined; + const handleExistingInstance = async (simfile: string): Promise => { + if (!instance) { + return true; + } + if (props?.enableSimUpdates) { + await events.emit("starting", { instance }); + await instance.update(simfile); + await events.emit("started"); + return false; + } else { + await events.emit("stopping"); + await stopSilently(instance); + return true; + } + }; const start = async (simfile: string) => { try { - if (instance) { - await events.emit("starting", { instance }); - await instance.update(simfile); - await events.emit("started"); - } else { + const shouldStartSim = await handleExistingInstance(simfile); + if (shouldStartSim) { instance = new simulator.Simulator({ simfile, stateDir: props?.stateDir, @@ -61,7 +74,6 @@ export const createSimulator = (props?: CreateSimulatorProps): Simulator => { events.emit("trace", trace); }, }); - await events.emit("starting", { instance }); await instance.start(); await events.emit("started"); From f89bae9690f7a33c24802b19c80ae7d6b90549e2 Mon Sep 17 00:00:00 2001 From: Chris Rybicki Date: Thu, 4 Apr 2024 10:47:10 -0400 Subject: [PATCH 06/16] fix(sdk): cloud.Api routes update incorrectly (#6136) Fixes #6135 There's a bug where `cloud.Api` endpoints can't be called in the simulator after the simulator is updated. The root cause was because the HTTP router used in the implementation wasn't getting updated properly when routes were removed. Currently whenever the simulator reloads, all `cloud.Function` resources are deleted and recreated (a side effect of https://github.com/winglang/wing/pull/6117). Each `cloud.Api` route corresponds to a `cloud.Function` -- so this means all routes are removed and re-added as well. This should be fine, but routes were not getting removed from the express router instance, so the route handlers continued handling requests and try calling old `cloud.Function` instances that no longer existed. ---- This PR fixes the bug by tracking and removing Express.js's internal route handlers when necessary. I couldn't find docs for Express v4 saying it supports this, but I'm guessing it's enough to get us by. An alternative approach offered in https://github.com/winglang/wing/pull/6137. ## Checklist - [x] Title matches [Winglang's style guide](https://www.winglang.io/contributing/start-here/pull_requests#how-are-pull-request-titles-formatted) - [x] Description explains motivation and solution - [x] Tests added (always) - [ ] Docs updated (only required for features) - [ ] Added `pr/e2e-full` label if this feature requires end-to-end testing *By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*. --- libs/wingsdk/src/target-sim/api.inflight.ts | 46 ++++++++++++++++--- libs/wingsdk/test/simulator/cleanup.test.ts | 2 +- libs/wingsdk/test/simulator/simulator.test.ts | 45 ++++++++++++++++++ 3 files changed, 85 insertions(+), 8 deletions(-) diff --git a/libs/wingsdk/src/target-sim/api.inflight.ts b/libs/wingsdk/src/target-sim/api.inflight.ts index 0f32fdb39ac..f53b86400c9 100644 --- a/libs/wingsdk/src/target-sim/api.inflight.ts +++ b/libs/wingsdk/src/target-sim/api.inflight.ts @@ -44,6 +44,7 @@ interface StateFileContents { interface ApiRouteWithFunctionHandle extends ApiRoute { functionHandle: string; + expressLayer: any; } export class Api @@ -178,22 +179,53 @@ export class Api subscriptionProps: EventSubscription ): Promise { const routes = (subscriptionProps as any).routes as ApiRoute[]; - routes.forEach((r) => { + for (const route of routes) { const s = { functionHandle: subscriber, - method: r.method, - pathPattern: r.pathPattern, + method: route.method, + pathPattern: route.pathPattern, }; - this.routes.push(s); this.populateRoute(s, subscriber); - }); + + // Keep track of the internal express function so we can remove it later + // Each layer object in express looks something like this: + // + // Layer { + // handle: [Function: bound dispatch], + // name: 'bound dispatch', + // params: undefined, + // path: undefined, + // keys: [ [Object] ], + // regexp: /^\/foo\/(?:([^\/]+?))\/?$/i { fast_star: false, fast_slash: false }, + // route: Route { path: '/foo/:bar', stack: [Array], methods: [Object] } + // } + const expressRouteHandle = + this.app._router.stack[this.app._router.stack.length - 1]; + this.routes.push({ + ...s, + expressLayer: expressRouteHandle, + }); + } } public async removeEventSubscription(subscriber: string): Promise { const index = this.routes.findIndex((s) => s.functionHandle === subscriber); - if (index >= 0) { - this.routes.splice(index, 1); + if (index === -1) { + this.addTrace( + `Internal error: No route found for subscriber ${subscriber}.` + ); + return; + } + const layer = this.routes[index].expressLayer; + const layerIndex = this.app._router.stack.indexOf(layer); + if (layerIndex === -1) { + this.addTrace( + `Internal error: No express layer found for route ${this.routes[index].pathPattern}.` + ); + return; } + this.app._router.stack.splice(layerIndex, 1); + this.routes.splice(index, 1); } private populateRoute(route: ApiRoute, functionHandle: string): void { diff --git a/libs/wingsdk/test/simulator/cleanup.test.ts b/libs/wingsdk/test/simulator/cleanup.test.ts index 770d27715f6..9a62a311927 100644 --- a/libs/wingsdk/test/simulator/cleanup.test.ts +++ b/libs/wingsdk/test/simulator/cleanup.test.ts @@ -5,7 +5,7 @@ import { Testing } from "../../src/simulator"; import { SimApp } from "../sim-app"; const script = (simdir: string) => ` -const { simulator } = require("./"); +const { simulator } = require("./src"); async function main() { const sim = new simulator.Simulator({ simfile: "${simdir}" }); diff --git a/libs/wingsdk/test/simulator/simulator.test.ts b/libs/wingsdk/test/simulator/simulator.test.ts index 7d8fb866fd6..24015bc5ccd 100644 --- a/libs/wingsdk/test/simulator/simulator.test.ts +++ b/libs/wingsdk/test/simulator/simulator.test.ts @@ -638,6 +638,51 @@ describe("in-place updates", () => { "root/Service started", ]); }); + + test("cloud.Api routes are updated", async () => { + const app = new SimApp(); + const handler = Testing.makeHandler( + `async handle(req) { return { status: 200 }; }` + ); + const api = new Api(app, "Api"); + api.get("/hello", handler); + + const sim = await app.startSimulator(); + const apiUrl = sim.getResourceConfig("/Api").attrs.url as string; + const response1 = await fetch(`${apiUrl}/hello`, { method: "GET" }); + expect(response1.status).toEqual(200); + + const app2 = new SimApp(); + const api2 = new Api(app2, "Api"); + api2.get("/world", handler); + + const app2Dir = app2.synth(); + await sim.update(app2Dir); + + // /hello route should be removed + const response2 = await fetch(`${apiUrl}/hello`, { method: "GET" }); + expect(response2.status).toEqual(404); + + // /world route should be added + const response3 = await fetch(`${apiUrl}/world`, { method: "GET" }); + expect(response3.status).toEqual(200); + + expect(simTraces(sim)).toEqual([ + "root/Api started", + "root/Api/Endpoint started", + "root/Api/OnRequestHandler0 started", + "root/Api/ApiEventMapping0 started", + "Update: 0 added, 3 updated, 0 deleted", + "root/Api/ApiEventMapping0 stopped", + "root/Api/OnRequestHandler0 stopped", + "root/Api/Endpoint stopped", + "root/Api stopped", + "root/Api started", + "root/Api/Endpoint started", + "root/Api/OnRequestHandler0 started", + "root/Api/ApiEventMapping0 started", + ]); + }); }); test("debugging inspector inherited by sandbox", async () => { From e30e50aad2d5e2e5be463da174d11d817ba6ea2c Mon Sep 17 00:00:00 2001 From: Hasan <45375125+hasanaburayyan@users.noreply.github.com> Date: Thu, 4 Apr 2024 13:19:27 -0400 Subject: [PATCH 07/16] fix(compiler): invalid json schema generated for structs with `Json` (#6148) Closes: https://github.com/winglang/wing/issues/5961 ## Summary - Remove `jsonschema` library in place for `Ajv` which is used also in the platform parameters, it supports latest Json schema revisions, where `jsonschema` does not - Enable type unions in json schema validation - Changes generated json schemas of json objects from: `type: "object"` to use type unions for any valid json -> `type: ["object", "string", "number", "boolean", "array"] ## Checklist - [ ] Title matches [Winglang's style guide](https://www.winglang.io/contributing/start-here/pull_requests#how-are-pull-request-titles-formatted) - [ ] Description explains motivation and solution - [ ] Tests added (always) - [ ] Docs updated (only required for features) - [ ] Added `pr/e2e-full` label if this feature requires end-to-end testing *By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*. --- examples/tests/sdk_tests/std/struct.test.w | 22 +++++++++++++++++-- libs/wingc/src/json_schema_generator.rs | 2 +- libs/wingsdk/.projen/deps.json | 4 ---- libs/wingsdk/.projenrc.ts | 1 - libs/wingsdk/package.json | 2 -- libs/wingsdk/src/std/json_schema.ts | 22 ++++++++++--------- pnpm-lock.yaml | 10 ++++----- tools/hangar/__snapshots__/error.ts.snap | 20 ++++++++--------- tools/hangar/__snapshots__/invalid.ts.snap | 6 ++--- .../sdk_tests/std/struct.test.w_test_sim.md | 3 ++- .../struct_from_json.test.w_compile_tf-aws.md | 6 ++--- 11 files changed, 55 insertions(+), 43 deletions(-) diff --git a/examples/tests/sdk_tests/std/struct.test.w b/examples/tests/sdk_tests/std/struct.test.w index 50dc2499275..f7241ffd533 100644 --- a/examples/tests/sdk_tests/std/struct.test.w +++ b/examples/tests/sdk_tests/std/struct.test.w @@ -10,7 +10,7 @@ let assertThrows = inflight (expected: str, block: (): void) => { try { block(); } catch actual { - assert(actual == expected); + expect.equal(actual, expected); error = true; } assert(error); @@ -48,7 +48,7 @@ test "tryParseJson()" { test "invalid parseJson()" { let jsonString = "\{\"name\": \"Billy\", \"age\": false}"; - assertThrows("unable to parse Person:\n- instance.age is not of a type(s) number", () => { + assertThrows("unable to parse Person:\n- Person/age must be number", () => { Person.parseJson(jsonString); }); } @@ -59,4 +59,22 @@ test "invalid tryParseJson()" { if let person = Person.tryParseJson(jsonString) { assert(false); // should not happen } +} + +struct Foo { + someJson: Json; +} + +test "valid Json types" { + let s = Foo.fromJson({someJson: "wow"}); + let b = Foo.fromJson({someJson: true}); + let n = Foo.fromJson({someJson: 123}); + let arr = Foo.fromJson({someJson: [1, 2, 3]}); + let j = Foo.fromJson({someJson: {even: "more json!"}}); + + expect.equal(s.someJson, "wow"); + expect.equal(b.someJson, true); + expect.equal(n.someJson, 123); + expect.equal(arr.someJson, [1, 2, 3]); + expect.equal(j.someJson, {even: "more json!"}); } \ No newline at end of file diff --git a/libs/wingc/src/json_schema_generator.rs b/libs/wingc/src/json_schema_generator.rs index ac4560cf7b9..507946ed83a 100644 --- a/libs/wingc/src/json_schema_generator.rs +++ b/libs/wingc/src/json_schema_generator.rs @@ -79,7 +79,7 @@ impl JsonSchemaGenerator { code.to_string() } Type::Optional(t) => self.get_struct_schema_field(&t), - Type::Json(_) => "{ type: \"object\" }".to_string(), + Type::Json(_) => "{ type: [\"object\", \"string\", \"boolean\", \"number\", \"array\"] }".to_string(), _ => "{ type: \"null\" }".to_string(), } } diff --git a/libs/wingsdk/.projen/deps.json b/libs/wingsdk/.projen/deps.json index 9eac9925809..564972961e0 100644 --- a/libs/wingsdk/.projen/deps.json +++ b/libs/wingsdk/.projen/deps.json @@ -295,10 +295,6 @@ "name": "ioredis", "type": "bundled" }, - { - "name": "jsonschema", - "type": "bundled" - }, { "name": "mime-types", "type": "bundled" diff --git a/libs/wingsdk/.projenrc.ts b/libs/wingsdk/.projenrc.ts index c3a945b332d..addde8d41b3 100644 --- a/libs/wingsdk/.projenrc.ts +++ b/libs/wingsdk/.projenrc.ts @@ -80,7 +80,6 @@ const project = new cdk.JsiiProject({ "cron-parser", // shared client dependencies "ioredis", - "jsonschema", "ajv", "cron-validator", // fs module dependency diff --git a/libs/wingsdk/package.json b/libs/wingsdk/package.json index 974459351a6..10afc75f260 100644 --- a/libs/wingsdk/package.json +++ b/libs/wingsdk/package.json @@ -107,7 +107,6 @@ "glob": "^8.1.0", "google-auth-library": "^8.9.0", "ioredis": "^5.3.2", - "jsonschema": "^1.4.1", "mime": "^3.0.0", "mime-types": "^2.1.35", "nanoid": "^3.3.6", @@ -149,7 +148,6 @@ "glob", "google-auth-library", "ioredis", - "jsonschema", "mime", "mime-types", "nanoid", diff --git a/libs/wingsdk/src/std/json_schema.ts b/libs/wingsdk/src/std/json_schema.ts index 27c32678957..b2084ef1bc8 100644 --- a/libs/wingsdk/src/std/json_schema.ts +++ b/libs/wingsdk/src/std/json_schema.ts @@ -1,4 +1,4 @@ -import { Validator } from "jsonschema"; +import Ajv from "ajv"; import { Json, JsonValidationOptions } from "./json"; import { InflightClient } from "../core"; import { @@ -31,11 +31,11 @@ export class JsonSchema { /** @internal */ public _rawSchema: any; - private validator: Validator; + private validator: Ajv; constructor(schema: Json) { this._rawSchema = schema; - this.validator = new Validator(); + this.validator = new Ajv({ allErrors: true, allowUnionTypes: true }); } /** @@ -48,14 +48,16 @@ export class JsonSchema { if (options?.unsafe) { return; // skip validation } - - const result = this.validator.validate(obj, this._rawSchema); - if (result.errors.length > 0) { + const validator = this.validator.compile(this._rawSchema); + const valid = validator(obj); + if (!valid) { + const schemaId = this._rawSchema.$id.replace("/", ""); throw new Error( - `unable to parse ${this._rawSchema.$id.replace( - "/", - "" - )}:\n- ${result.errors.join("\n- ")}` + `unable to parse ${schemaId}:\n- ${validator.errors + ?.map( + (error: any) => schemaId + error.instancePath + " " + error.message + ) + .join("\n- ")}` ); } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a36dda7f447..e51cf4d90b1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1341,9 +1341,6 @@ importers: ioredis: specifier: ^5.3.2 version: 5.3.2 - jsonschema: - specifier: ^1.4.1 - version: 1.4.1 mime: specifier: ^3.0.0 version: 3.0.0(patch_hash=2he2uszztbibyal6zfzmv2a2oa) @@ -14194,7 +14191,7 @@ packages: dependencies: semver: 7.5.4 shelljs: 0.8.5 - typescript: 5.5.0-dev.20240328 + typescript: 5.5.0-dev.20240404 dev: true /dset@3.1.2: @@ -17871,6 +17868,7 @@ packages: /jsonschema@1.4.1: resolution: {integrity: sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==} + dev: true /jsonwebtoken@9.0.2: resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==} @@ -22802,8 +22800,8 @@ packages: engines: {node: '>=14.17'} hasBin: true - /typescript@5.5.0-dev.20240328: - resolution: {integrity: sha512-psmUop0GPegCmqZqysToBqpX/pKW/0YGwVc/Ma0kDOkruXO40euXu2GL5UM6KbL+nnyHiMtWiTmVQ+7To9s9yQ==} + /typescript@5.5.0-dev.20240404: + resolution: {integrity: sha512-Knb9Yx0JJHc0mmqXLEPPKNSwOvPQrtYZEDLQY7Wns7LckkQl82AZ+OGTPG/ofwqx2QeDCHCtKjutZPy1UEiwKA==} engines: {node: '>=14.17'} hasBin: true dev: true diff --git a/tools/hangar/__snapshots__/error.ts.snap b/tools/hangar/__snapshots__/error.ts.snap index 47882742e78..14b1bb7a334 100644 --- a/tools/hangar/__snapshots__/error.ts.snap +++ b/tools/hangar/__snapshots__/error.ts.snap @@ -2,7 +2,7 @@ exports[`bool_from_json.test.w 1`] = ` "Error: unable to parse bool: -- instance is not of a type(s) boolean +- bool must be boolean --> ../../../examples/tests/error/bool_from_json.test.w:5:15 | // If it is run with other tests, subsequent failures will be ignored in snapshot. | let j = Json { a: 123 }; @@ -91,7 +91,7 @@ Duration " exports[`number_from_json.test.w 1`] = ` "Error: unable to parse num: -- instance is not of a type(s) number +- num must be number --> ../../../examples/tests/error/number_from_json.test.w:5:14 | // If it is run with other tests, subsequent failures will be ignored in snapshot. | let j = Json { a: \\"apples\\" }; @@ -152,7 +152,7 @@ Duration " exports[`string_from_json.test.w 1`] = ` "Error: unable to parse string: -- instance is not of a type(s) string +- string must be string --> ../../../examples/tests/error/string_from_json.test.w:5:14 | // If it is run with other tests, subsequent failures will be ignored in snapshot. | let j = Json { a: 123 }; @@ -169,7 +169,7 @@ Duration " exports[`struct_from_json_1.test.w 1`] = ` "Error: unable to parse Person: -- instance.age is not of a type(s) number +- Person/age must be number --> ../../../examples/tests/error/struct_from_json_1.test.w:11:1 | | let j = {name: \\"cool\\", age: \\"not a number\\"}; @@ -186,8 +186,8 @@ Duration " exports[`struct_from_json_2.test.w 1`] = ` "Error: unable to parse Student: -- instance.age is not of a type(s) number -- instance requires property \\"advisor\\" +- Student must have required property 'advisor' +- Student/age must be number --> ../../../examples/tests/error/struct_from_json_2.test.w:22:1 | age: \\"not a number\\" | }; @@ -204,8 +204,8 @@ Duration " exports[`struct_from_json_3.test.w 1`] = ` "Error: unable to parse Student: -- instance.advisors[1].id is not of a type(s) string -- instance.age is not of a type(s) number +- Student/advisors/1/id must be string +- Student/age must be number --> ../../../examples/tests/error/struct_from_json_3.test.w:26:1 | ] | }; @@ -222,7 +222,7 @@ Duration " exports[`struct_from_json_4.test.w 1`] = ` "Error: unable to parse Student: -- instance.advisors contains duplicate item +- Student/advisors must NOT have duplicate items (items ## 0 and 1 are identical) --> ../../../examples/tests/error/struct_from_json_4.test.w:27:1 | ] | }; @@ -239,7 +239,7 @@ Duration " exports[`struct_from_json_5.test.w 1`] = ` "Error: unable to parse Foo: -- instance.names.c is not of a type(s) string +- Foo/names/c must be string --> ../../../examples/tests/error/struct_from_json_5.test.w:16:1 | } | }; diff --git a/tools/hangar/__snapshots__/invalid.ts.snap b/tools/hangar/__snapshots__/invalid.ts.snap index c8bad3498a1..6cf66d7d09a 100644 --- a/tools/hangar/__snapshots__/invalid.ts.snap +++ b/tools/hangar/__snapshots__/invalid.ts.snap @@ -3752,9 +3752,9 @@ Duration " exports[`struct_from_parameter.test.w 1`] = ` "Error: unable to parse MyParams: -- instance requires property \\"bar\\" -- instance requires property \\"baz\\" -- instance requires property \\"foo\\" +- MyParams must have required property 'bar' +- MyParams must have required property 'baz' +- MyParams must have required property 'foo' --> ../../../examples/tests/invalid/struct_from_parameter.test.w:14:1 | // technically we never enforced the parameters must have been | // provided diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/struct.test.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/struct.test.w_test_sim.md index 403f7eb2f2b..430602726ce 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/struct.test.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/struct.test.w_test_sim.md @@ -6,9 +6,10 @@ pass ─ struct.test.wsim » root/env0/test:parseJson() pass ─ struct.test.wsim » root/env1/test:tryParseJson() pass ─ struct.test.wsim » root/env2/test:invalid parseJson() pass ─ struct.test.wsim » root/env3/test:invalid tryParseJson() +pass ─ struct.test.wsim » root/env4/test:valid Json types -Tests 4 passed (4) +Tests 5 passed (5) Test Files 1 passed (1) Duration ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/struct_from_json.test.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/struct_from_json.test.w_compile_tf-aws.md index 52865eb4974..8b709681bf6 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/struct_from_json.test.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/struct_from_json.test.w_compile_tf-aws.md @@ -187,7 +187,7 @@ class $Root extends $stdlib.std.Resource { const Foosible = $stdlib.std.Struct._createJsonSchema({$id:"/Foosible",type:"object",properties:{f:{type:"string"},},required:[]}); const MyStruct = $stdlib.std.Struct._createJsonSchema({$id:"/MyStruct",type:"object",properties:{m1:{type:"object",properties:{val:{type:"number"},},required:["val",]},m2:{type:"object",properties:{val:{type:"string"},},required:["val",]},},required:["m1","m2",]}); const SomeStruct = $stdlib.std.Struct._createJsonSchema({$id:"/SomeStruct",type:"object",properties:{foo:{type:"string"},},required:["foo",]}); - const Student = $stdlib.std.Struct._createJsonSchema({$id:"/Student",type:"object",properties:{additionalData:{type:"object"},advisor:{type:"object",properties:{dob:{type:"object",properties:{day:{type:"number"},month:{type:"number"},year:{type:"number"},},required:["day","month","year",]},employeeID:{type:"string"},firstName:{type:"string"},lastName:{type:"string"},},required:["dob","employeeID","firstName","lastName",]},coursesTaken:{type:"array",items:{type:"object",properties:{course:{type:"object",properties:{credits:{type:"number"},name:{type:"string"},},required:["credits","name",]},dateTaken:{type:"object",properties:{day:{type:"number"},month:{type:"number"},year:{type:"number"},},required:["day","month","year",]},grade:{type:"string"},},required:["course","dateTaken","grade",]}},dob:{type:"object",properties:{day:{type:"number"},month:{type:"number"},year:{type:"number"},},required:["day","month","year",]},enrolled:{type:"boolean"},enrolledCourses:{type:"array",uniqueItems:true,items:{type:"object",properties:{credits:{type:"number"},name:{type:"string"},},required:["credits","name",]}},firstName:{type:"string"},lastName:{type:"string"},schoolId:{type:"string"},},required:["dob","enrolled","firstName","lastName","schoolId",]}); + const Student = $stdlib.std.Struct._createJsonSchema({$id:"/Student",type:"object",properties:{additionalData:{type:["object","string","boolean","number","array"]},advisor:{type:"object",properties:{dob:{type:"object",properties:{day:{type:"number"},month:{type:"number"},year:{type:"number"},},required:["day","month","year",]},employeeID:{type:"string"},firstName:{type:"string"},lastName:{type:"string"},},required:["dob","employeeID","firstName","lastName",]},coursesTaken:{type:"array",items:{type:"object",properties:{course:{type:"object",properties:{credits:{type:"number"},name:{type:"string"},},required:["credits","name",]},dateTaken:{type:"object",properties:{day:{type:"number"},month:{type:"number"},year:{type:"number"},},required:["day","month","year",]},grade:{type:"string"},},required:["course","dateTaken","grade",]}},dob:{type:"object",properties:{day:{type:"number"},month:{type:"number"},year:{type:"number"},},required:["day","month","year",]},enrolled:{type:"boolean"},enrolledCourses:{type:"array",uniqueItems:true,items:{type:"object",properties:{credits:{type:"number"},name:{type:"string"},},required:["credits","name",]}},firstName:{type:"string"},lastName:{type:"string"},schoolId:{type:"string"},},required:["dob","enrolled","firstName","lastName","schoolId",]}); const cloud_BucketProps = $stdlib.std.Struct._createJsonSchema({$id:"/BucketProps",type:"object",properties:{public:{type:"boolean"},},required:[]}); const externalStructs_MyOtherStruct = $stdlib.std.Struct._createJsonSchema({$id:"/MyOtherStruct",type:"object",properties:{data:{type:"object",properties:{val:{type:"number"},},required:["val",]},},required:["data",]}); class $Closure1 extends $stdlib.std.AutoIdResource { @@ -516,7 +516,7 @@ const Foo = $stdlib.std.Struct._createJsonSchema({$id:"/Foo",type:"object",prope const Foosible = $stdlib.std.Struct._createJsonSchema({$id:"/Foosible",type:"object",properties:{f:{type:"string"},},required:[]}); const MyStruct = $stdlib.std.Struct._createJsonSchema({$id:"/MyStruct",type:"object",properties:{m1:{type:"object",properties:{val:{type:"number"},},required:["val",]},m2:{type:"object",properties:{val:{type:"string"},},required:["val",]},},required:["m1","m2",]}); const SomeStruct = $stdlib.std.Struct._createJsonSchema({$id:"/SomeStruct",type:"object",properties:{foo:{type:"string"},},required:["foo",]}); -const Student = $stdlib.std.Struct._createJsonSchema({$id:"/Student",type:"object",properties:{additionalData:{type:"object"},advisor:{type:"object",properties:{dob:{type:"object",properties:{day:{type:"number"},month:{type:"number"},year:{type:"number"},},required:["day","month","year",]},employeeID:{type:"string"},firstName:{type:"string"},lastName:{type:"string"},},required:["dob","employeeID","firstName","lastName",]},coursesTaken:{type:"array",items:{type:"object",properties:{course:{type:"object",properties:{credits:{type:"number"},name:{type:"string"},},required:["credits","name",]},dateTaken:{type:"object",properties:{day:{type:"number"},month:{type:"number"},year:{type:"number"},},required:["day","month","year",]},grade:{type:"string"},},required:["course","dateTaken","grade",]}},dob:{type:"object",properties:{day:{type:"number"},month:{type:"number"},year:{type:"number"},},required:["day","month","year",]},enrolled:{type:"boolean"},enrolledCourses:{type:"array",uniqueItems:true,items:{type:"object",properties:{credits:{type:"number"},name:{type:"string"},},required:["credits","name",]}},firstName:{type:"string"},lastName:{type:"string"},schoolId:{type:"string"},},required:["dob","enrolled","firstName","lastName","schoolId",]}); +const Student = $stdlib.std.Struct._createJsonSchema({$id:"/Student",type:"object",properties:{additionalData:{type:["object","string","boolean","number","array"]},advisor:{type:"object",properties:{dob:{type:"object",properties:{day:{type:"number"},month:{type:"number"},year:{type:"number"},},required:["day","month","year",]},employeeID:{type:"string"},firstName:{type:"string"},lastName:{type:"string"},},required:["dob","employeeID","firstName","lastName",]},coursesTaken:{type:"array",items:{type:"object",properties:{course:{type:"object",properties:{credits:{type:"number"},name:{type:"string"},},required:["credits","name",]},dateTaken:{type:"object",properties:{day:{type:"number"},month:{type:"number"},year:{type:"number"},},required:["day","month","year",]},grade:{type:"string"},},required:["course","dateTaken","grade",]}},dob:{type:"object",properties:{day:{type:"number"},month:{type:"number"},year:{type:"number"},},required:["day","month","year",]},enrolled:{type:"boolean"},enrolledCourses:{type:"array",uniqueItems:true,items:{type:"object",properties:{credits:{type:"number"},name:{type:"string"},},required:["credits","name",]}},firstName:{type:"string"},lastName:{type:"string"},schoolId:{type:"string"},},required:["dob","enrolled","firstName","lastName","schoolId",]}); const cloud_BucketProps = $stdlib.std.Struct._createJsonSchema({$id:"/BucketProps",type:"object",properties:{public:{type:"boolean"},},required:[]}); const externalStructs_MyOtherStruct = $stdlib.std.Struct._createJsonSchema({$id:"/MyOtherStruct",type:"object",properties:{data:{type:"object",properties:{val:{type:"number"},},required:["val",]},},required:["data",]}); module.exports = { }; @@ -534,7 +534,7 @@ const Foo = $stdlib.std.Struct._createJsonSchema({$id:"/Foo",type:"object",prope const Foosible = $stdlib.std.Struct._createJsonSchema({$id:"/Foosible",type:"object",properties:{f:{type:"string"},},required:[]}); const MyStruct = $stdlib.std.Struct._createJsonSchema({$id:"/MyStruct",type:"object",properties:{m1:{type:"object",properties:{val:{type:"number"},},required:["val",]},m2:{type:"object",properties:{val:{type:"string"},},required:["val",]},},required:["m1","m2",]}); const SomeStruct = $stdlib.std.Struct._createJsonSchema({$id:"/SomeStruct",type:"object",properties:{foo:{type:"string"},},required:["foo",]}); -const Student = $stdlib.std.Struct._createJsonSchema({$id:"/Student",type:"object",properties:{additionalData:{type:"object"},advisor:{type:"object",properties:{dob:{type:"object",properties:{day:{type:"number"},month:{type:"number"},year:{type:"number"},},required:["day","month","year",]},employeeID:{type:"string"},firstName:{type:"string"},lastName:{type:"string"},},required:["dob","employeeID","firstName","lastName",]},coursesTaken:{type:"array",items:{type:"object",properties:{course:{type:"object",properties:{credits:{type:"number"},name:{type:"string"},},required:["credits","name",]},dateTaken:{type:"object",properties:{day:{type:"number"},month:{type:"number"},year:{type:"number"},},required:["day","month","year",]},grade:{type:"string"},},required:["course","dateTaken","grade",]}},dob:{type:"object",properties:{day:{type:"number"},month:{type:"number"},year:{type:"number"},},required:["day","month","year",]},enrolled:{type:"boolean"},enrolledCourses:{type:"array",uniqueItems:true,items:{type:"object",properties:{credits:{type:"number"},name:{type:"string"},},required:["credits","name",]}},firstName:{type:"string"},lastName:{type:"string"},schoolId:{type:"string"},},required:["dob","enrolled","firstName","lastName","schoolId",]}); +const Student = $stdlib.std.Struct._createJsonSchema({$id:"/Student",type:"object",properties:{additionalData:{type:["object","string","boolean","number","array"]},advisor:{type:"object",properties:{dob:{type:"object",properties:{day:{type:"number"},month:{type:"number"},year:{type:"number"},},required:["day","month","year",]},employeeID:{type:"string"},firstName:{type:"string"},lastName:{type:"string"},},required:["dob","employeeID","firstName","lastName",]},coursesTaken:{type:"array",items:{type:"object",properties:{course:{type:"object",properties:{credits:{type:"number"},name:{type:"string"},},required:["credits","name",]},dateTaken:{type:"object",properties:{day:{type:"number"},month:{type:"number"},year:{type:"number"},},required:["day","month","year",]},grade:{type:"string"},},required:["course","dateTaken","grade",]}},dob:{type:"object",properties:{day:{type:"number"},month:{type:"number"},year:{type:"number"},},required:["day","month","year",]},enrolled:{type:"boolean"},enrolledCourses:{type:"array",uniqueItems:true,items:{type:"object",properties:{credits:{type:"number"},name:{type:"string"},},required:["credits","name",]}},firstName:{type:"string"},lastName:{type:"string"},schoolId:{type:"string"},},required:["dob","enrolled","firstName","lastName","schoolId",]}); const cloud_BucketProps = $stdlib.std.Struct._createJsonSchema({$id:"/BucketProps",type:"object",properties:{public:{type:"boolean"},},required:[]}); const externalStructs_MyOtherStruct = $stdlib.std.Struct._createJsonSchema({$id:"/MyOtherStruct",type:"object",properties:{data:{type:"object",properties:{val:{type:"number"},},required:["val",]},},required:["data",]}); class UsesStructInImportedFile extends $stdlib.std.Resource { From 23e2be2dd816d8cc31de1cc49bd2244c4c04ec84 Mon Sep 17 00:00:00 2001 From: Mark McCulloh Date: Thu, 4 Apr 2024 20:31:03 -0400 Subject: [PATCH 08/16] fix: missing uncaught inflight exceptions when debugging (#6152) During normal usage, when an unhandled exception occurs inflight we will prepare a stack trace for the user to show them where things went wrong. When debugging, the `throw` itself tells you it happened first. Since we were technically catching all inflight errors, the useful concept of "break on uncaught exception" didn't work. With this change, the original errors remain uncaught and we can still communicate that error with the parent process. *By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*. --- docs/docs/06-tools/03-debugging.md | 1 - libs/wingsdk/src/shared/sandbox.ts | 12 ++++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/docs/06-tools/03-debugging.md b/docs/docs/06-tools/03-debugging.md index 7b4433efcf7..631aa9f2133 100644 --- a/docs/docs/06-tools/03-debugging.md +++ b/docs/docs/06-tools/03-debugging.md @@ -18,7 +18,6 @@ Open the command palette and type "Debug: Open JavaScript Debug Terminal". This - ([Issue](https://github.com/winglang/wing/issues/5988)) When using the Wing Console (`wing it`) and attempting to debug inflight code in a `test` or Function, the first execution of the test will not hit a breakpoint and will need to be run again - ([Issue](https://github.com/winglang/wing/issues/5986)) inflight code by default has a timeout that continues during debugging, so if execution is paused for too long the program is terminate -- Caught/Unhandled will often not stop at expected places #### Non-VSCode Support diff --git a/libs/wingsdk/src/shared/sandbox.ts b/libs/wingsdk/src/shared/sandbox.ts index 0fe362f3195..f61d61fde6d 100644 --- a/libs/wingsdk/src/shared/sandbox.ts +++ b/libs/wingsdk/src/shared/sandbox.ts @@ -50,14 +50,14 @@ export class Sandbox { // wrap contents with a shim that handles the communication with the parent process // we insert this shim before bundling to ensure source maps are generated correctly contents += ` +process.setUncaughtExceptionCaptureCallback((reason) => { + process.send({ type: "reject", reason }); +}); + process.on("message", async (message) => { const { fn, args } = message; - try { - const value = await exports[fn](...args); - process.send({ type: "resolve", value }); - } catch (err) { - process.send({ type: "reject", reason: err }); - } + const value = await exports[fn](...args); + process.send({ type: "resolve", value }); }); `; const wrappedPath = entrypoint.replace(/\.js$/, ".sandbox.js"); From fd9ddcc8335549adc132b4d30c4fb504d77eb09d Mon Sep 17 00:00:00 2001 From: Marcio Cruz de Almeida <67694075+marciocadev@users.noreply.github.com> Date: Thu, 4 Apr 2024 22:51:44 -0300 Subject: [PATCH 09/16] feat(sdk): subscribing queues to topics (#6132) - [x] subscribing queue to topic (sim) - [x] subscribing queue to topic (tf-aws) - [x] subscribing queue to topic (awscdk) - [x] wing test Closes #6032 ## Checklist - [x] Title matches [Winglang's style guide](https://www.winglang.io/contributing/start-here/pull_requests#how-are-pull-request-titles-formatted) - [x] Description explains motivation and solution - [ ] Tests added (always) - [ ] Docs updated (only required for features) - [ ] Added `pr/e2e-full` label if this feature requires end-to-end testing *By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*. --- docs/docs/04-standard-library/cloud/topic.md | 82 ++++ .../sdk_tests/topic/subscribe-queue.test.w | 36 ++ libs/awscdk/src/topic.ts | 14 +- .../incomplete_inflight_namespace.snap | 8 +- .../completions/namespace_middle_dot.snap | 8 +- .../completions/new_expression_nested.snap | 2 +- .../partial_type_reference_annotation.snap | 8 +- .../variable_type_annotation_namespace.snap | 8 +- libs/wingsdk/src/cloud/topic.md | 14 + libs/wingsdk/src/cloud/topic.ts | 18 + libs/wingsdk/src/target-sim/topic.ts | 45 +- libs/wingsdk/src/target-tf-aws/topic.ts | 45 +- .../subscribe-queue.test.w_compile_tf-aws.md | 443 ++++++++++++++++++ .../topic/subscribe-queue.test.w_test_sim.md | 12 + 14 files changed, 735 insertions(+), 8 deletions(-) create mode 100644 examples/tests/sdk_tests/topic/subscribe-queue.test.w create mode 100644 tools/hangar/__snapshots__/test_corpus/sdk_tests/topic/subscribe-queue.test.w_compile_tf-aws.md create mode 100644 tools/hangar/__snapshots__/test_corpus/sdk_tests/topic/subscribe-queue.test.w_test_sim.md diff --git a/docs/docs/04-standard-library/cloud/topic.md b/docs/docs/04-standard-library/cloud/topic.md index 74e3342b164..3881a60741e 100644 --- a/docs/docs/04-standard-library/cloud/topic.md +++ b/docs/docs/04-standard-library/cloud/topic.md @@ -40,6 +40,20 @@ topic.onMessage(inflight (message: str) => { }); ``` +### Subscribing a Queue to a Topic + +```js +bring cloud; + +let queue = new cloud.Queue(); +queue.setConsumer(inflight (message str) => { + log("Topic published message: {message}"); +}); + +let topic = new cloud.Topic(); +topic.subscribeQueue(queue); +``` + ### Publishing to a topic The inflight method `publish` sends a message to all of the topic's subscribers. @@ -135,6 +149,7 @@ new cloud.Topic(props?: TopicProps); | **Name** | **Description** | | --- | --- | | onMessage | Run an inflight whenever an message is published to the topic. | +| subscribeQueue | Subscribing queue to the topic. | ##### Inflight Methods @@ -164,6 +179,26 @@ Run an inflight whenever an message is published to the topic. --- +##### `subscribeQueue` + +```wing +subscribeQueue(queue: Queue, props?: TopicSubscribeQueueOptions): void +``` + +Subscribing queue to the topic. + +###### `queue`Required + +- *Type:* Queue + +--- + +###### `props`Optional + +- *Type:* TopicSubscribeQueueOptions + +--- + ##### `publish` ```wing @@ -344,6 +379,53 @@ let TopicProps = cloud.TopicProps{ ... }; ``` +### TopicSubscribeQueueOptions + +Options for `Topic.subscribeQueue`. + +#### Initializer + +```wing +bring cloud; + +let TopicSubscribeQueueOptions = cloud.TopicSubscribeQueueOptions{ ... }; +``` + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| retentionPeriod | duration | How long a queue retains a message. | +| timeout | duration | How long a queue's consumers have to process a message. | + +--- + +##### `retentionPeriod`Optional + +```wing +retentionPeriod: duration; +``` + +- *Type:* duration +- *Default:* 1h + +How long a queue retains a message. + +--- + +##### `timeout`Optional + +```wing +timeout: duration; +``` + +- *Type:* duration +- *Default:* 30s + +How long a queue's consumers have to process a message. + +--- + ## Protocols ### ITopicOnMessageHandler diff --git a/examples/tests/sdk_tests/topic/subscribe-queue.test.w b/examples/tests/sdk_tests/topic/subscribe-queue.test.w new file mode 100644 index 00000000000..554d7034c52 --- /dev/null +++ b/examples/tests/sdk_tests/topic/subscribe-queue.test.w @@ -0,0 +1,36 @@ +bring cloud; +bring util; + +let msg_test = "Hello World!!1"; + +let c = new cloud.Counter(); + +let t = new cloud.Topic(); +t.onMessage(inflight (msg: str) => { + if msg == msg_test { + c.inc(1, "t"); + } +}); + +let q1 = new cloud.Queue() as "q1"; +q1.setConsumer(inflight (msg: str) => { + if msg == msg_test { + c.inc(1, "q1"); + } +}); +t.subscribeQueue(q1); + +let q2 = new cloud.Queue() as "q2"; +q2.setConsumer(inflight (msg: str) => { + if msg == msg_test { + c.inc(1, "q2"); + } +}); +t.subscribeQueue(q2); + +test "functions and queues receiving messages from the topic" { + t.publish(msg_test); + assert(util.waitUntil(inflight () => { return c.peek("q1") == 1; })); + assert(util.waitUntil(inflight () => { return c.peek("q2") == 1; })); + assert(util.waitUntil(inflight () => { return c.peek("t") == 1; })); +} diff --git a/libs/awscdk/src/topic.ts b/libs/awscdk/src/topic.ts index 93a5b6758b0..904fed261bf 100644 --- a/libs/awscdk/src/topic.ts +++ b/libs/awscdk/src/topic.ts @@ -1,6 +1,7 @@ import { join } from "path"; import { Topic as SNSTopic } from "aws-cdk-lib/aws-sns"; -import { LambdaSubscription } from "aws-cdk-lib/aws-sns-subscriptions"; +import { Queue as SQSQeueue } from "aws-cdk-lib/aws-sqs"; +import { LambdaSubscription, SqsSubscription } from "aws-cdk-lib/aws-sns-subscriptions"; import { Construct } from "constructs"; import { App } from "./app"; import { cloud, core, std } from "@winglang/sdk"; @@ -8,6 +9,7 @@ import { convertBetweenHandlers } from "@winglang/sdk/lib/shared/convert"; import { calculateTopicPermissions } from "@winglang/sdk/lib/shared-aws/permissions"; import { IAwsTopic } from "@winglang/sdk/lib/shared-aws/topic"; import { addPolicyStatements, isAwsCdkFunction } from "./function"; +import { Queue } from "./queue"; /** * AWS Implementation of `cloud.Topic`. @@ -58,6 +60,16 @@ export class Topic extends cloud.Topic implements IAwsTopic { return fn; } + public subscribeQueue(queue: cloud.Queue): void { + if (!(queue instanceof Queue)) { + throw new Error("'subscribeQueue' allows only tfaws.Queue to be subscribed to the Topic"); + } + + const baseTopic = SNSTopic.fromTopicArn(this, "BaseTopic", this.topicArn); + const baseQueue = SQSQeueue.fromQueueArn(this, "BaseQueue", queue.queueArn); + baseTopic.addSubscription(new SqsSubscription(baseQueue)); + } + public onLift(host: std.IInflightHost, ops: string[]): void { if (!isAwsCdkFunction(host)) { throw new Error("Expected 'host' to implement 'IAwsCdkFunction' method"); diff --git a/libs/wingc/src/lsp/snapshots/completions/incomplete_inflight_namespace.snap b/libs/wingc/src/lsp/snapshots/completions/incomplete_inflight_namespace.snap index bfe32f53fca..2f1d4d58221 100644 --- a/libs/wingc/src/lsp/snapshots/completions/incomplete_inflight_namespace.snap +++ b/libs/wingc/src/lsp/snapshots/completions/incomplete_inflight_namespace.snap @@ -71,7 +71,7 @@ source: libs/wingc/src/lsp/completions.rs kind: 7 documentation: kind: markdown - value: "```wing\nclass Topic\n```\n---\nA topic.\n\n### Initializer\n- `...props` — `TopicProps?`\n### Fields\n- `node` — `Node` — The tree node.\n### Methods\n- `isConstruct` — `preflight (x: any): bool` — Checks if `x` is a construct.\n- `onLift` — `preflight (host: IInflightHost, ops: Array): void` — A hook called by the Wing compiler once for each inflight host that needs to use this resource inflight.\n- `onLiftType` — `preflight (host: IInflightHost, ops: Array): void` — A hook called by the Wing compiler once for each inflight host that needs to use this type inflight.\n- `onMessage` — `preflight (inflight: inflight (event: str): void, props: TopicOnMessageOptions?): Function` — Run an inflight whenever an message is published to the topic.\n- `publish` — `inflight (message: str): void` — Publish message to topic.\n- `toString` — `preflight (): str` — Returns a string representation of this construct." + value: "```wing\nclass Topic\n```\n---\nA topic.\n\n### Initializer\n- `...props` — `TopicProps?`\n### Fields\n- `node` — `Node` — The tree node.\n### Methods\n- `isConstruct` — `preflight (x: any): bool` — Checks if `x` is a construct.\n- `onLift` — `preflight (host: IInflightHost, ops: Array): void` — A hook called by the Wing compiler once for each inflight host that needs to use this resource inflight.\n- `onLiftType` — `preflight (host: IInflightHost, ops: Array): void` — A hook called by the Wing compiler once for each inflight host that needs to use this type inflight.\n- `onMessage` — `preflight (inflight: inflight (event: str): void, props: TopicOnMessageOptions?): Function` — Run an inflight whenever an message is published to the topic.\n- `publish` — `inflight (message: str): void` — Publish message to topic.\n- `subscribeQueue` — `preflight (queue: Queue, props: TopicSubscribeQueueOptions?): void` — Subscribing queue to the topic.\n- `toString` — `preflight (): str` — Returns a string representation of this construct." sortText: gg|Topic - label: Website kind: 7 @@ -319,6 +319,12 @@ source: libs/wingc/src/lsp/completions.rs kind: markdown value: "```wing\nstruct TopicProps\n```\n---\nOptions for `Topic`." sortText: hh|TopicProps +- label: TopicSubscribeQueueOptions + kind: 22 + documentation: + kind: markdown + value: "```wing\nstruct TopicSubscribeQueueOptions extends QueueProps\n```\n---\nOptions for `Topic.subscribeQueue`.\n### Fields\n- `retentionPeriod?` — `duration?`\n- `timeout?` — `duration?`" + sortText: hh|TopicSubscribeQueueOptions - label: WebsiteDomainOptions kind: 22 documentation: diff --git a/libs/wingc/src/lsp/snapshots/completions/namespace_middle_dot.snap b/libs/wingc/src/lsp/snapshots/completions/namespace_middle_dot.snap index bfe32f53fca..2f1d4d58221 100644 --- a/libs/wingc/src/lsp/snapshots/completions/namespace_middle_dot.snap +++ b/libs/wingc/src/lsp/snapshots/completions/namespace_middle_dot.snap @@ -71,7 +71,7 @@ source: libs/wingc/src/lsp/completions.rs kind: 7 documentation: kind: markdown - value: "```wing\nclass Topic\n```\n---\nA topic.\n\n### Initializer\n- `...props` — `TopicProps?`\n### Fields\n- `node` — `Node` — The tree node.\n### Methods\n- `isConstruct` — `preflight (x: any): bool` — Checks if `x` is a construct.\n- `onLift` — `preflight (host: IInflightHost, ops: Array): void` — A hook called by the Wing compiler once for each inflight host that needs to use this resource inflight.\n- `onLiftType` — `preflight (host: IInflightHost, ops: Array): void` — A hook called by the Wing compiler once for each inflight host that needs to use this type inflight.\n- `onMessage` — `preflight (inflight: inflight (event: str): void, props: TopicOnMessageOptions?): Function` — Run an inflight whenever an message is published to the topic.\n- `publish` — `inflight (message: str): void` — Publish message to topic.\n- `toString` — `preflight (): str` — Returns a string representation of this construct." + value: "```wing\nclass Topic\n```\n---\nA topic.\n\n### Initializer\n- `...props` — `TopicProps?`\n### Fields\n- `node` — `Node` — The tree node.\n### Methods\n- `isConstruct` — `preflight (x: any): bool` — Checks if `x` is a construct.\n- `onLift` — `preflight (host: IInflightHost, ops: Array): void` — A hook called by the Wing compiler once for each inflight host that needs to use this resource inflight.\n- `onLiftType` — `preflight (host: IInflightHost, ops: Array): void` — A hook called by the Wing compiler once for each inflight host that needs to use this type inflight.\n- `onMessage` — `preflight (inflight: inflight (event: str): void, props: TopicOnMessageOptions?): Function` — Run an inflight whenever an message is published to the topic.\n- `publish` — `inflight (message: str): void` — Publish message to topic.\n- `subscribeQueue` — `preflight (queue: Queue, props: TopicSubscribeQueueOptions?): void` — Subscribing queue to the topic.\n- `toString` — `preflight (): str` — Returns a string representation of this construct." sortText: gg|Topic - label: Website kind: 7 @@ -319,6 +319,12 @@ source: libs/wingc/src/lsp/completions.rs kind: markdown value: "```wing\nstruct TopicProps\n```\n---\nOptions for `Topic`." sortText: hh|TopicProps +- label: TopicSubscribeQueueOptions + kind: 22 + documentation: + kind: markdown + value: "```wing\nstruct TopicSubscribeQueueOptions extends QueueProps\n```\n---\nOptions for `Topic.subscribeQueue`.\n### Fields\n- `retentionPeriod?` — `duration?`\n- `timeout?` — `duration?`" + sortText: hh|TopicSubscribeQueueOptions - label: WebsiteDomainOptions kind: 22 documentation: diff --git a/libs/wingc/src/lsp/snapshots/completions/new_expression_nested.snap b/libs/wingc/src/lsp/snapshots/completions/new_expression_nested.snap index 8ccc2e0fadd..2f4723ceb43 100644 --- a/libs/wingc/src/lsp/snapshots/completions/new_expression_nested.snap +++ b/libs/wingc/src/lsp/snapshots/completions/new_expression_nested.snap @@ -126,7 +126,7 @@ source: libs/wingc/src/lsp/completions.rs kind: 7 documentation: kind: markdown - value: "```wing\nclass Topic\n```\n---\nA topic.\n\n### Initializer\n- `...props` — `TopicProps?`\n### Fields\n- `node` — `Node` — The tree node.\n### Methods\n- `isConstruct` — `preflight (x: any): bool` — Checks if `x` is a construct.\n- `onLift` — `preflight (host: IInflightHost, ops: Array): void` — A hook called by the Wing compiler once for each inflight host that needs to use this resource inflight.\n- `onLiftType` — `preflight (host: IInflightHost, ops: Array): void` — A hook called by the Wing compiler once for each inflight host that needs to use this type inflight.\n- `onMessage` — `preflight (inflight: inflight (event: str): void, props: TopicOnMessageOptions?): Function` — Run an inflight whenever an message is published to the topic.\n- `publish` — `inflight (message: str): void` — Publish message to topic.\n- `toString` — `preflight (): str` — Returns a string representation of this construct." + value: "```wing\nclass Topic\n```\n---\nA topic.\n\n### Initializer\n- `...props` — `TopicProps?`\n### Fields\n- `node` — `Node` — The tree node.\n### Methods\n- `isConstruct` — `preflight (x: any): bool` — Checks if `x` is a construct.\n- `onLift` — `preflight (host: IInflightHost, ops: Array): void` — A hook called by the Wing compiler once for each inflight host that needs to use this resource inflight.\n- `onLiftType` — `preflight (host: IInflightHost, ops: Array): void` — A hook called by the Wing compiler once for each inflight host that needs to use this type inflight.\n- `onMessage` — `preflight (inflight: inflight (event: str): void, props: TopicOnMessageOptions?): Function` — Run an inflight whenever an message is published to the topic.\n- `publish` — `inflight (message: str): void` — Publish message to topic.\n- `subscribeQueue` — `preflight (queue: Queue, props: TopicSubscribeQueueOptions?): void` — Subscribing queue to the topic.\n- `toString` — `preflight (): str` — Returns a string representation of this construct." sortText: gg|Topic insertText: Topic($1) insertTextFormat: 2 diff --git a/libs/wingc/src/lsp/snapshots/completions/partial_type_reference_annotation.snap b/libs/wingc/src/lsp/snapshots/completions/partial_type_reference_annotation.snap index bfe32f53fca..2f1d4d58221 100644 --- a/libs/wingc/src/lsp/snapshots/completions/partial_type_reference_annotation.snap +++ b/libs/wingc/src/lsp/snapshots/completions/partial_type_reference_annotation.snap @@ -71,7 +71,7 @@ source: libs/wingc/src/lsp/completions.rs kind: 7 documentation: kind: markdown - value: "```wing\nclass Topic\n```\n---\nA topic.\n\n### Initializer\n- `...props` — `TopicProps?`\n### Fields\n- `node` — `Node` — The tree node.\n### Methods\n- `isConstruct` — `preflight (x: any): bool` — Checks if `x` is a construct.\n- `onLift` — `preflight (host: IInflightHost, ops: Array): void` — A hook called by the Wing compiler once for each inflight host that needs to use this resource inflight.\n- `onLiftType` — `preflight (host: IInflightHost, ops: Array): void` — A hook called by the Wing compiler once for each inflight host that needs to use this type inflight.\n- `onMessage` — `preflight (inflight: inflight (event: str): void, props: TopicOnMessageOptions?): Function` — Run an inflight whenever an message is published to the topic.\n- `publish` — `inflight (message: str): void` — Publish message to topic.\n- `toString` — `preflight (): str` — Returns a string representation of this construct." + value: "```wing\nclass Topic\n```\n---\nA topic.\n\n### Initializer\n- `...props` — `TopicProps?`\n### Fields\n- `node` — `Node` — The tree node.\n### Methods\n- `isConstruct` — `preflight (x: any): bool` — Checks if `x` is a construct.\n- `onLift` — `preflight (host: IInflightHost, ops: Array): void` — A hook called by the Wing compiler once for each inflight host that needs to use this resource inflight.\n- `onLiftType` — `preflight (host: IInflightHost, ops: Array): void` — A hook called by the Wing compiler once for each inflight host that needs to use this type inflight.\n- `onMessage` — `preflight (inflight: inflight (event: str): void, props: TopicOnMessageOptions?): Function` — Run an inflight whenever an message is published to the topic.\n- `publish` — `inflight (message: str): void` — Publish message to topic.\n- `subscribeQueue` — `preflight (queue: Queue, props: TopicSubscribeQueueOptions?): void` — Subscribing queue to the topic.\n- `toString` — `preflight (): str` — Returns a string representation of this construct." sortText: gg|Topic - label: Website kind: 7 @@ -319,6 +319,12 @@ source: libs/wingc/src/lsp/completions.rs kind: markdown value: "```wing\nstruct TopicProps\n```\n---\nOptions for `Topic`." sortText: hh|TopicProps +- label: TopicSubscribeQueueOptions + kind: 22 + documentation: + kind: markdown + value: "```wing\nstruct TopicSubscribeQueueOptions extends QueueProps\n```\n---\nOptions for `Topic.subscribeQueue`.\n### Fields\n- `retentionPeriod?` — `duration?`\n- `timeout?` — `duration?`" + sortText: hh|TopicSubscribeQueueOptions - label: WebsiteDomainOptions kind: 22 documentation: diff --git a/libs/wingc/src/lsp/snapshots/completions/variable_type_annotation_namespace.snap b/libs/wingc/src/lsp/snapshots/completions/variable_type_annotation_namespace.snap index bfe32f53fca..2f1d4d58221 100644 --- a/libs/wingc/src/lsp/snapshots/completions/variable_type_annotation_namespace.snap +++ b/libs/wingc/src/lsp/snapshots/completions/variable_type_annotation_namespace.snap @@ -71,7 +71,7 @@ source: libs/wingc/src/lsp/completions.rs kind: 7 documentation: kind: markdown - value: "```wing\nclass Topic\n```\n---\nA topic.\n\n### Initializer\n- `...props` — `TopicProps?`\n### Fields\n- `node` — `Node` — The tree node.\n### Methods\n- `isConstruct` — `preflight (x: any): bool` — Checks if `x` is a construct.\n- `onLift` — `preflight (host: IInflightHost, ops: Array): void` — A hook called by the Wing compiler once for each inflight host that needs to use this resource inflight.\n- `onLiftType` — `preflight (host: IInflightHost, ops: Array): void` — A hook called by the Wing compiler once for each inflight host that needs to use this type inflight.\n- `onMessage` — `preflight (inflight: inflight (event: str): void, props: TopicOnMessageOptions?): Function` — Run an inflight whenever an message is published to the topic.\n- `publish` — `inflight (message: str): void` — Publish message to topic.\n- `toString` — `preflight (): str` — Returns a string representation of this construct." + value: "```wing\nclass Topic\n```\n---\nA topic.\n\n### Initializer\n- `...props` — `TopicProps?`\n### Fields\n- `node` — `Node` — The tree node.\n### Methods\n- `isConstruct` — `preflight (x: any): bool` — Checks if `x` is a construct.\n- `onLift` — `preflight (host: IInflightHost, ops: Array): void` — A hook called by the Wing compiler once for each inflight host that needs to use this resource inflight.\n- `onLiftType` — `preflight (host: IInflightHost, ops: Array): void` — A hook called by the Wing compiler once for each inflight host that needs to use this type inflight.\n- `onMessage` — `preflight (inflight: inflight (event: str): void, props: TopicOnMessageOptions?): Function` — Run an inflight whenever an message is published to the topic.\n- `publish` — `inflight (message: str): void` — Publish message to topic.\n- `subscribeQueue` — `preflight (queue: Queue, props: TopicSubscribeQueueOptions?): void` — Subscribing queue to the topic.\n- `toString` — `preflight (): str` — Returns a string representation of this construct." sortText: gg|Topic - label: Website kind: 7 @@ -319,6 +319,12 @@ source: libs/wingc/src/lsp/completions.rs kind: markdown value: "```wing\nstruct TopicProps\n```\n---\nOptions for `Topic`." sortText: hh|TopicProps +- label: TopicSubscribeQueueOptions + kind: 22 + documentation: + kind: markdown + value: "```wing\nstruct TopicSubscribeQueueOptions extends QueueProps\n```\n---\nOptions for `Topic.subscribeQueue`.\n### Fields\n- `retentionPeriod?` — `duration?`\n- `timeout?` — `duration?`" + sortText: hh|TopicSubscribeQueueOptions - label: WebsiteDomainOptions kind: 22 documentation: diff --git a/libs/wingsdk/src/cloud/topic.md b/libs/wingsdk/src/cloud/topic.md index ce4d2addd7f..95a104215af 100644 --- a/libs/wingsdk/src/cloud/topic.md +++ b/libs/wingsdk/src/cloud/topic.md @@ -40,6 +40,20 @@ topic.onMessage(inflight (message: str) => { }); ``` +### Subscribing a Queue to a Topic + +```js +bring cloud; + +let queue = new cloud.Queue(); +queue.setConsumer(inflight (message str) => { + log("Topic published message: {message}"); +}); + +let topic = new cloud.Topic(); +topic.subscribeQueue(queue); +``` + ### Publishing to a topic The inflight method `publish` sends a message to all of the topic's subscribers. diff --git a/libs/wingsdk/src/cloud/topic.ts b/libs/wingsdk/src/cloud/topic.ts index 22f711e8620..47ac73f97d7 100644 --- a/libs/wingsdk/src/cloud/topic.ts +++ b/libs/wingsdk/src/cloud/topic.ts @@ -1,5 +1,6 @@ import { Construct } from "constructs"; import { Function, FunctionProps } from "./function"; +import { Queue, QueueProps } from "./queue"; import { fqnForType } from "../constants"; import { AbstractMemberError } from "../core/errors"; import { INFLIGHT_SYMBOL } from "../core/types"; @@ -47,12 +48,29 @@ export class Topic extends Resource { props; throw new AbstractMemberError(); } + + /** + * Subscribing queue to the topic + * @abstract + */ + public subscribeQueue( + queue: Queue, + props?: TopicSubscribeQueueOptions + ): void { + queue; + props; + throw new AbstractMemberError(); + } } /** * Options for `Topic.onMessage`. */ export interface TopicOnMessageOptions extends FunctionProps {} +/** + * Options for `Topic.subscribeQueue`. + */ +export interface TopicSubscribeQueueOptions extends QueueProps {} /** * Inflight interface for `Topic`. diff --git a/libs/wingsdk/src/target-sim/topic.ts b/libs/wingsdk/src/target-sim/topic.ts index 39d0ba00ae4..a6a888e6470 100644 --- a/libs/wingsdk/src/target-sim/topic.ts +++ b/libs/wingsdk/src/target-sim/topic.ts @@ -8,9 +8,12 @@ import { TopicSchema } from "./schema-resources"; import { bindSimulatorResource, makeSimulatorJsClient } from "./util"; import * as cloud from "../cloud"; import { convertBetweenHandlers } from "../shared/convert"; +import { Testing } from "../simulator"; import { BaseResourceSchema } from "../simulator/simulator"; import { IInflightHost, Node, SDK_SOURCE_MODULE } from "../std"; +const QUEUE_PUSH_METHOD = "push"; + /** * Simulator implementation of `cloud.Topic` * @@ -55,6 +58,43 @@ export class Topic extends cloud.Topic implements ISimulatorResource { return fn; } + public subscribeQueue(queue: cloud.Queue): void { + const functionHandler = convertBetweenHandlers( + Testing.makeHandler( + "async handle(event) { return await this.queue.push(event); }", + { + queue: { + obj: queue, + ops: [QUEUE_PUSH_METHOD], + }, + } + ), + join(__dirname, "topic.onmessage.inflight.js"), + "TopicOnMessageHandlerClient" + ); + + const fn = new Function( + this, + App.of(this).makeId(this, "subscribeQueue"), + functionHandler, + {} + ); + Node.of(fn).sourceModule = SDK_SOURCE_MODULE; + Node.of(fn).title = "subscribeQueue()"; + + new EventMapping(this, App.of(this).makeId(this, "TopicEventMapping"), { + subscriber: fn, + publisher: this, + subscriptionProps: {}, + }); + + Node.of(this).addConnection({ + source: this, + target: fn, + name: "subscribeQueue()", + }); + } + public onLift(host: IInflightHost, ops: string[]): void { bindSimulatorResource(__filename, this, host); super.onLift(host, ops); @@ -67,7 +107,10 @@ export class Topic extends cloud.Topic implements ISimulatorResource { /** @internal */ public _supportedOps(): string[] { - return [cloud.TopicInflightMethods.PUBLISH]; + return [ + cloud.QueueInflightMethods.PUSH, + cloud.TopicInflightMethods.PUBLISH, + ]; } public toSimulator(): BaseResourceSchema { diff --git a/libs/wingsdk/src/target-tf-aws/topic.ts b/libs/wingsdk/src/target-tf-aws/topic.ts index 67f3fa4c725..e585dbe6785 100644 --- a/libs/wingsdk/src/target-tf-aws/topic.ts +++ b/libs/wingsdk/src/target-tf-aws/topic.ts @@ -2,9 +2,11 @@ import { join } from "path"; import { Construct } from "constructs"; import { App } from "./app"; import { Function } from "./function"; +import { Queue } from "./queue"; import { SnsTopic } from "../.gen/providers/aws/sns-topic"; import { SnsTopicPolicy } from "../.gen/providers/aws/sns-topic-policy"; import { SnsTopicSubscription } from "../.gen/providers/aws/sns-topic-subscription"; +import { SqsQueuePolicy } from "../.gen/providers/aws/sqs-queue-policy"; import * as cloud from "../cloud"; import * as core from "../core"; import { convertBetweenHandlers } from "../shared/convert"; @@ -80,7 +82,7 @@ export class Topic extends cloud.Topic implements IAwsTopic { this, App.of(this).makeId(this, "TopicSubscription"), { - topicArn: this.topic.arn, + topicArn: this.topicArn, protocol: "lambda", endpoint: fn.functionArn, } @@ -97,6 +99,47 @@ export class Topic extends cloud.Topic implements IAwsTopic { return fn; } + public subscribeQueue(queue: cloud.Queue): void { + if (!(queue instanceof Queue)) { + throw new Error( + "'subscribeQueue' allows only tfaws.Queue to be subscribed to the Topic" + ); + } + + new SnsTopicSubscription( + this, + App.of(this).makeId(this, "TopicSubscription"), + { + topicArn: this.topicArn, + protocol: "sqs", + endpoint: queue.queueArn, + rawMessageDelivery: true, + } + ); + + new SqsQueuePolicy(this, `SqsQueuePolicy-${queue.node.addr}`, { + queueUrl: queue.queueUrl, + policy: JSON.stringify({ + Version: "2012-10-17", + Statement: [ + { + Effect: "Allow", + Principal: { + Service: "sns.amazonaws.com", + }, + Action: "sqs:SendMessage", + Resource: `${queue.queueArn}`, + Condition: { + ArnEquals: { + "aws:SourceArn": `${this.topicArn}`, + }, + }, + }, + ], + }), + }); + } + /** * Grants the given identity permissions to publish this topic. * @param source the resource that will publish to the topic diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/topic/subscribe-queue.test.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/topic/subscribe-queue.test.w_compile_tf-aws.md new file mode 100644 index 00000000000..8a0674fd361 --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/topic/subscribe-queue.test.w_compile_tf-aws.md @@ -0,0 +1,443 @@ +# [subscribe-queue.test.w](../../../../../../examples/tests/sdk_tests/topic/subscribe-queue.test.w) | compile | tf-aws + +## main.tf.json +```json +{ + "//": { + "metadata": { + "backend": "local", + "stackName": "root", + "version": "0.20.3" + }, + "outputs": {} + }, + "provider": { + "aws": [ + {} + ] + }, + "resource": { + "aws_cloudwatch_log_group": { + "Topic-OnMessage0_CloudwatchLogGroup_DE4DF0A1": { + "//": { + "metadata": { + "path": "root/Default/Default/Topic-OnMessage0/CloudwatchLogGroup", + "uniqueId": "Topic-OnMessage0_CloudwatchLogGroup_DE4DF0A1" + } + }, + "name": "/aws/lambda/Topic-OnMessage0-c85d7820", + "retention_in_days": 30 + }, + "q1-SetConsumer0_CloudwatchLogGroup_B5256514": { + "//": { + "metadata": { + "path": "root/Default/Default/q1-SetConsumer0/CloudwatchLogGroup", + "uniqueId": "q1-SetConsumer0_CloudwatchLogGroup_B5256514" + } + }, + "name": "/aws/lambda/q1-SetConsumer0-c8600a39", + "retention_in_days": 30 + }, + "q2-SetConsumer0_CloudwatchLogGroup_A9ABA3A4": { + "//": { + "metadata": { + "path": "root/Default/Default/q2-SetConsumer0/CloudwatchLogGroup", + "uniqueId": "q2-SetConsumer0_CloudwatchLogGroup_A9ABA3A4" + } + }, + "name": "/aws/lambda/q2-SetConsumer0-c8ba098b", + "retention_in_days": 30 + } + }, + "aws_dynamodb_table": { + "Counter": { + "//": { + "metadata": { + "path": "root/Default/Default/Counter/Default", + "uniqueId": "Counter" + } + }, + "attribute": [ + { + "name": "id", + "type": "S" + } + ], + "billing_mode": "PAY_PER_REQUEST", + "hash_key": "id", + "name": "wing-counter-Counter-c824ef62" + } + }, + "aws_iam_role": { + "Topic-OnMessage0_IamRole_64DD36FA": { + "//": { + "metadata": { + "path": "root/Default/Default/Topic-OnMessage0/IamRole", + "uniqueId": "Topic-OnMessage0_IamRole_64DD36FA" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + }, + "q1-SetConsumer0_IamRole_8299B0EC": { + "//": { + "metadata": { + "path": "root/Default/Default/q1-SetConsumer0/IamRole", + "uniqueId": "q1-SetConsumer0_IamRole_8299B0EC" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + }, + "q2-SetConsumer0_IamRole_910A96B5": { + "//": { + "metadata": { + "path": "root/Default/Default/q2-SetConsumer0/IamRole", + "uniqueId": "q2-SetConsumer0_IamRole_910A96B5" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + } + }, + "aws_iam_role_policy": { + "Topic-OnMessage0_IamRolePolicy_F5EE09D8": { + "//": { + "metadata": { + "path": "root/Default/Default/Topic-OnMessage0/IamRolePolicy", + "uniqueId": "Topic-OnMessage0_IamRolePolicy_F5EE09D8" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":[\"dynamodb:UpdateItem\"],\"Resource\":[\"${aws_dynamodb_table.Counter.arn}\"],\"Effect\":\"Allow\"}]}", + "role": "${aws_iam_role.Topic-OnMessage0_IamRole_64DD36FA.name}" + }, + "q1-SetConsumer0_IamRolePolicy_7B7EFF72": { + "//": { + "metadata": { + "path": "root/Default/Default/q1-SetConsumer0/IamRolePolicy", + "uniqueId": "q1-SetConsumer0_IamRolePolicy_7B7EFF72" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":[\"sqs:ReceiveMessage\",\"sqs:ChangeMessageVisibility\",\"sqs:GetQueueUrl\",\"sqs:DeleteMessage\",\"sqs:GetQueueAttributes\"],\"Resource\":[\"${aws_sqs_queue.q1.arn}\"],\"Effect\":\"Allow\"},{\"Action\":[\"dynamodb:UpdateItem\"],\"Resource\":[\"${aws_dynamodb_table.Counter.arn}\"],\"Effect\":\"Allow\"}]}", + "role": "${aws_iam_role.q1-SetConsumer0_IamRole_8299B0EC.name}" + }, + "q2-SetConsumer0_IamRolePolicy_4F213331": { + "//": { + "metadata": { + "path": "root/Default/Default/q2-SetConsumer0/IamRolePolicy", + "uniqueId": "q2-SetConsumer0_IamRolePolicy_4F213331" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":[\"sqs:ReceiveMessage\",\"sqs:ChangeMessageVisibility\",\"sqs:GetQueueUrl\",\"sqs:DeleteMessage\",\"sqs:GetQueueAttributes\"],\"Resource\":[\"${aws_sqs_queue.q2.arn}\"],\"Effect\":\"Allow\"},{\"Action\":[\"dynamodb:UpdateItem\"],\"Resource\":[\"${aws_dynamodb_table.Counter.arn}\"],\"Effect\":\"Allow\"}]}", + "role": "${aws_iam_role.q2-SetConsumer0_IamRole_910A96B5.name}" + } + }, + "aws_iam_role_policy_attachment": { + "Topic-OnMessage0_IamRolePolicyAttachment_091E665D": { + "//": { + "metadata": { + "path": "root/Default/Default/Topic-OnMessage0/IamRolePolicyAttachment", + "uniqueId": "Topic-OnMessage0_IamRolePolicyAttachment_091E665D" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.Topic-OnMessage0_IamRole_64DD36FA.name}" + }, + "q1-SetConsumer0_IamRolePolicyAttachment_87EE6CD7": { + "//": { + "metadata": { + "path": "root/Default/Default/q1-SetConsumer0/IamRolePolicyAttachment", + "uniqueId": "q1-SetConsumer0_IamRolePolicyAttachment_87EE6CD7" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.q1-SetConsumer0_IamRole_8299B0EC.name}" + }, + "q2-SetConsumer0_IamRolePolicyAttachment_6DB0A9EE": { + "//": { + "metadata": { + "path": "root/Default/Default/q2-SetConsumer0/IamRolePolicyAttachment", + "uniqueId": "q2-SetConsumer0_IamRolePolicyAttachment_6DB0A9EE" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.q2-SetConsumer0_IamRole_910A96B5.name}" + } + }, + "aws_lambda_event_source_mapping": { + "q1_EventSourceMapping_26C17B14": { + "//": { + "metadata": { + "path": "root/Default/Default/q1/EventSourceMapping", + "uniqueId": "q1_EventSourceMapping_26C17B14" + } + }, + "batch_size": 1, + "event_source_arn": "${aws_sqs_queue.q1.arn}", + "function_name": "${aws_lambda_function.q1-SetConsumer0.function_name}" + }, + "q2_EventSourceMapping_F484014F": { + "//": { + "metadata": { + "path": "root/Default/Default/q2/EventSourceMapping", + "uniqueId": "q2_EventSourceMapping_F484014F" + } + }, + "batch_size": 1, + "event_source_arn": "${aws_sqs_queue.q2.arn}", + "function_name": "${aws_lambda_function.q2-SetConsumer0.function_name}" + } + }, + "aws_lambda_function": { + "Topic-OnMessage0": { + "//": { + "metadata": { + "path": "root/Default/Default/Topic-OnMessage0/Default", + "uniqueId": "Topic-OnMessage0" + } + }, + "architectures": [ + "arm64" + ], + "environment": { + "variables": { + "DYNAMODB_TABLE_NAME_6cb5a3a4": "${aws_dynamodb_table.Counter.name}", + "NODE_OPTIONS": "--enable-source-maps", + "WING_FUNCTION_NAME": "Topic-OnMessage0-c85d7820", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "Topic-OnMessage0-c85d7820", + "handler": "index.handler", + "memory_size": 1024, + "publish": true, + "role": "${aws_iam_role.Topic-OnMessage0_IamRole_64DD36FA.arn}", + "runtime": "nodejs20.x", + "s3_bucket": "${aws_s3_bucket.Code.bucket}", + "s3_key": "${aws_s3_object.Topic-OnMessage0_S3Object_D41E9C10.key}", + "timeout": 60, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + }, + "q1-SetConsumer0": { + "//": { + "metadata": { + "path": "root/Default/Default/q1-SetConsumer0/Default", + "uniqueId": "q1-SetConsumer0" + } + }, + "architectures": [ + "arm64" + ], + "environment": { + "variables": { + "DYNAMODB_TABLE_NAME_6cb5a3a4": "${aws_dynamodb_table.Counter.name}", + "NODE_OPTIONS": "--enable-source-maps", + "WING_FUNCTION_NAME": "q1-SetConsumer0-c8600a39", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "q1-SetConsumer0-c8600a39", + "handler": "index.handler", + "memory_size": 1024, + "publish": true, + "role": "${aws_iam_role.q1-SetConsumer0_IamRole_8299B0EC.arn}", + "runtime": "nodejs20.x", + "s3_bucket": "${aws_s3_bucket.Code.bucket}", + "s3_key": "${aws_s3_object.q1-SetConsumer0_S3Object_60123604.key}", + "timeout": "${aws_sqs_queue.q1.visibility_timeout_seconds}", + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + }, + "q2-SetConsumer0": { + "//": { + "metadata": { + "path": "root/Default/Default/q2-SetConsumer0/Default", + "uniqueId": "q2-SetConsumer0" + } + }, + "architectures": [ + "arm64" + ], + "environment": { + "variables": { + "DYNAMODB_TABLE_NAME_6cb5a3a4": "${aws_dynamodb_table.Counter.name}", + "NODE_OPTIONS": "--enable-source-maps", + "WING_FUNCTION_NAME": "q2-SetConsumer0-c8ba098b", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "q2-SetConsumer0-c8ba098b", + "handler": "index.handler", + "memory_size": 1024, + "publish": true, + "role": "${aws_iam_role.q2-SetConsumer0_IamRole_910A96B5.arn}", + "runtime": "nodejs20.x", + "s3_bucket": "${aws_s3_bucket.Code.bucket}", + "s3_key": "${aws_s3_object.q2-SetConsumer0_S3Object_FB40B099.key}", + "timeout": "${aws_sqs_queue.q2.visibility_timeout_seconds}", + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + } + }, + "aws_lambda_permission": { + "Topic-OnMessage0_InvokePermission-c8228fb70d825c2a5610c610e5246d5313ea6bd1a2_2E2D0106": { + "//": { + "metadata": { + "path": "root/Default/Default/Topic-OnMessage0/InvokePermission-c8228fb70d825c2a5610c610e5246d5313ea6bd1a2", + "uniqueId": "Topic-OnMessage0_InvokePermission-c8228fb70d825c2a5610c610e5246d5313ea6bd1a2_2E2D0106" + } + }, + "action": "lambda:InvokeFunction", + "function_name": "${aws_lambda_function.Topic-OnMessage0.function_name}", + "principal": "sns.amazonaws.com", + "source_arn": "${aws_sns_topic.Topic.arn}" + } + }, + "aws_s3_bucket": { + "Code": { + "//": { + "metadata": { + "path": "root/Default/Code", + "uniqueId": "Code" + } + }, + "bucket_prefix": "code-c84a50b1-" + } + }, + "aws_s3_object": { + "Topic-OnMessage0_S3Object_D41E9C10": { + "//": { + "metadata": { + "path": "root/Default/Default/Topic-OnMessage0/S3Object", + "uniqueId": "Topic-OnMessage0_S3Object_D41E9C10" + } + }, + "bucket": "${aws_s3_bucket.Code.bucket}", + "key": "", + "source": "" + }, + "q1-SetConsumer0_S3Object_60123604": { + "//": { + "metadata": { + "path": "root/Default/Default/q1-SetConsumer0/S3Object", + "uniqueId": "q1-SetConsumer0_S3Object_60123604" + } + }, + "bucket": "${aws_s3_bucket.Code.bucket}", + "key": "", + "source": "" + }, + "q2-SetConsumer0_S3Object_FB40B099": { + "//": { + "metadata": { + "path": "root/Default/Default/q2-SetConsumer0/S3Object", + "uniqueId": "q2-SetConsumer0_S3Object_FB40B099" + } + }, + "bucket": "${aws_s3_bucket.Code.bucket}", + "key": "", + "source": "" + } + }, + "aws_sns_topic": { + "Topic": { + "//": { + "metadata": { + "path": "root/Default/Default/Topic/Default", + "uniqueId": "Topic" + } + }, + "name": "Topic-c8228fb7" + } + }, + "aws_sns_topic_subscription": { + "Topic_TopicSubscription0_0EA5CC90": { + "//": { + "metadata": { + "path": "root/Default/Default/Topic/TopicSubscription0", + "uniqueId": "Topic_TopicSubscription0_0EA5CC90" + } + }, + "endpoint": "${aws_lambda_function.Topic-OnMessage0.arn}", + "protocol": "lambda", + "topic_arn": "${aws_sns_topic.Topic.arn}" + }, + "Topic_TopicSubscription1_7AA173DC": { + "//": { + "metadata": { + "path": "root/Default/Default/Topic/TopicSubscription1", + "uniqueId": "Topic_TopicSubscription1_7AA173DC" + } + }, + "endpoint": "${aws_sqs_queue.q1.arn}", + "protocol": "sqs", + "raw_message_delivery": true, + "topic_arn": "${aws_sns_topic.Topic.arn}" + }, + "Topic_TopicSubscription2_588150DD": { + "//": { + "metadata": { + "path": "root/Default/Default/Topic/TopicSubscription2", + "uniqueId": "Topic_TopicSubscription2_588150DD" + } + }, + "endpoint": "${aws_sqs_queue.q2.arn}", + "protocol": "sqs", + "raw_message_delivery": true, + "topic_arn": "${aws_sns_topic.Topic.arn}" + } + }, + "aws_sqs_queue": { + "q1": { + "//": { + "metadata": { + "path": "root/Default/Default/q1/Default", + "uniqueId": "q1" + } + }, + "message_retention_seconds": 3600, + "name": "q1-c8d04b5e", + "visibility_timeout_seconds": 30 + }, + "q2": { + "//": { + "metadata": { + "path": "root/Default/Default/q2/Default", + "uniqueId": "q2" + } + }, + "message_retention_seconds": 3600, + "name": "q2-c8aa6380", + "visibility_timeout_seconds": 30 + } + }, + "aws_sqs_queue_policy": { + "Topic_SqsQueuePolicy-c8aa63803bb48703f04c4e86e7ec46acc23af1eae7_2C2F1390": { + "//": { + "metadata": { + "path": "root/Default/Default/Topic/SqsQueuePolicy-c8aa63803bb48703f04c4e86e7ec46acc23af1eae7", + "uniqueId": "Topic_SqsQueuePolicy-c8aa63803bb48703f04c4e86e7ec46acc23af1eae7_2C2F1390" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"sns.amazonaws.com\"},\"Action\":\"sqs:SendMessage\",\"Resource\":\"${aws_sqs_queue.q2.arn}\",\"Condition\":{\"ArnEquals\":{\"aws:SourceArn\":\"${aws_sns_topic.Topic.arn}\"}}}]}", + "queue_url": "${aws_sqs_queue.q2.url}" + }, + "Topic_SqsQueuePolicy-c8d04b5ef86e7d86fc1200f50de3110292a6dd012d_38A7F5C3": { + "//": { + "metadata": { + "path": "root/Default/Default/Topic/SqsQueuePolicy-c8d04b5ef86e7d86fc1200f50de3110292a6dd012d", + "uniqueId": "Topic_SqsQueuePolicy-c8d04b5ef86e7d86fc1200f50de3110292a6dd012d_38A7F5C3" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"sns.amazonaws.com\"},\"Action\":\"sqs:SendMessage\",\"Resource\":\"${aws_sqs_queue.q1.arn}\",\"Condition\":{\"ArnEquals\":{\"aws:SourceArn\":\"${aws_sns_topic.Topic.arn}\"}}}]}", + "queue_url": "${aws_sqs_queue.q1.url}" + } + } + } +} +``` + diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/topic/subscribe-queue.test.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/topic/subscribe-queue.test.w_test_sim.md new file mode 100644 index 00000000000..0f0711d3e9e --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/topic/subscribe-queue.test.w_test_sim.md @@ -0,0 +1,12 @@ +# [subscribe-queue.test.w](../../../../../../examples/tests/sdk_tests/topic/subscribe-queue.test.w) | test | sim + +## stdout.log +```log +pass ─ subscribe-queue.test.wsim » root/env0/test:functions and queues receiving messages from the topic + + +Tests 1 passed (1) +Test Files 1 passed (1) +Duration +``` + From 33211e61248d933f5c81d2d111931ce34eb319be Mon Sep 17 00:00:00 2001 From: wingbot <109207340+monadabot@users.noreply.github.com> Date: Thu, 4 Apr 2024 22:32:08 -0400 Subject: [PATCH 10/16] chore(docs): compatibility matrix update (#6155) chore(docs): update compatibility matrix [Workflow Run]: https://github.com/winglang/wing/actions/runs/8563841178 ------ *Automatically created via the "matrix-update" workflow* --- .../04-standard-library/compatibility/compatibility.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/docs/04-standard-library/compatibility/compatibility.json b/docs/docs/04-standard-library/compatibility/compatibility.json index 233112e47e0..29c145df644 100644 --- a/docs/docs/04-standard-library/compatibility/compatibility.json +++ b/docs/docs/04-standard-library/compatibility/compatibility.json @@ -869,6 +869,14 @@ "tf-aws": { "implemented": true } + }, + "subscribeQueue": { + "sim": { + "implemented": true + }, + "tf-aws": { + "implemented": true + } } }, "Schedule": { From 1bfc04707486cf19476ce046960810b553659a1a Mon Sep 17 00:00:00 2001 From: Emmanuel Ferdman Date: Fri, 5 Apr 2024 16:48:51 +0300 Subject: [PATCH 11/16] fix(docs): update the location of different resources (#6156) ## Checklist - [x] Title matches [Winglang's style guide](https://www.winglang.io/contributing/start-here/pull_requests#how-are-pull-request-titles-formatted) - [x] Description explains motivation and solution - [ ] Tests added (always) - [ ] Docs updated (only required for features) - [ ] Added `pr/e2e-full` label if this feature requires end-to-end testing *By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*. **PR Summary**: I noticed that a section in `docs/contributing/01-start-here/07-wingsdk.md` remained unchanged following updates in PRs such as #690, #4149, #4256, and #1576. This PR updates the documentation and resources locations to reflect those changes. --- docs/contributing/01-start-here/07-wingsdk.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/contributing/01-start-here/07-wingsdk.md b/docs/contributing/01-start-here/07-wingsdk.md index 71ac681193f..06bce93f06b 100644 --- a/docs/contributing/01-start-here/07-wingsdk.md +++ b/docs/contributing/01-start-here/07-wingsdk.md @@ -67,16 +67,16 @@ A resource in the SDK has several parts: * A set of base APIs that must be implemented by all cloud targets. Typically the resource's preflight APIs correspond to a base class in TypeScript, and the resource's inflight APIs correspond to an interface in TypeScript. These are defined in `src/cloud` or `src/ex`. For example, [`src/cloud/bucket.ts`](https://github.com/winglang/wing/tree/main/libs/wingsdk/src/cloud/bucket.ts). * An interface representing the inflight API common across all cloud targets. By convention, if the resource is named like `Gizmo`, the inflight interface should be named `IGizmoClient`. This is usually in the same file as the preflight API. -* A simulator implementation in `src/sim`. This includes: - * A schema with information to simulate the resource and display the resource in the Wing console. Currently these are in [`src/sim/schema-resources.ts`](https://github.com/winglang/wing/tree/main/libs/wingsdk/src/sim/schema-resources.ts). - * A class that implements the polycon API and can produce the resource's simulation schema. For example, [`src/sim/bucket.ts`](https://github.com/winglang/wing/tree/main/libs/wingsdk/src/sim/bucket.ts). - * An class that implements the inflight API and can simulate the resource. For example, [`src/sim/bucket.sim.ts`](https://github.com/winglang/wing/tree/main/libs/wingsdk/src/sim/bucket.sim.ts). - * Unit tests for the simulator implementation. For example, [`test/sim/bucket.test.ts`](https://github.com/winglang/wing/tree/main/libs/wingsdk/test/sim/bucket.test.ts). +* A simulator implementation in `src/target-sim`. This includes: + * A schema with information to simulate the resource and display the resource in the Wing console. Currently these are in [`src/target-sim/schema-resources.ts`](https://github.com/winglang/wing/tree/main/libs/wingsdk/src/target-sim/schema-resources.ts). + * A class that implements the polycon API and can produce the resource's simulation schema. For example, [`src/target-sim/bucket.ts`](https://github.com/winglang/wing/tree/main/libs/wingsdk/src/target-sim/bucket.ts). + * An class that implements the inflight API and can simulate the resource. For example, [`src/target-sim/bucket.inflight.ts`](https://github.com/winglang/wing/tree/main/libs/wingsdk/src/target-sim/bucket.inflight.ts). + * Unit tests for the simulator implementation. For example, [`test/target-sim/bucket.test.ts`](https://github.com/winglang/wing/tree/main/libs/wingsdk/test/target-sim/bucket.test.ts). * An implementation for each target cloud (currently just AWS). This includes: - * A class that implements the polycon API and creates all of the required terraform resources. For example, [`src/tf-aws/bucket.ts`](https://github.com/winglang/wing/tree/main/libs/wingsdk/src/tf-aws/bucket.ts). - * A class that implements the inflight API that interacts with the cloud resource. For example, [`src/tf-aws/bucket.inflight.ts`](https://github.com/winglang/wing/tree/main/libs/wingsdk/src/tf-aws/bucket.inflight.ts). - * Unit tests for the cloud infrastructure. For example, [`test/tf-aws/bucket.test.ts`](https://github.com/winglang/wing/tree/main/libs/wingsdk/test/tf-aws/bucket.test.ts). - * End-to-end tests. These are added to the "examples" directory at the root of the repository. For example, [`examples/tests/sdk_tests/bucket/bucket_list.w`](https://github.com/winglang/wing/blob/main/examples/tests/sdk_tests/bucket/bucket_list.w). + * A class that implements the polycon API and creates all of the required terraform resources. For example, [`src/shared-aws/bucket.ts`](https://github.com/winglang/wing/tree/main/libs/wingsdk/src/shared-aws/bucket.ts). + * A class that implements the inflight API that interacts with the cloud resource. For example, [`src/shared-aws/bucket.inflight.ts`](https://github.com/winglang/wing/tree/main/libs/wingsdk/src/shared-aws/bucket.inflight.ts). + * Unit tests for the cloud infrastructure. For example, [`test/target-tf-aws/bucket.test.ts`](https://github.com/winglang/wing/tree/main/libs/wingsdk/test/target-tf-aws/bucket.test.ts). + * End-to-end tests. These are added to the "examples" directory at the root of the repository. For example, [`examples/tests/sdk_tests/bucket/bucket_list.test.w`](https://github.com/winglang/wing/blob/main/examples/tests/sdk_tests/bucket/bucket_list.test.w). If you are implementing a new resource, or implementing an existing resource for a new cloud provider, try to take a look at code for existing resources (`Bucket`, `Function`, `Queue`) to see how to structure your code. From 20c06f4d466c22294cde8e69656bb47bfe8c1814 Mon Sep 17 00:00:00 2001 From: yoav-steinberg Date: Sun, 7 Apr 2024 11:39:33 +0300 Subject: [PATCH 12/16] fix(compiler): base class fields not being lifted (#6160) Fixes #5258 Some details: 1. Correctly collect fields from entire ancestry when passing lifted fields to class inflight client ctor. 2. Make sure fields of entire ancestry is taken into account when passing them to `super()` in the client ctor. 3. In case a derived field is being used directly in the derived class, we need to de-dup lifted field token names when passing them to the client's ctor (Use `IndexMax` instead of vec). ## Checklist - [x] Title matches [Winglang's style guide](https://www.winglang.io/contributing/start-here/pull_requests#how-are-pull-request-titles-formatted) - [x] Description explains motivation and solution - [x] Tests added (always) - [ ] Docs updated (only required for features) - [ ] Added `pr/e2e-full` label if this feature requires end-to-end testing *By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*. --- .../tests/valid/lift_parent_fields.test.w | 49 ++++ libs/wingc/src/jsify.rs | 75 ++--- .../snapshots/base_class_lift_indirect.snap | 1 + libs/wingc/src/type_check/lifts.rs | 9 +- ...ift_parent_fields.test.w_compile_tf-aws.md | 269 ++++++++++++++++++ .../lift_parent_fields.test.w_test_sim.md | 12 + 6 files changed, 372 insertions(+), 43 deletions(-) create mode 100644 examples/tests/valid/lift_parent_fields.test.w create mode 100644 tools/hangar/__snapshots__/test_corpus/valid/lift_parent_fields.test.w_compile_tf-aws.md create mode 100644 tools/hangar/__snapshots__/test_corpus/valid/lift_parent_fields.test.w_test_sim.md diff --git a/examples/tests/valid/lift_parent_fields.test.w b/examples/tests/valid/lift_parent_fields.test.w new file mode 100644 index 00000000000..d0c19938f2b --- /dev/null +++ b/examples/tests/valid/lift_parent_fields.test.w @@ -0,0 +1,49 @@ +class A { + pub a: str; + + new() { + this.a = "a"; + } + + pub inflight do(): str { + return this.a; + } +} + +class B extends A { + pub b: str; + + new() { + super(); + this.b = "b"; + } + + pub inflight do(): str { + return "{this.b} {super.do()}"; + } +} + +class C extends B { + pub c: str; + + new() { + super(); + this.c = "c"; + } + + inflight dummy() { + // Directly access the field of the parent class, this means it's lifted both for + // initializing the parent class and for direct access here. This verifies we don't + // lift twice and cause a name conflict. + log("{this.b}"); + } + + pub inflight do(): str { + return "{this.c} {super.do()}"; + } +} + +let c = new C(); +test "test" { + assert(c.do() == "c b a"); +} \ No newline at end of file diff --git a/libs/wingc/src/jsify.rs b/libs/wingc/src/jsify.rs index f4e70ada311..0d1c84630ed 100644 --- a/libs/wingc/src/jsify.rs +++ b/libs/wingc/src/jsify.rs @@ -1529,12 +1529,7 @@ impl<'a> JSifier<'a> { if let Some(parent) = &class.parent { // If this is an imported type (with a package fqn) attemp to go through the stdlib target dep-injection mechanism - let parent_type = env - .lookup_nested_str(&parent.full_path_str(), None) - .unwrap() - .0 - .as_type() - .unwrap(); + let parent_type = class_type.as_class().unwrap().parent.unwrap(); if let Some(fqn) = &parent_type.as_class().unwrap().fqn { code.append(new_code!( &class.name.span, @@ -1583,7 +1578,7 @@ impl<'a> JSifier<'a> { // emit the `_toInflight` and `_toInflightType` methods (TODO: renamed to `_liftObject` and // `_liftType`). code.add_code(self.jsify_to_inflight_type_method(&class, ctx)); - code.add_code(self.jsify_to_inflight_method(&class.name, ctx)); + code.add_code(self.jsify_to_inflight_method(&class.name, class_type)); // emit `onLift` and `onLiftType` to bind permissions and environment variables to inflight hosts code.add_code(self.jsify_register_bind_method(class, class_type, BindMethod::Instance, ctx)); @@ -1666,8 +1661,24 @@ impl<'a> JSifier<'a> { code } - fn jsify_to_inflight_method(&self, resource_name: &Symbol, ctx: &JSifyContext) -> CodeMaker { - let mut code = CodeMaker::with_source(&resource_name.span); + // Recursively get all lifted fields from a class and its ancestry + fn class_lifted_fields(class_type: TypeRef) -> IndexMap { + let mut res = IndexMap::new(); + let class_type = class_type.as_class().unwrap(); + + if let Some(lifts) = &class_type.lifts { + res.extend(lifts.lifted_fields()); + } + + if let Some(parent) = class_type.parent { + res.extend(Self::class_lifted_fields(parent)); + } + + res + } + + fn jsify_to_inflight_method(&self, class_name: &Symbol, class_type: TypeRef) -> CodeMaker { + let mut code = CodeMaker::with_source(&class_name.span); code.open("_toInflight() {"); @@ -1677,15 +1688,16 @@ impl<'a> JSifier<'a> { code.line(format!( "const {}Client = ${{{}._toInflightType()}};", - resource_name.name, resource_name.name, + class_name.name, class_name.name, )); - code.open(format!("const client = new {}Client({{", resource_name.name)); + code.open(format!("const client = new {}Client({{", class_name.name)); - if let Some(lifts) = &ctx.lifts { - for (token, obj) in lifts.lifted_fields() { - code.line(format!("{token}: ${{{STDLIB_CORE}.liftObject({obj})}},")); - } + // Get lifted fields from entire class ancestry + let lifts = Self::class_lifted_fields(class_type); + + for (token, obj) in lifts { + code.line(format!("{token}: ${{{STDLIB_CORE}.liftObject({obj})}},")); } code.close("});"); @@ -1719,7 +1731,7 @@ impl<'a> JSifier<'a> { // if this is a preflight class, emit the binding constructor if class.phase == Phase::Preflight { - self.jsify_inflight_binding_constructor(class, &mut class_code, &ctx); + self.jsify_inflight_binding_constructor(class, class_type, &mut class_code); } for def in class.inflight_methods(false) { @@ -1793,43 +1805,34 @@ impl<'a> JSifier<'a> { } } - fn jsify_inflight_binding_constructor(&self, class: &AstClass, class_code: &mut CodeMaker, ctx: &JSifyContext) { + fn jsify_inflight_binding_constructor(&self, class: &AstClass, class_type: TypeRef, class_code: &mut CodeMaker) { + let class_type = class_type.as_class().unwrap(); + // Get the fields that are lifted by this class but not by its parent, they will be initialized // in the generated constructor - let lifted_fields = if let Some(lifts) = &ctx.lifts { - lifts.lifted_fields().keys().map(|f| f.clone()).collect_vec() + let lifted_fields = if let Some(lifts) = &class_type.lifts { + lifts.lifted_fields().map(|(f, _)| f.clone()).collect() } else { - vec![] + IndexSet::new() }; - let parent_fields = if let Some(parent) = &class.parent { - let parent_type = resolve_user_defined_type( - parent, - ctx.visit_ctx.current_env().expect("an env"), - ctx.visit_ctx.current_stmt_idx(), - ) - .expect("resolved type"); - if let Some(parent_lifts) = &parent_type.as_class().unwrap().lifts { - parent_lifts.lifted_fields().keys().map(|f| f.clone()).collect_vec() - } else { - vec![] - } + let parent_fields = if let Some(parent) = class_type.parent { + Self::class_lifted_fields(parent).keys().cloned().collect() } else { - vec![] + IndexSet::new() }; class_code.open(format!( "{JS_CONSTRUCTOR}({{ {} }}) {{", lifted_fields - .iter() - .merge(parent_fields.iter()) + .union(&parent_fields) .map(|token| { token.clone() }) .collect_vec() .join(", ") )); if class.parent.is_some() { - class_code.line(format!("super({{ {} }});", parent_fields.join(", "))); + class_code.line(format!("super({{ {} }});", parent_fields.iter().join(", "))); } for token in &lifted_fields { diff --git a/libs/wingc/src/jsify/snapshots/base_class_lift_indirect.snap b/libs/wingc/src/jsify/snapshots/base_class_lift_indirect.snap index 649c199d1e0..9b49bee71cb 100644 --- a/libs/wingc/src/jsify/snapshots/base_class_lift_indirect.snap +++ b/libs/wingc/src/jsify/snapshots/base_class_lift_indirect.snap @@ -130,6 +130,7 @@ class $Root extends $stdlib.std.Resource { (await (async () => { const DerivedClient = ${Derived._toInflightType()}; const client = new DerivedClient({ + $this_b: ${$stdlib.core.liftObject(this.b)}, }); if (client.$inflight_init) { await client.$inflight_init(); } return client; diff --git a/libs/wingc/src/type_check/lifts.rs b/libs/wingc/src/type_check/lifts.rs index 6ed6980ebbd..0fb34892c25 100644 --- a/libs/wingc/src/type_check/lifts.rs +++ b/libs/wingc/src/type_check/lifts.rs @@ -146,17 +146,12 @@ impl Lifts { } /// List of all lifted fields in the class. (map from lift token to preflight code) - pub fn lifted_fields(&self) -> BTreeMap { - let mut result: BTreeMap = BTreeMap::new(); - + pub fn lifted_fields(&self) -> impl Iterator + '_ { self .captures .iter() .filter(|(_, lift)| lift.is_field) - .for_each(|(token, lift)| { - result.insert(token.clone(), lift.code.clone()); - }); - result + .map(|(t, c)| (t.clone(), c.code.clone())) } } diff --git a/tools/hangar/__snapshots__/test_corpus/valid/lift_parent_fields.test.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/lift_parent_fields.test.w_compile_tf-aws.md new file mode 100644 index 00000000000..562aefdccc7 --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/valid/lift_parent_fields.test.w_compile_tf-aws.md @@ -0,0 +1,269 @@ +# [lift_parent_fields.test.w](../../../../../examples/tests/valid/lift_parent_fields.test.w) | compile | tf-aws + +## inflight.$Closure1-1.js +```js +"use strict"; +const $helpers = require("@winglang/sdk/lib/helpers"); +module.exports = function({ $c }) { + class $Closure1 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async handle() { + $helpers.assert($helpers.eq((await $c.do()), "c b a"), "c.do() == \"c b a\""); + } + } + return $Closure1; +} +//# sourceMappingURL=inflight.$Closure1-1.js.map +``` + +## inflight.A-1.js +```js +"use strict"; +const $helpers = require("@winglang/sdk/lib/helpers"); +module.exports = function({ }) { + class A { + constructor({ $this_a }) { + this.$this_a = $this_a; + } + async do() { + return this.$this_a; + } + } + return A; +} +//# sourceMappingURL=inflight.A-1.js.map +``` + +## inflight.B-1.js +```js +"use strict"; +const $helpers = require("@winglang/sdk/lib/helpers"); +module.exports = function({ $A }) { + class B extends $A { + constructor({ $this_b, $this_a }) { + super({ $this_a }); + this.$this_b = $this_b; + } + async do() { + return String.raw({ raw: ["", " ", ""] }, this.$this_b, (await super.do())); + } + } + return B; +} +//# sourceMappingURL=inflight.B-1.js.map +``` + +## inflight.C-1.js +```js +"use strict"; +const $helpers = require("@winglang/sdk/lib/helpers"); +module.exports = function({ $B }) { + class C extends $B { + constructor({ $this_b, $this_c, $this_a }) { + super({ $this_b, $this_a }); + this.$this_b = $this_b; + this.$this_c = $this_c; + } + async dummy() { + console.log(String.raw({ raw: ["", ""] }, this.$this_b)); + } + async do() { + return String.raw({ raw: ["", " ", ""] }, this.$this_c, (await super.do())); + } + } + return C; +} +//# sourceMappingURL=inflight.C-1.js.map +``` + +## main.tf.json +```json +{ + "//": { + "metadata": { + "backend": "local", + "stackName": "root", + "version": "0.20.3" + }, + "outputs": {} + }, + "provider": { + "aws": [ + {} + ] + } +} +``` + +## preflight.js +```js +"use strict"; +const $stdlib = require('@winglang/sdk'); +const $platforms = ((s) => !s ? [] : s.split(';'))(process.env.WING_PLATFORMS); +const $outdir = process.env.WING_SYNTH_DIR ?? "."; +const $wing_is_test = process.env.WING_IS_TEST === "true"; +const std = $stdlib.std; +const $helpers = $stdlib.helpers; +class $Root extends $stdlib.std.Resource { + constructor($scope, $id) { + super($scope, $id); + class A extends $stdlib.std.Resource { + constructor($scope, $id, ) { + super($scope, $id); + this.a = "a"; + } + static _toInflightType() { + return ` + require("${$helpers.normalPath(__dirname)}/inflight.A-1.js")({ + }) + `; + } + _toInflight() { + return ` + (await (async () => { + const AClient = ${A._toInflightType()}; + const client = new AClient({ + $this_a: ${$stdlib.core.liftObject(this.a)}, + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `; + } + get _liftMap() { + return ({ + "do": [ + [this.a, []], + ], + "$inflight_init": [ + [this.a, []], + ], + }); + } + } + class B extends A { + constructor($scope, $id, ) { + super($scope, $id, ); + this.b = "b"; + } + static _toInflightType() { + return ` + require("${$helpers.normalPath(__dirname)}/inflight.B-1.js")({ + $A: ${$stdlib.core.liftObject(A)}, + }) + `; + } + _toInflight() { + return ` + (await (async () => { + const BClient = ${B._toInflightType()}; + const client = new BClient({ + $this_b: ${$stdlib.core.liftObject(this.b)}, + $this_a: ${$stdlib.core.liftObject(this.a)}, + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `; + } + get _liftMap() { + return $stdlib.core.mergeLiftDeps(super._liftMap, { + "do": [ + [this.b, []], + ], + "$inflight_init": [ + [this.b, []], + ], + }); + } + } + class C extends B { + constructor($scope, $id, ) { + super($scope, $id, ); + this.c = "c"; + } + static _toInflightType() { + return ` + require("${$helpers.normalPath(__dirname)}/inflight.C-1.js")({ + $B: ${$stdlib.core.liftObject(B)}, + }) + `; + } + _toInflight() { + return ` + (await (async () => { + const CClient = ${C._toInflightType()}; + const client = new CClient({ + $this_b: ${$stdlib.core.liftObject(this.b)}, + $this_c: ${$stdlib.core.liftObject(this.c)}, + $this_a: ${$stdlib.core.liftObject(this.a)}, + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `; + } + get _liftMap() { + return $stdlib.core.mergeLiftDeps(super._liftMap, { + "dummy": [ + [this.b, []], + ], + "do": [ + [this.c, []], + ], + "$inflight_init": [ + [this.b, []], + [this.c, []], + ], + }); + } + } + class $Closure1 extends $stdlib.std.AutoIdResource { + _id = $stdlib.core.closureId(); + constructor($scope, $id, ) { + super($scope, $id); + $helpers.nodeof(this).hidden = true; + } + static _toInflightType() { + return ` + require("${$helpers.normalPath(__dirname)}/inflight.$Closure1-1.js")({ + $c: ${$stdlib.core.liftObject(c)}, + }) + `; + } + _toInflight() { + return ` + (await (async () => { + const $Closure1Client = ${$Closure1._toInflightType()}; + const client = new $Closure1Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `; + } + get _liftMap() { + return ({ + "handle": [ + [c, ["do"]], + ], + "$inflight_init": [ + [c, []], + ], + }); + } + } + const c = new C(this, "C"); + this.node.root.new("@winglang/sdk.std.Test", std.Test, this, "test:test", new $Closure1(this, "$Closure1")); + } +} +const $PlatformManager = new $stdlib.platform.PlatformManager({platformPaths: $platforms}); +const $APP = $PlatformManager.createApp({ outdir: $outdir, name: "lift_parent_fields.test", rootConstruct: $Root, isTestEnvironment: $wing_is_test, entrypointDir: process.env['WING_SOURCE_DIR'], rootId: process.env['WING_ROOT_ID'] }); +$APP.synth(); +//# sourceMappingURL=preflight.js.map +``` + diff --git a/tools/hangar/__snapshots__/test_corpus/valid/lift_parent_fields.test.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/lift_parent_fields.test.w_test_sim.md new file mode 100644 index 00000000000..4224ff430b9 --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/valid/lift_parent_fields.test.w_test_sim.md @@ -0,0 +1,12 @@ +# [lift_parent_fields.test.w](../../../../../examples/tests/valid/lift_parent_fields.test.w) | test | sim + +## stdout.log +```log +pass ─ lift_parent_fields.test.wsim » root/env0/test:test + + +Tests 1 passed (1) +Test Files 1 passed (1) +Duration +``` + From ad4e94c9b883118119ecd9bfe92fd69587577cc6 Mon Sep 17 00:00:00 2001 From: Ainvoner <2538825+ainvoner@users.noreply.github.com> Date: Sun, 7 Apr 2024 15:31:28 +0300 Subject: [PATCH 13/16] fix(docs): failed to update docs (#6164) `
` tag should be closed for some reason. updated to `
` ## Checklist - [ ] Title matches [Winglang's style guide](https://www.winglang.io/contributing/start-here/pull_requests#how-are-pull-request-titles-formatted) - [ ] Description explains motivation and solution - [ ] Tests added (always) - [ ] Docs updated (only required for features) - [ ] Added `pr/e2e-full` label if this feature requires end-to-end testing *By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*. --- docs/docs/03-language-reference.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/03-language-reference.md b/docs/docs/03-language-reference.md index 2eb407424f9..b60dcaecc25 100644 --- a/docs/docs/03-language-reference.md +++ b/docs/docs/03-language-reference.md @@ -1869,8 +1869,8 @@ Mapping JSII types to Wing types: | **JSII Type** | **Wing Type** | |---------------|--------------------| -| [class](https://aws.github.io/jsii/user-guides/language-support/assembly/#classes) | A [Wing class](#32-classes).
The [phase](#13-phase-modifiers) of the class will be `preflight` if the imported class is a [construct](https://github.com/aws/constructs) (derived from `constructs.Construct`). Otherwise the class will be phase independent.
By convention construct constructors have a `scope` and `id` as their first parameters. These will be used by Wing to define the default scope and id for new instances of this [preflight class](#33-preflight-classes) or explicit scope and id using the `in` and `as` keywords. | -| [interface](https://aws.github.io/jsii/user-guides/language-support/assembly/#interfaces) | A [Wing interface](#34-interfaces). All imported interfaces are `preflight` interfaces.
JSII library authors may annotate their interface with a docstring tag like `@inflight IMyClient` to indicate a second interface that'll be used to import inflight methods **into** this Wing interface. | +| [class](https://aws.github.io/jsii/user-guides/language-support/assembly/#classes) | A [Wing class](#32-classes).
The [phase](#13-phase-modifiers) of the class will be `preflight` if the imported class is a [construct](https://github.com/aws/constructs) (derived from `constructs.Construct`). Otherwise the class will be phase independent.
By convention construct constructors have a `scope` and `id` as their first parameters. These will be used by Wing to define the default scope and id for new instances of this [preflight class](#33-preflight-classes) or explicit scope and id using the `in` and `as` keywords. | +| [interface](https://aws.github.io/jsii/user-guides/language-support/assembly/#interfaces) | A [Wing interface](#34-interfaces). All imported interfaces are `preflight` interfaces.
JSII library authors may annotate their interface with a docstring tag like `@inflight IMyClient` to indicate a second interface that'll be used to import inflight methods **into** this Wing interface. | | [struct (a.k.a. data-type)](https://aws.github.io/jsii/user-guides/language-support/assembly/#structs-aka-data-types) | A [Wing struct](#31-structs). Always phase independent. | | [enum](https://aws.github.io/jsii/user-guides/language-support/assembly/#enums) | A [Wing enum](#38-enumeration). | From 087e81678963b413db487c1e0166b59a0faa70a6 Mon Sep 17 00:00:00 2001 From: Ainvoner <2538825+ainvoner@users.noreply.github.com> Date: Sun, 7 Apr 2024 15:39:28 +0300 Subject: [PATCH 14/16] fix(docs): failed to update docs 2 (#6165) and now with the correct tag closing character ## Checklist - [ ] Title matches [Winglang's style guide](https://www.winglang.io/contributing/start-here/pull_requests#how-are-pull-request-titles-formatted) - [ ] Description explains motivation and solution - [ ] Tests added (always) - [ ] Docs updated (only required for features) - [ ] Added `pr/e2e-full` label if this feature requires end-to-end testing *By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*. --- docs/docs/03-language-reference.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/03-language-reference.md b/docs/docs/03-language-reference.md index b60dcaecc25..f4f26739a16 100644 --- a/docs/docs/03-language-reference.md +++ b/docs/docs/03-language-reference.md @@ -1869,8 +1869,8 @@ Mapping JSII types to Wing types: | **JSII Type** | **Wing Type** | |---------------|--------------------| -| [class](https://aws.github.io/jsii/user-guides/language-support/assembly/#classes) | A [Wing class](#32-classes).
The [phase](#13-phase-modifiers) of the class will be `preflight` if the imported class is a [construct](https://github.com/aws/constructs) (derived from `constructs.Construct`). Otherwise the class will be phase independent.
By convention construct constructors have a `scope` and `id` as their first parameters. These will be used by Wing to define the default scope and id for new instances of this [preflight class](#33-preflight-classes) or explicit scope and id using the `in` and `as` keywords. | -| [interface](https://aws.github.io/jsii/user-guides/language-support/assembly/#interfaces) | A [Wing interface](#34-interfaces). All imported interfaces are `preflight` interfaces.
JSII library authors may annotate their interface with a docstring tag like `@inflight IMyClient` to indicate a second interface that'll be used to import inflight methods **into** this Wing interface. | +| [class](https://aws.github.io/jsii/user-guides/language-support/assembly/#classes) | A [Wing class](#32-classes).
The [phase](#13-phase-modifiers) of the class will be `preflight` if the imported class is a [construct](https://github.com/aws/constructs) (derived from `constructs.Construct`). Otherwise the class will be phase independent.
By convention construct constructors have a `scope` and `id` as their first parameters. These will be used by Wing to define the default scope and id for new instances of this [preflight class](#33-preflight-classes) or explicit scope and id using the `in` and `as` keywords. | +| [interface](https://aws.github.io/jsii/user-guides/language-support/assembly/#interfaces) | A [Wing interface](#34-interfaces). All imported interfaces are `preflight` interfaces.
JSII library authors may annotate their interface with a docstring tag like `@inflight IMyClient` to indicate a second interface that'll be used to import inflight methods **into** this Wing interface. | | [struct (a.k.a. data-type)](https://aws.github.io/jsii/user-guides/language-support/assembly/#structs-aka-data-types) | A [Wing struct](#31-structs). Always phase independent. | | [enum](https://aws.github.io/jsii/user-guides/language-support/assembly/#enums) | A [Wing enum](#38-enumeration). | From 44760ce857697926c6c4091db3e727fd193c55cd Mon Sep 17 00:00:00 2001 From: yoav-steinberg Date: Sun, 7 Apr 2024 18:51:01 +0300 Subject: [PATCH 15/16] fix(compiler): no error when missing `return` and there's an inner closure that has a `return` (#6162) Fixes #5481 Don't recurse into inner closures when searching for a return stmt for missing `return` diagnostics. ## Checklist - [x] Title matches [Winglang's style guide](https://www.winglang.io/contributing/start-here/pull_requests#how-are-pull-request-titles-formatted) - [x] Description explains motivation and solution - [x] Tests added (always) - [ ] Docs updated (only required for features) - [ ] Added `pr/e2e-full` label if this feature requires end-to-end testing *By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*. --- examples/tests/invalid/missing_return.test.w | 8 ++++++++ examples/tests/valid/while_loop_await.test.w | 2 +- libs/wingc/src/type_check/has_type_stmt.rs | 10 +++++++++- tools/hangar/__snapshots__/invalid.ts.snap | 12 ++++++++++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/examples/tests/invalid/missing_return.test.w b/examples/tests/invalid/missing_return.test.w index 558f5d1d705..0a18c1a221e 100644 --- a/examples/tests/invalid/missing_return.test.w +++ b/examples/tests/invalid/missing_return.test.w @@ -23,3 +23,11 @@ let returnString2 = inflight (): str => { return "hi"; } }; + +// Ignore return statements in inner closures when searching for return statements +let returnString3 = (): str => { + let x = (): str => { + return "what?"; // This should be ignored and we should produce a missing return error + }; +}; +//^ A function whose return type is "str" must return a value. diff --git a/examples/tests/valid/while_loop_await.test.w b/examples/tests/valid/while_loop_await.test.w index f7e032126cf..4ba2bc9a549 100644 --- a/examples/tests/valid/while_loop_await.test.w +++ b/examples/tests/valid/while_loop_await.test.w @@ -2,7 +2,7 @@ bring cloud; let queue = new cloud.Queue(); -let handler = inflight (body: str): str => { +let handler = inflight (body: str): void => { let i = 0; let iterator = inflight (j: num): num => { return j+1; diff --git a/libs/wingc/src/type_check/has_type_stmt.rs b/libs/wingc/src/type_check/has_type_stmt.rs index 363e97fa63c..e28edc8cef6 100644 --- a/libs/wingc/src/type_check/has_type_stmt.rs +++ b/libs/wingc/src/type_check/has_type_stmt.rs @@ -1,5 +1,5 @@ use crate::{ - ast::{Stmt, StmtKind}, + ast::{Expr, ExprKind, Stmt, StmtKind}, visit::{self, Visit}, }; @@ -27,4 +27,12 @@ impl Visit<'_> for HasStatementVisitor { } visit::visit_stmt(self, node); } + + fn visit_expr(&mut self, node: &'_ Expr) { + // Don't recurse into closures. This way our search will ignore stmts in inner closures. + if matches!(node.kind, ExprKind::FunctionClosure(_)) { + return; + } + visit::visit_expr(self, node); + } } diff --git a/tools/hangar/__snapshots__/invalid.ts.snap b/tools/hangar/__snapshots__/invalid.ts.snap index 6cf66d7d09a..a44e6108b80 100644 --- a/tools/hangar/__snapshots__/invalid.ts.snap +++ b/tools/hangar/__snapshots__/invalid.ts.snap @@ -2712,6 +2712,18 @@ exports[`missing_return.test.w 1`] = ` | \\\\-^ A function whose return type is \\"str\\" must return a value. +error: A function whose return type is \\"str\\" must return a value. + --> ../../../examples/tests/invalid/missing_return.test.w:28:32 + | +28 | let returnString3 = (): str => { + | /--------------------------------^ +29 | | let x = (): str => { +30 | | return \\"what?\\"; // This should be ignored and we should produce a missing return error +31 | | }; +32 | | }; + | \\\\-^ A function whose return type is \\"str\\" must return a value. + + Tests 1 failed (1) From 47fd645afa0b1cdd4ee1de68a78343853302571b Mon Sep 17 00:00:00 2001 From: Chris Rybicki Date: Mon, 8 Apr 2024 12:15:22 -0400 Subject: [PATCH 16/16] fix(sdk): permissions errors are not caught in simulator (#6153) Reintroduce https://github.com/winglang/wing/pull/6079 after it was reverted by https://github.com/winglang/wing/pull/6125 in an attempt to fix https://github.com/winglang/wing/issues/6135. Fixes #6002 ## Checklist - [x] Title matches [Winglang's style guide](https://www.winglang.io/contributing/start-here/pull_requests#how-are-pull-request-titles-formatted) - [x] Description explains motivation and solution - [x] Tests added (always) - [ ] Docs updated (only required for features) - [ ] Added `pr/e2e-full` label if this feature requires end-to-end testing *By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*. --- .../04-standard-library/sim/api-reference.md | 224 +++- .../invalid/simulator_permissions.test.w | 26 + .../tests/sdk_tests/service/callbacks.test.w | 2 +- libs/wingsdk/src/cloud/bucket.ts | 2 +- libs/wingsdk/src/shared/sandbox.ts | 4 +- libs/wingsdk/src/simulator/client.ts | 16 +- libs/wingsdk/src/simulator/simulator.ts | 178 ++- libs/wingsdk/src/simulator/util.ts | 19 + libs/wingsdk/src/target-sim/api.inflight.ts | 15 +- libs/wingsdk/src/target-sim/api.ts | 6 +- libs/wingsdk/src/target-sim/app.ts | 17 +- .../wingsdk/src/target-sim/bucket.inflight.ts | 20 +- libs/wingsdk/src/target-sim/bucket.ts | 47 +- .../src/target-sim/container.inflight.ts | 32 +- libs/wingsdk/src/target-sim/container.ts | 2 +- .../src/target-sim/counter.inflight.ts | 18 +- libs/wingsdk/src/target-sim/counter.ts | 2 +- .../wingsdk/src/target-sim/domain.inflight.ts | 4 +- .../src/target-sim/endpoint.inflight.ts | 26 +- .../src/target-sim/event-mapping.inflight.ts | 33 +- libs/wingsdk/src/target-sim/event-mapping.ts | 8 +- .../src/target-sim/function.inflight.ts | 33 +- libs/wingsdk/src/target-sim/function.ts | 27 +- libs/wingsdk/src/target-sim/index.ts | 1 + .../src/target-sim/on-deploy.inflight.ts | 19 +- libs/wingsdk/src/target-sim/on-deploy.ts | 4 +- .../wingsdk/src/target-sim/policy.inflight.ts | 22 + libs/wingsdk/src/target-sim/policy.ts | 72 ++ libs/wingsdk/src/target-sim/queue.inflight.ts | 21 +- libs/wingsdk/src/target-sim/queue.ts | 17 +- .../src/target-sim/react-app.inflight.ts | 15 +- libs/wingsdk/src/target-sim/react-app.ts | 2 +- libs/wingsdk/src/target-sim/redis.inflight.ts | 7 +- libs/wingsdk/src/target-sim/redis.ts | 2 +- libs/wingsdk/src/target-sim/resource.ts | 26 +- .../src/target-sim/schedule.inflight.ts | 15 +- libs/wingsdk/src/target-sim/schedule.ts | 6 +- .../src/target-sim/schema-resources.ts | 57 +- .../wingsdk/src/target-sim/secret.inflight.ts | 16 +- libs/wingsdk/src/target-sim/secret.ts | 2 +- .../src/target-sim/service.inflight.ts | 86 +- libs/wingsdk/src/target-sim/service.ts | 81 +- libs/wingsdk/src/target-sim/state.inflight.ts | 17 +- libs/wingsdk/src/target-sim/state.ts | 2 +- libs/wingsdk/src/target-sim/table.inflight.ts | 15 +- libs/wingsdk/src/target-sim/table.ts | 2 +- .../src/target-sim/test-runner.inflight.ts | 20 +- libs/wingsdk/src/target-sim/test-runner.ts | 2 +- libs/wingsdk/src/target-sim/topic.inflight.ts | 19 +- libs/wingsdk/src/target-sim/topic.ts | 9 +- libs/wingsdk/src/target-sim/util.ts | 19 +- .../src/target-sim/website.inflight.ts | 16 +- libs/wingsdk/src/target-sim/website.ts | 2 +- libs/wingsdk/src/util/enhanced-error.ts | 3 +- .../__snapshots__/connections.test.ts.snap | 58 + libs/wingsdk/test/simulator/cleanup.test.ts | 25 +- libs/wingsdk/test/simulator/on-trace.test.ts | 2 +- libs/wingsdk/test/simulator/simulator.test.ts | 196 ++- .../target-sim/__snapshots__/api.test.ts.snap | 1064 ++++++++++++++++- .../__snapshots__/bucket.test.ts.snap | 197 ++- .../__snapshots__/counter.test.ts.snap | 56 + .../__snapshots__/file-counter.test.ts.snap | 111 +- .../__snapshots__/function.test.ts.snap | 292 ++++- .../immutable-capture.test.ts.snap | 462 +++++++ .../__snapshots__/on-deploy.test.ts.snap | 36 + .../__snapshots__/queue.test.ts.snap | 270 ++++- .../__snapshots__/redis.test.ts.snap | 8 + .../__snapshots__/schedule.test.ts.snap | 216 ++++ .../__snapshots__/secret.test.ts.snap | 8 + .../__snapshots__/service.test.ts.snap | 59 +- .../__snapshots__/table.test.ts.snap | 56 + .../__snapshots__/test.test.ts.snap | 33 + .../__snapshots__/topic-producer.test.ts.snap | 11 +- .../__snapshots__/topic.test.ts.snap | 33 + libs/wingsdk/test/target-sim/app.test.ts | 9 +- libs/wingsdk/test/target-sim/bucket.test.ts | 16 +- libs/wingsdk/test/target-sim/function.test.ts | 18 +- .../wingsdk/test/target-sim/on-deploy.test.ts | 2 +- libs/wingsdk/test/target-sim/queue.test.ts | 2 +- libs/wingsdk/test/target-sim/service.test.ts | 5 +- .../test/target-sim/topic-producer.test.ts | 7 +- libs/wingsdk/test/target-sim/util.ts | 2 +- .../test/ui/__snapshots__/ui.test.ts.snap | 4 + tools/hangar/__snapshots__/invalid.ts.snap | 26 + 84 files changed, 4336 insertions(+), 306 deletions(-) create mode 100644 examples/tests/invalid/simulator_permissions.test.w create mode 100644 libs/wingsdk/src/simulator/util.ts create mode 100644 libs/wingsdk/src/target-sim/policy.inflight.ts create mode 100644 libs/wingsdk/src/target-sim/policy.ts diff --git a/docs/docs/04-standard-library/sim/api-reference.md b/docs/docs/04-standard-library/sim/api-reference.md index 0ecb35cda5c..6749af2595a 100644 --- a/docs/docs/04-standard-library/sim/api-reference.md +++ b/docs/docs/04-standard-library/sim/api-reference.md @@ -126,6 +126,126 @@ A token that resolves to the host port of this container. --- +### Policy + +- *Implements:* ISimulatorResource + +Implementation of `sim.Policy`. + +#### Initializers + +```wing +bring sim; + +new sim.Policy(props: PolicyProps); +``` + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| props | PolicyProps | *No description.* | + +--- + +##### `props`Required + +- *Type:* PolicyProps + +--- + +#### Methods + +| **Name** | **Description** | +| --- | --- | +| addStatement | Adds a statement to the policy. | +| toSimulator | Convert this resource to a resource schema for the simulator. | + +--- + +##### `addStatement` + +```wing +addStatement(resource: IResource, op: str): void +``` + +Adds a statement to the policy. + +###### `resource`Required + +- *Type:* IResource + +--- + +###### `op`Required + +- *Type:* str + +--- + +##### `toSimulator` + +```wing +toSimulator(): BaseResourceSchema +``` + +Convert this resource to a resource schema for the simulator. + +#### Static Functions + +| **Name** | **Description** | +| --- | --- | +| onLiftType | A hook called by the Wing compiler once for each inflight host that needs to use this type inflight. | + +--- + +##### `onLiftType` + +```wing +bring sim; + +sim.Policy.onLiftType(host: IInflightHost, ops: MutArray); +``` + +A hook called by the Wing compiler once for each inflight host that needs to use this type inflight. + +The list of requested inflight methods +needed by the inflight host are given by `ops`. + +This method is commonly used for adding permissions, environment variables, or +other capabilities to the inflight host. + +###### `host`Required + +- *Type:* IInflightHost + +--- + +###### `ops`Required + +- *Type:* MutArray<str> + +--- + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| node | constructs.Node | The tree node. | + +--- + +##### `node`Required + +```wing +node: Node; +``` + +- *Type:* constructs.Node + +The tree node. + +--- + + ### State - *Implements:* ISimulatorResource @@ -436,15 +556,115 @@ A glob of local files to consider as input sources for the container, relative t --- +### PolicyProps + +Options for `sim.Policy`. + +#### Initializer + +```wing +bring sim; + +let PolicyProps = sim.PolicyProps{ ... }; +``` + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| principal | IResource | The resource to which the policy is attached. | + +--- + +##### `principal`Required + +```wing +principal: IResource; +``` + +- *Type:* IResource + +The resource to which the policy is attached. + +--- + ## Protocols +### IPolicyClient + +- *Implemented By:* IPolicyClient + +Inflight interface for `Policy`. + + + +### ISimulatorInflightHost + +- *Extends:* IInflightHost + +- *Implemented By:* ISimulatorInflightHost + +Interfaces shared by all preflight classes that host inflight code. + +#### Methods + +| **Name** | **Description** | +| --- | --- | +| addPermission | Add a simulated permission to this inflight host. | + +--- + +##### `addPermission` + +```wing +addPermission(resource: IResource, op: str): void +``` + +Add a simulated permission to this inflight host. + +###### `resource`Required + +- *Type:* IResource + +The resource to add. + +--- + +###### `op`Required + +- *Type:* str + +The action to add. + +--- + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| node | constructs.Node | The tree node. | + +--- + +##### `node`Required + +```wing +node: Node; +``` + +- *Type:* constructs.Node + +The tree node. + +--- + ### ISimulatorResource - *Extends:* IResource -- *Implemented By:* Container, State, ISimulatorResource +- *Implemented By:* Container, Policy, State, ISimulatorResource -Interfaces shared by all polycon implementations (preflight classes) targeting the simulator. +Interfaces shared by all preflight classes targeting the simulator. #### Methods diff --git a/examples/tests/invalid/simulator_permissions.test.w b/examples/tests/invalid/simulator_permissions.test.w new file mode 100644 index 00000000000..81f3ab9f033 --- /dev/null +++ b/examples/tests/invalid/simulator_permissions.test.w @@ -0,0 +1,26 @@ +bring cloud; + +let buckets = [ + new cloud.Bucket() as "b1", + new cloud.Bucket() as "b2" +]; + +test "incorrect resource permission" { + // This test fails because permission is granted to b2, not b1 + lift(buckets.at(1), ["put"]); + let var i = 10; + while i > 0 { + i -= 1; + } + buckets.at(i).put("key", "value"); +} + +test "incorrect permission operation" { + // This test fails because permission is granted for "list", not "put" + lift(buckets.at(0), ["list"]); + let var i = 10; + while i > 0 { + i -= 1; + } + buckets.at(i).put("key", "value"); +} diff --git a/examples/tests/sdk_tests/service/callbacks.test.w b/examples/tests/sdk_tests/service/callbacks.test.w index 3ed3b962a62..1f35b77da80 100644 --- a/examples/tests/sdk_tests/service/callbacks.test.w +++ b/examples/tests/sdk_tests/service/callbacks.test.w @@ -50,4 +50,4 @@ if util.env("WING_TARGET") == "sim" { assert(startCounter.peek() == 0); assert(b.get(status) == stopped); } -} \ No newline at end of file +} diff --git a/libs/wingsdk/src/cloud/bucket.ts b/libs/wingsdk/src/cloud/bucket.ts index e35992a38e4..dae03e3c800 100644 --- a/libs/wingsdk/src/cloud/bucket.ts +++ b/libs/wingsdk/src/cloud/bucket.ts @@ -107,7 +107,7 @@ export class Bucket extends Resource { * Gets topic form the topics map, or creates if not exists * @param actionType */ - private getTopic(actionType: BucketEventType): Topic { + protected getTopic(actionType: BucketEventType): Topic { if (!this._topics.has(actionType)) { this._topics.set(actionType, this.createTopic(actionType)); } diff --git a/libs/wingsdk/src/shared/sandbox.ts b/libs/wingsdk/src/shared/sandbox.ts index f61d61fde6d..510b2c9e443 100644 --- a/libs/wingsdk/src/shared/sandbox.ts +++ b/libs/wingsdk/src/shared/sandbox.ts @@ -222,14 +222,14 @@ process.on("message", async (message) => { // "exit" could be emitted if the user code called process.exit(), or if we killed the process // due to a timeout or unexpected error. In any case, we reject the promise. - this.onChildExit = (code: number | null) => { + this.onChildExit = (code: number | null, signal: unknown) => { this.debugLog("Child processed stopped."); this.child = undefined; this.available = true; if (this.timeout) { clearTimeout(this.timeout); } - reject(new Error(`Process exited with code ${code}`)); + reject(new Error(`Process exited with code ${code}, signal ${signal}`)); }; if (this.options.timeout) { diff --git a/libs/wingsdk/src/simulator/client.ts b/libs/wingsdk/src/simulator/client.ts index a46262b7f05..9b223330fbd 100644 --- a/libs/wingsdk/src/simulator/client.ts +++ b/libs/wingsdk/src/simulator/client.ts @@ -35,7 +35,19 @@ function makeHttpRequest(options: HttpRequestOptions): Promise { }); } -export function makeSimulatorClient(url: string, handle: string) { +/** + * Creates a proxy object that forwards method calls to the simulator server. + * + * @param url The URL of the simulator server + * @param handle The handle for the resource we're calling methods on or getting properties from + * @param caller The handle of the resource that is making the calls + * @returns A proxy object that forwards calls to the simulator server + */ +export function makeSimulatorClient( + url: string, + handle: string, + caller: string +) { let proxy: any; let hasThenMethod = true; // assume that the object has a "then" method until proven otherwise @@ -45,7 +57,7 @@ export function makeSimulatorClient(url: string, handle: string) { } return async function (...args: any[]) { - const body: SimulatorServerRequest = { handle, method, args }; + const body: SimulatorServerRequest = { caller, handle, method, args }; const parsedUrl = new URL(url); const resp = await makeHttpRequest({ hostname: parsedUrl.hostname, diff --git a/libs/wingsdk/src/simulator/simulator.ts b/libs/wingsdk/src/simulator/simulator.ts index bb63842446b..f445875160e 100644 --- a/libs/wingsdk/src/simulator/simulator.ts +++ b/libs/wingsdk/src/simulator/simulator.ts @@ -7,14 +7,23 @@ import { Graph } from "./graph"; import { deserialize, serialize } from "./serialization"; import { resolveTokens } from "./tokens"; import { Tree } from "./tree"; +import { exists } from "./util"; import { SDK_VERSION } from "../constants"; import { TREE_FILE_PATH } from "../core"; import { readJsonSync } from "../shared/misc"; import { CONNECTIONS_FILE_PATH, Trace, TraceType } from "../std"; +import { POLICY_FQN } from "../target-sim"; +import { PolicySchemaProps } from "../target-sim/schema-resources"; const LOCALHOST_ADDRESS = "127.0.0.1"; const HANDLE_ATTRIBUTE = "handle"; +/** + * If an API call is made to a resource with name as the caller, any permissions + * checking will be skipped. Used by unit tests and the Wing Console. + */ +const ADMIN_PERMISSION = "admin"; + /** * Props for `Simulator`. */ @@ -93,6 +102,11 @@ export interface ISimulatorContext { */ readonly resourcePath: string; + /** + * The handle of the resource that is being simulated. + */ + readonly resourceHandle: string; + /** * The url that the simulator server is listening on. */ @@ -101,7 +115,7 @@ export interface ISimulatorContext { /** * Obtain a client given a resource's handle. */ - getClient(handle: string): unknown; + getClient(handle: string, asAdmin?: boolean): unknown; /** * Add a trace. Traces are breadcrumbs of information about resource @@ -186,6 +200,7 @@ export class Simulator { private _serverUrl: string | undefined; private _server: Server | undefined; private _model: Model; + private _policyRegistry: PolicyRegistry; // keeps the actual resolved state (props and attrs) of all started resources. this state is // merged in when calling `getResourceConfig()`. @@ -198,6 +213,7 @@ export class Simulator { this._running = "stopped"; this._handles = new HandleManager(); + this._policyRegistry = new PolicyRegistry(); this._traces = new Array(); this._traceSubscribers = new Array(); } @@ -380,13 +396,19 @@ export class Simulator { try { const resource = this._handles.find(handle); + await this.ensureStateDirExists(path); await resource.save(this.getResourceStateDir(path)); - this._handles.deallocate(handle); await resource.cleanup(); + this._handles.deallocate(handle); } catch (err) { console.warn(err); } + // if the resource is a policy, remove it from the policy registry + if (this.getResourceConfig(path).type === POLICY_FQN) { + this._policyRegistry.deregister(path); + } + this.addSimulatorTrace(path, { message: `${path} stopped` }); delete this.state[path]; // delete the state of the resource } @@ -453,8 +475,7 @@ export class Simulator { if (!handle) { return undefined; } - - return makeSimulatorClient(this.url, handle); + return makeSimulatorClient(this.url, handle, ADMIN_PERMISSION); } private tryGetResourceHandle(path: string): string | undefined { @@ -509,6 +530,14 @@ export class Simulator { return join(this.statedir, config.addr); } + private async ensureStateDirExists(path: string) { + const statedir = this.getResourceStateDir(path); + const statedirExists = await exists(statedir); + if (!statedirExists) { + await mkdir(statedir, { recursive: true }); + } + } + /** * Obtain a resource's visual interaction components. * @returns An array of UIComponent objects @@ -551,6 +580,43 @@ export class Simulator { return structuredClone(this._model.connections); } + private checkPermission( + callerHandle: string, + calleeHandle: string, + method: string + ): { granted: boolean; reason?: string } { + if (callerHandle === ADMIN_PERMISSION) { + return { granted: true }; + } + + const callerPath = this._handles.tryFindPath(callerHandle); + if (!callerPath) { + return { + granted: false, + reason: `(Permission checking) No caller resource with handle "${callerHandle}" found.`, + }; + } + + const calleePath = this._handles.tryFindPath(calleeHandle); + if (!calleePath) { + return { + granted: false, + reason: `(Permission checking) No callee resource with handle "${calleeHandle}" found.`, + }; + } + + if ( + this._policyRegistry.checkPermission(callerHandle, calleeHandle, method) + ) { + return { granted: true }; + } + + return { + granted: false, + reason: `Resource "${callerPath}" does not have permission to perform operation "${method}" on resource "${calleePath}".`, + }; + } + /** * Start a server that allows any resource to be accessed via HTTP. */ @@ -568,9 +634,24 @@ export class Simulator { }); req.on("end", () => { const request: SimulatorServerRequest = deserialize(body); - const { handle, method, args } = request; + const { caller, handle, method, args } = request; const resource = this._handles.tryFind(handle); + // Check if the caller has permission to call the method on the resource + const grant = this.checkPermission(caller, handle, method); + if (!grant.granted) { + res.writeHead(403, { "Content-Type": "application/json" }); + res.end( + serialize({ + error: { + message: grant.reason, + }, + }), + "utf-8" + ); + return; + } + // If we weren't able to find a resource with the given handle, it could actually // be OK if the resource is still starting up or has already been cleaned up. // In that case, we return a 500 error with a message that explains what happened. @@ -690,7 +771,6 @@ export class Simulator { } const resourceConfig = this.getResourceConfig(path); - const context = this.createContext(resourceConfig); const resolvedProps = this.resolveTokens(resourceConfig.props); @@ -711,15 +791,18 @@ export class Simulator { // create the resource based on its type // eslint-disable-next-line @typescript-eslint/no-require-imports const ResourceType = require(typeInfo.sourcePath)[typeInfo.className]; - const resourceObject = new ResourceType(resolvedProps, context); - const attrs = await resourceObject.init(); + const resourceObject = new ResourceType(resolvedProps); + + // allocate a handle for the resource so others can find it + const handle = this._handles.allocate(path, resourceObject); + + // initialize the resource with the simulator context + const context = this.createContext(resourceConfig, handle); + const attrs = await resourceObject.init(context); // save the current state await resourceObject.save(); - // allocate a handle for the resource so others can find it - const handle = this._handles.allocate(resourceObject); - // merge the attributes this.state[path].attrs = { ...this.state[path].attrs, @@ -731,16 +814,27 @@ export class Simulator { this.addSimulatorTrace(path, { message: `${resourceConfig.path} started`, }); + + // if the resource is a policy, add it to the policy registry + if (resourceConfig.type === POLICY_FQN) { + const policyProps = resolvedProps as PolicySchemaProps; + this._policyRegistry.register(resourceConfig.path, policyProps); + } } - private createContext(resourceConfig: BaseResourceSchema): ISimulatorContext { + private createContext( + resourceConfig: BaseResourceSchema, + resourceHandle: string + ): ISimulatorContext { return { simdir: this._model.simdir, statedir: join(this.statedir, resourceConfig.addr), resourcePath: resourceConfig.path, + resourceHandle: resourceHandle, serverUrl: this.url, - getClient: (handle: string) => { - return makeSimulatorClient(this.url, handle); + getClient: (calleeHandle: string, asAdmin: boolean) => { + const callerHandle = asAdmin ? ADMIN_PERMISSION : resourceHandle; + return makeSimulatorClient(this.url, calleeHandle, callerHandle); }, addTrace: (trace: Trace) => { this.addTrace(trace); @@ -944,16 +1038,19 @@ export interface ISimulatorFactory { class HandleManager { private readonly handles: Map; + private readonly paths: Map; // handle -> path private nextHandle: number; public constructor() { this.handles = new Map(); + this.paths = new Map(); this.nextHandle = 0; } - public allocate(resource: ISimulatorResourceInstance): string { + public allocate(path: string, resource: ISimulatorResourceInstance): string { const handle = `sim-${this.nextHandle++}`; this.handles.set(handle, resource); + this.paths.set(handle, path); return handle; } @@ -969,17 +1066,23 @@ class HandleManager { return this.handles.get(handle); } + public tryFindPath(handle: string): string | undefined { + return this.paths.get(handle); + } + public deallocate(handle: string): ISimulatorResourceInstance { const instance = this.handles.get(handle); if (!instance) { throw new Error(`No resource found with handle "${handle}".`); } this.handles.delete(handle); + this.paths.delete(handle); return instance; } public reset(): void { this.handles.clear(); + this.paths.clear(); this.nextHandle = 0; } } @@ -992,7 +1095,7 @@ export interface ISimulatorResourceInstance { * Perform any async initialization required by the resource. Return a map of * the resource's runtime attributes. */ - init(): Promise>; + init(ctx: ISimulatorContext): Promise>; /** * Stop the resource and clean up any physical resources it may have created @@ -1091,7 +1194,9 @@ export interface ConnectionData { * Subject to breaking changes. */ export interface SimulatorServerRequest { - /** The resource handle (an ID unique among resources in the simulation). */ + /** The handle of the resource making the request. */ + readonly caller: string; + /** The target resource handle (an ID unique among resources in the simulation). */ readonly handle: string; /** The method to call on the resource. */ readonly method: string; @@ -1109,3 +1214,42 @@ export interface SimulatorServerResponse { /** The error that occurred during the method call. */ readonly error?: any; } + +class PolicyRegistry { + private readonly policies: Record; + + constructor() { + this.policies = {}; + } + + public register(id: string, policy: PolicySchemaProps) { + if (this.policies[id]) { + throw new Error(`Policy with id ${id} already registered.`); + } + this.policies[id] = policy; + } + + public deregister(id: string) { + delete this.policies[id]; + } + + public checkPermission( + caller: string, + callee: string, + method: string + ): boolean { + for (const policy of Object.values(this.policies)) { + if (policy.principal === caller) { + for (const statement of policy.statements) { + if ( + statement.resourceHandle === callee && + statement.operation === method + ) { + return true; + } + } + } + } + return false; + } +} diff --git a/libs/wingsdk/src/simulator/util.ts b/libs/wingsdk/src/simulator/util.ts new file mode 100644 index 00000000000..16148b3cf1b --- /dev/null +++ b/libs/wingsdk/src/simulator/util.ts @@ -0,0 +1,19 @@ +import { access, constants } from "node:fs"; +import { promisify } from "node:util"; + +/** + * Check if a file exists for an specific path + * @param filePath + * @Returns Return `true` if the file exists, `false` otherwise. + */ +export async function exists(filePath: string): Promise { + try { + await promisify(access)( + filePath, + constants.F_OK | constants.R_OK | constants.W_OK //eslint-disable-line no-bitwise + ); + return true; + } catch (er) { + return false; + } +} diff --git a/libs/wingsdk/src/target-sim/api.inflight.ts b/libs/wingsdk/src/target-sim/api.inflight.ts index f53b86400c9..6a0bd4b1595 100644 --- a/libs/wingsdk/src/target-sim/api.inflight.ts +++ b/libs/wingsdk/src/target-sim/api.inflight.ts @@ -51,15 +51,14 @@ export class Api implements IApiClient, ISimulatorResourceInstance, IEventPublisher { private readonly routes: ApiRouteWithFunctionHandle[]; - private readonly context: ISimulatorContext; + private _context: ISimulatorContext | undefined; private readonly app: express.Application; private server: Server | undefined; private url: string | undefined; private port: number | undefined; - constructor(props: ApiSchema["props"], context: ISimulatorContext) { + constructor(props: ApiSchema["props"]) { this.routes = []; - this.context = context; const { corsHeaders } = props; // Set up an express server that handles the routes. @@ -95,7 +94,15 @@ export class Api } } - public async init(): Promise { + private get context(): ISimulatorContext { + if (!this._context) { + throw new Error("Cannot access context during class construction"); + } + return this._context; + } + + public async init(context: ISimulatorContext): Promise { + this._context = context; // Check for a previous state file to see if there was a port that was previously being used // if so, try to use it out of convenience let lastPort: number | undefined; diff --git a/libs/wingsdk/src/target-sim/api.ts b/libs/wingsdk/src/target-sim/api.ts index 5cdb5cddc0d..ea60d2ccd62 100644 --- a/libs/wingsdk/src/target-sim/api.ts +++ b/libs/wingsdk/src/target-sim/api.ts @@ -3,6 +3,7 @@ import { Construct } from "constructs"; import { App } from "./app"; import { EventMapping } from "./event-mapping"; import { Function } from "./function"; +import { Policy } from "./policy"; import { ISimulatorResource } from "./resource"; import { ApiSchema, ApiRoute } from "./schema-resources"; import { simulatorAttrToken } from "./tokens"; @@ -24,6 +25,7 @@ export class Api extends cloud.Api implements ISimulatorResource { > = {}; private readonly endpoint: cloud.Endpoint; + private readonly policy: Policy; constructor(scope: Construct, id: string, props: cloud.ApiProps = {}) { super(scope, id, props); @@ -34,6 +36,7 @@ export class Api extends cloud.Api implements ISimulatorResource { simulatorAttrToken(this, "url"), { label: `Api ${this.node.path}` } ); + this.policy = new Policy(this, "Policy", { principal: this }); } protected get _endpoint(): cloud.Endpoint { @@ -116,6 +119,7 @@ export class Api extends cloud.Api implements ISimulatorResource { target: fn, name: `${method.toLowerCase()}()`, }); + this.policy.addStatement(fn, cloud.FunctionInflightMethods.INVOKE); } /** @@ -245,7 +249,7 @@ export class Api extends cloud.Api implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host); + bindSimulatorResource(__filename, this, host, ops); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/app.ts b/libs/wingsdk/src/target-sim/app.ts index 8595c37bc6a..140dddb7454 100644 --- a/libs/wingsdk/src/target-sim/app.ts +++ b/libs/wingsdk/src/target-sim/app.ts @@ -9,13 +9,14 @@ import { Endpoint } from "./endpoint"; import { EVENT_MAPPING_FQN } from "./event-mapping"; import { Function } from "./function"; import { OnDeploy } from "./on-deploy"; +import { POLICY_FQN, Policy } from "./policy"; import { Queue } from "./queue"; import { ReactApp } from "./react-app"; import { Redis } from "./redis"; import { ISimulatorResource, isSimulatorResource } from "./resource"; import { Schedule } from "./schedule"; import { Secret } from "./secret"; -import { Service } from "./service"; +import { SERVICE_HELPER_FQN, Service, ServiceHelper } from "./service"; import { STATE_FQN, State } from "./state"; import { Table } from "./table"; import { TestRunner } from "./test-runner"; @@ -59,12 +60,14 @@ const SIMULATOR_CLASS_DATA = { [EVENT_MAPPING_FQN]: "EventMapping", [FUNCTION_FQN]: "Function", [ON_DEPLOY_FQN]: "OnDeploy", + [POLICY_FQN]: "Policy", [QUEUE_FQN]: "Queue", [REACT_APP_FQN]: "ReactApp", [REDIS_FQN]: "Redis", [SCHEDULE_FQN]: "Schedule", [SECRET_FQN]: "Secret", [SERVICE_FQN]: "Service", + [SERVICE_HELPER_FQN]: "ServiceHelper", [STATE_FQN]: "State", [SIM_CONTAINER_FQN]: "Container", [TABLE_FQN]: "Table", @@ -119,6 +122,9 @@ export class App extends core.App { case ON_DEPLOY_FQN: return require.resolve("./on-deploy.inflight"); + case POLICY_FQN: + return require.resolve("./policy.inflight"); + case QUEUE_FQN: return require.resolve("./queue.inflight"); @@ -137,6 +143,9 @@ export class App extends core.App { case SERVICE_FQN: return require.resolve("./service.inflight"); + case SERVICE_HELPER_FQN: + return require.resolve("./service.inflight"); + case STATE_FQN: return require.resolve("./state.inflight"); @@ -184,6 +193,9 @@ export class App extends core.App { case ON_DEPLOY_FQN: return OnDeploy; + case POLICY_FQN: + return Policy; + case QUEUE_FQN: return Queue; @@ -202,6 +214,9 @@ export class App extends core.App { case SERVICE_FQN: return Service; + case SERVICE_HELPER_FQN: + return ServiceHelper; + case STATE_FQN: return State; diff --git a/libs/wingsdk/src/target-sim/bucket.inflight.ts b/libs/wingsdk/src/target-sim/bucket.inflight.ts index f4178e6e50b..18cb87ed8f2 100644 --- a/libs/wingsdk/src/target-sim/bucket.inflight.ts +++ b/libs/wingsdk/src/target-sim/bucket.inflight.ts @@ -28,23 +28,31 @@ import { Datetime, Json, TraceType } from "../std"; export const METADATA_FILENAME = "metadata.json"; export class Bucket implements IBucketClient, ISimulatorResourceInstance { - private readonly _fileDir: string; - private readonly context: ISimulatorContext; + private _fileDir!: string; + private _context: ISimulatorContext | undefined; private readonly initialObjects: Record; private readonly _public: boolean; private readonly topicHandlers: Partial>; private _metadata: Map; - public constructor(props: BucketSchema["props"], context: ISimulatorContext) { - this._fileDir = join(context.statedir, "files"); - this.context = context; + public constructor(props: BucketSchema["props"]) { this.initialObjects = props.initialObjects ?? {}; this._public = props.public ?? false; this.topicHandlers = props.topics; this._metadata = new Map(); } - public async init(): Promise { + private get context(): ISimulatorContext { + if (!this._context) { + throw new Error("Cannot access context during class construction"); + } + return this._context; + } + + public async init(context: ISimulatorContext): Promise { + this._context = context; + this._fileDir = join(context.statedir, "files"); + const fileDirExists = await exists(this._fileDir); if (!fileDirExists) { await fs.promises.mkdir(this._fileDir, { recursive: true }); diff --git a/libs/wingsdk/src/target-sim/bucket.ts b/libs/wingsdk/src/target-sim/bucket.ts index afb13c5573b..0d263dbfec1 100644 --- a/libs/wingsdk/src/target-sim/bucket.ts +++ b/libs/wingsdk/src/target-sim/bucket.ts @@ -1,5 +1,6 @@ import { join } from "path"; import { Construct } from "constructs"; +import { Policy } from "./policy"; import { ISimulatorResource } from "./resource"; import { BucketSchema } from "./schema-resources"; import { simulatorHandleToken } from "./tokens"; @@ -16,10 +17,13 @@ import { IInflightHost } from "../std"; export class Bucket extends cloud.Bucket implements ISimulatorResource { private readonly public: boolean; private readonly initialObjects: Record = {}; + private readonly policy: Policy; + constructor(scope: Construct, id: string, props: cloud.BucketProps = {}) { super(scope, id, props); this.public = props.public ?? false; + this.policy = new Policy(this, "Policy", { principal: this }); } /** @internal */ @@ -41,6 +45,7 @@ export class Bucket extends cloud.Bucket implements ISimulatorResource { cloud.BucketInflightMethods.RENAME, ]; } + /** * Iterates over the topics and supply their sim handler * @returns an object of Bucket event types (keys) and their topic handlers (values) @@ -59,6 +64,46 @@ export class Bucket extends cloud.Bucket implements ISimulatorResource { this.initialObjects[key] = body; } + public onCreate( + fn: cloud.IBucketEventHandler, + opts?: cloud.BucketOnCreateOptions | undefined + ): void { + super.onCreate(fn, opts); + const topic = this.getTopic(cloud.BucketEventType.CREATE); + this.policy.addStatement(topic, cloud.TopicInflightMethods.PUBLISH); + } + + public onDelete( + fn: cloud.IBucketEventHandler, + opts?: cloud.BucketOnDeleteOptions | undefined + ): void { + super.onDelete(fn, opts); + const topic = this.getTopic(cloud.BucketEventType.DELETE); + this.policy.addStatement(topic, cloud.TopicInflightMethods.PUBLISH); + } + + public onUpdate( + fn: cloud.IBucketEventHandler, + opts?: cloud.BucketOnUpdateOptions | undefined + ): void { + super.onUpdate(fn, opts); + const topic = this.getTopic(cloud.BucketEventType.UPDATE); + this.policy.addStatement(topic, cloud.TopicInflightMethods.PUBLISH); + } + + public onEvent( + fn: cloud.IBucketEventHandler, + opts?: cloud.BucketOnEventOptions + ): void { + super.onEvent(fn, opts); + const createTopic = this.getTopic(cloud.BucketEventType.CREATE); + this.policy.addStatement(createTopic, cloud.TopicInflightMethods.PUBLISH); + const deleteTopic = this.getTopic(cloud.BucketEventType.DELETE); + this.policy.addStatement(deleteTopic, cloud.TopicInflightMethods.PUBLISH); + const updateTopic = this.getTopic(cloud.BucketEventType.UPDATE); + this.policy.addStatement(updateTopic, cloud.TopicInflightMethods.PUBLISH); + } + protected eventHandlerLocation(): string { return join(__dirname, "bucket.onevent.inflight.js"); } @@ -79,7 +124,7 @@ export class Bucket extends cloud.Bucket implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host); + bindSimulatorResource(__filename, this, host, ops); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/container.inflight.ts b/libs/wingsdk/src/target-sim/container.inflight.ts index 2edab95d93c..b8df58b31f5 100644 --- a/libs/wingsdk/src/target-sim/container.inflight.ts +++ b/libs/wingsdk/src/target-sim/container.inflight.ts @@ -12,27 +12,23 @@ import { Util } from "../util"; export class Container implements IContainerClient, ISimulatorResourceInstance { private readonly imageTag: string; private readonly containerName: string; + private _context: ISimulatorContext | undefined; - public constructor( - private readonly props: ContainerSchema["props"], - private readonly context: ISimulatorContext - ) { + public constructor(private readonly props: ContainerSchema["props"]) { this.imageTag = props.imageTag; this.containerName = `wing-container-${Util.ulid()}`; } - private log(message: string) { - this.context.addTrace({ - data: { message }, - sourcePath: this.context.resourcePath, - sourceType: "container", - timestamp: new Date().toISOString(), - type: TraceType.RESOURCE, //system messages that will be displayed on debug mode only - }); + private get context(): ISimulatorContext { + if (!this._context) { + throw new Error("Cannot access context during class construction"); + } + return this._context; } - public async init(): Promise { + public async init(context: ISimulatorContext): Promise { + this._context = context; // if this a reference to a local directory, build the image from a docker file if (isPath(this.props.image)) { // check if the image is already built @@ -134,6 +130,16 @@ export class Container implements IContainerClient, ISimulatorResourceInstance { public async plan() { return UpdatePlan.AUTO; } + + private log(message: string) { + this.context.addTrace({ + data: { message }, + sourcePath: this.context.resourcePath, + sourceType: "container", + timestamp: new Date().toISOString(), + type: TraceType.RESOURCE, + }); + } } async function waitUntil(predicate: () => Promise) { diff --git a/libs/wingsdk/src/target-sim/container.ts b/libs/wingsdk/src/target-sim/container.ts index 947553686de..af4022f5392 100644 --- a/libs/wingsdk/src/target-sim/container.ts +++ b/libs/wingsdk/src/target-sim/container.ts @@ -119,7 +119,7 @@ export class Container extends Resource implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host); + bindSimulatorResource(__filename, this, host, ops); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/counter.inflight.ts b/libs/wingsdk/src/target-sim/counter.inflight.ts index 3e52273cb8a..d4ef6ce46de 100644 --- a/libs/wingsdk/src/target-sim/counter.inflight.ts +++ b/libs/wingsdk/src/target-sim/counter.inflight.ts @@ -14,18 +14,22 @@ const VALUES_FILENAME = "values.json"; export class Counter implements ICounterClient, ISimulatorResourceInstance { private values: Map; private initial: number; - private readonly context: ISimulatorContext; + private _context: ISimulatorContext | undefined; - public constructor( - props: CounterSchema["props"], - context: ISimulatorContext - ) { + public constructor(props: CounterSchema["props"]) { this.initial = props.initial ?? 0; this.values = new Map().set("default", this.initial); - this.context = context; } - public async init(): Promise { + private get context(): ISimulatorContext { + if (!this._context) { + throw new Error("Cannot access context during class construction"); + } + return this._context; + } + + public async init(context: ISimulatorContext): Promise { + this._context = context; const valuesFile = join(this.context.statedir, VALUES_FILENAME); const valueFilesExists = await exists(valuesFile); if (valueFilesExists) { diff --git a/libs/wingsdk/src/target-sim/counter.ts b/libs/wingsdk/src/target-sim/counter.ts index a70abfabdf6..0c9c15f5b9e 100644 --- a/libs/wingsdk/src/target-sim/counter.ts +++ b/libs/wingsdk/src/target-sim/counter.ts @@ -43,7 +43,7 @@ export class Counter extends cloud.Counter implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host); + bindSimulatorResource(__filename, this, host, ops); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/domain.inflight.ts b/libs/wingsdk/src/target-sim/domain.inflight.ts index 22aa307a33a..b04c0ae80de 100644 --- a/libs/wingsdk/src/target-sim/domain.inflight.ts +++ b/libs/wingsdk/src/target-sim/domain.inflight.ts @@ -7,8 +7,8 @@ import { } from "../simulator"; export class Domain implements IDomainClient, ISimulatorResourceInstance { - constructor(_props: DomainSchema["props"], _context: ISimulatorContext) {} - public async init(): Promise> { + constructor(_props: DomainSchema["props"]) {} + public async init(_context: ISimulatorContext): Promise> { return {}; } diff --git a/libs/wingsdk/src/target-sim/endpoint.inflight.ts b/libs/wingsdk/src/target-sim/endpoint.inflight.ts index 6b6df4eaea3..fc3188c635a 100644 --- a/libs/wingsdk/src/target-sim/endpoint.inflight.ts +++ b/libs/wingsdk/src/target-sim/endpoint.inflight.ts @@ -29,11 +29,19 @@ export class Endpoint implements IEndpointClient, ISimulatorResourceInstance { private connectResponse?: ConnectResponse; private lastSubdomain?: string; private status: EndpointExposeStatus = "disconnected"; - constructor( - private readonly _props: EndpointSchema["props"], - private readonly _context: ISimulatorContext - ) {} - public async init(): Promise { + private _context: ISimulatorContext | undefined; + + constructor(private readonly _props: EndpointSchema["props"]) {} + + private get context(): ISimulatorContext { + if (!this._context) { + throw new Error("Cannot access context during class construction"); + } + return this._context; + } + + public async init(context: ISimulatorContext): Promise { + this._context = context; const state: StateFileContents = await this.loadState(); if (state.subdomain) { await this.connect(state.subdomain); @@ -81,11 +89,11 @@ export class Endpoint implements IEndpointClient, ISimulatorResourceInstance { private async loadState(): Promise { const stateFileExists = await exists( - join(this._context.statedir, STATE_FILENAME) + join(this.context.statedir, STATE_FILENAME) ); if (stateFileExists) { const stateFileContents = await readFile( - join(this._context.statedir, STATE_FILENAME), + join(this.context.statedir, STATE_FILENAME), "utf-8" ); return JSON.parse(stateFileContents); @@ -96,14 +104,14 @@ export class Endpoint implements IEndpointClient, ISimulatorResourceInstance { private async saveState(state: StateFileContents): Promise { writeFileSync( - join(this._context.statedir, STATE_FILENAME), + join(this.context.statedir, STATE_FILENAME), JSON.stringify(state) ); } private async connect(subdomain?: string) { try { - await this._context.withTrace({ + await this.context.withTrace({ message: `Creating tunnel for endpoint. ${ subdomain ? `Using subdomain: ${subdomain}` : "" }`, diff --git a/libs/wingsdk/src/target-sim/event-mapping.inflight.ts b/libs/wingsdk/src/target-sim/event-mapping.inflight.ts index c0c2b19956f..d1b7239405f 100644 --- a/libs/wingsdk/src/target-sim/event-mapping.inflight.ts +++ b/libs/wingsdk/src/target-sim/event-mapping.inflight.ts @@ -3,34 +3,47 @@ import { EventMappingAttributes, EventMappingSchema, EventSubscription, - FunctionHandle, - PublisherHandle, + ResourceHandle, } from "./schema-resources"; import { ISimulatorContext } from "../simulator"; import { ISimulatorResourceInstance, UpdatePlan } from "../simulator/simulator"; export class EventMapping implements ISimulatorResourceInstance { - private readonly publisher: PublisherHandle; - private readonly subscriber: FunctionHandle; + private readonly publisher: ResourceHandle; + private readonly subscriber: ResourceHandle; private readonly eventSubscription: EventSubscription; - private readonly context: ISimulatorContext; + private _context: ISimulatorContext | undefined; - constructor(props: EventMappingSchema["props"], context: ISimulatorContext) { + constructor(props: EventMappingSchema["props"]) { this.publisher = props.publisher; this.subscriber = props.subscriber; this.eventSubscription = props.subscriptionProps; + } - this.context = context; + private get context(): ISimulatorContext { + if (!this._context) { + throw new Error("Cannot access context during class construction"); + } + return this._context; } - public async init(): Promise { - const client = this.context.getClient(this.publisher) as IEventPublisher; + public async init( + context: ISimulatorContext + ): Promise { + this._context = context; + const client = this.context.getClient( + this.publisher, + true + ) as IEventPublisher; await client.addEventSubscription(this.subscriber, this.eventSubscription); return {}; } public async cleanup(): Promise { - const client = this.context.getClient(this.publisher) as IEventPublisher; + const client = this.context.getClient( + this.publisher, + true + ) as IEventPublisher; await client.removeEventSubscription(this.subscriber); } diff --git a/libs/wingsdk/src/target-sim/event-mapping.ts b/libs/wingsdk/src/target-sim/event-mapping.ts index b2e7770523d..4c907613698 100644 --- a/libs/wingsdk/src/target-sim/event-mapping.ts +++ b/libs/wingsdk/src/target-sim/event-mapping.ts @@ -3,7 +3,7 @@ import { ISimulatorResource } from "./resource"; import { EventMappingSchema, EventSubscription, - FunctionHandle, + ResourceHandle, } from "./schema-resources"; import { simulatorHandleToken } from "./tokens"; import { bindSimulatorResource, makeSimulatorJsClient } from "./util"; @@ -24,7 +24,7 @@ export interface IEventPublisher extends ISimulatorResourceInstance { * @param subscriptionProps additional subscription properties */ addEventSubscription: ( - subscriber: FunctionHandle, + subscriber: ResourceHandle, subscriptionProps: EventSubscription ) => Promise; @@ -33,7 +33,7 @@ export interface IEventPublisher extends ISimulatorResourceInstance { * @param subscriber the subscriber function * @param subscriptionProps additional subscription properties */ - removeEventSubscription: (subscriber: FunctionHandle) => Promise; + removeEventSubscription: (subscriber: ResourceHandle) => Promise; } export const EVENT_MAPPING_FQN = fqnForType("sim.EventMapping"); @@ -87,7 +87,7 @@ export class EventMapping extends Resource implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host); + bindSimulatorResource(__filename, this, host, ops); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/function.inflight.ts b/libs/wingsdk/src/target-sim/function.inflight.ts index b4d0258f3c4..62cd4440af3 100644 --- a/libs/wingsdk/src/target-sim/function.inflight.ts +++ b/libs/wingsdk/src/target-sim/function.inflight.ts @@ -11,29 +11,37 @@ import { import { TraceType } from "../std"; export class Function implements IFunctionClient, ISimulatorResourceInstance { - private readonly originalFile: string; + private readonly sourceCodeFile: string; + private originalFile!: string; private bundle: Bundle | undefined; private readonly env: Record; - private readonly context: ISimulatorContext; + private _context: ISimulatorContext | undefined; private readonly timeout: number; private readonly maxWorkers: number; private readonly workers = new Array(); - private createBundlePromise: Promise; + private createBundlePromise!: Promise; - constructor(props: FunctionSchema["props"], context: ISimulatorContext) { + constructor(props: FunctionSchema["props"]) { + this.sourceCodeFile = props.sourceCodeFile; if (props.sourceCodeLanguage !== "javascript") { throw new Error("Only JavaScript is supported"); } - this.originalFile = path.resolve(context.simdir, props.sourceCodeFile); this.env = props.environmentVariables ?? {}; - this.context = context; this.timeout = props.timeout; this.maxWorkers = props.concurrency; + } - this.createBundlePromise = this.createBundle(); + private get context(): ISimulatorContext { + if (!this._context) { + throw new Error("Cannot access context during class construction"); + } + return this._context; } - public async init(): Promise { + public async init(context: ISimulatorContext): Promise { + this._context = context; + this.originalFile = path.resolve(context.simdir, this.sourceCodeFile); + this.createBundlePromise = this.createBundle(); return {}; } @@ -83,12 +91,14 @@ export class Function implements IFunctionClient, ISimulatorResourceInstance { ); } process.nextTick(() => { - // If the call fails, we log the error and continue since we've already - // handed control back to the caller. void worker.call("handler", payload).catch((e) => { + // If the call fails, we log the error and continue since we've already + // handed control back to the caller. this.context.addTrace({ data: { - message: `InvokeAsync (payload=${JSON.stringify(payload)}).`, + message: `InvokeAsync (payload=${JSON.stringify( + payload + )}) failure.`, status: "failure", error: e, }, @@ -143,6 +153,7 @@ export class Function implements IFunctionClient, ISimulatorResourceInstance { return new Sandbox(this.bundle.entrypointPath, { env: { ...this.env, + WING_SIMULATOR_CALLER: this.context.resourceHandle, WING_SIMULATOR_URL: this.context.serverUrl, }, timeout: this.timeout, diff --git a/libs/wingsdk/src/target-sim/function.ts b/libs/wingsdk/src/target-sim/function.ts index 3a77d1d7951..b106cf732a4 100644 --- a/libs/wingsdk/src/target-sim/function.ts +++ b/libs/wingsdk/src/target-sim/function.ts @@ -1,12 +1,13 @@ import { relative } from "path"; import { Construct } from "constructs"; -import { ISimulatorResource } from "./resource"; +import { Policy } from "./policy"; +import { ISimulatorInflightHost, ISimulatorResource } from "./resource"; import { FunctionSchema } from "./schema-resources"; import { bindSimulatorResource, makeSimulatorJsClient } from "./util"; import * as cloud from "../cloud"; import { App } from "../core"; import { BaseResourceSchema } from "../simulator/simulator"; -import { IInflightHost } from "../std"; +import { IInflightHost, IResource } from "../std"; import { Duration } from "../std/duration"; export const ENV_WING_SIM_INFLIGHT_RESOURCE_PATH = @@ -19,9 +20,15 @@ export const ENV_WING_SIM_INFLIGHT_RESOURCE_TYPE = * * @inflight `@winglang/sdk.cloud.IFunctionClient` */ -export class Function extends cloud.Function implements ISimulatorResource { +export class Function + extends cloud.Function + implements ISimulatorResource, ISimulatorInflightHost +{ private readonly timeout: Duration; private readonly concurrency: number; + public readonly policy: Policy; + public _liftMap = undefined; + constructor( scope: Construct, id: string, @@ -33,6 +40,11 @@ export class Function extends cloud.Function implements ISimulatorResource { // props.memory is unused since we are not simulating it this.timeout = props.timeout ?? Duration.fromMinutes(1); this.concurrency = props.concurrency ?? 100; + this.policy = new Policy(this, "Policy", { principal: this }); + } + + public addPermission(resource: IResource, op: string): void { + this.policy.addStatement(resource, op); } public toSimulator(): BaseResourceSchema { @@ -62,7 +74,7 @@ export class Function extends cloud.Function implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host); + bindSimulatorResource(__filename, this, host, ops); super.onLift(host, ops); } @@ -71,3 +83,10 @@ export class Function extends cloud.Function implements ISimulatorResource { return makeSimulatorJsClient(__filename, this); } } + +/** + * Simulator-specific inflight methods for `cloud.Function`. + */ +export enum FunctionInflightMethods { + HAS_AVAILABLE_WORKERS = "hasAvailableWorkers", +} diff --git a/libs/wingsdk/src/target-sim/index.ts b/libs/wingsdk/src/target-sim/index.ts index dd8a337a355..7b8fd8ebf68 100644 --- a/libs/wingsdk/src/target-sim/index.ts +++ b/libs/wingsdk/src/target-sim/index.ts @@ -1,4 +1,5 @@ // only include here types that we want to expose in userland export * from "./container"; +export * from "./policy"; export * from "./resource"; export * from "./state"; diff --git a/libs/wingsdk/src/target-sim/on-deploy.inflight.ts b/libs/wingsdk/src/target-sim/on-deploy.inflight.ts index 8184d522013..2e3fe927cc6 100644 --- a/libs/wingsdk/src/target-sim/on-deploy.inflight.ts +++ b/libs/wingsdk/src/target-sim/on-deploy.inflight.ts @@ -8,21 +8,17 @@ import { export class OnDeploy implements IOnDeployClient, ISimulatorResourceInstance { private functionHandle: string; - private readonly context: ISimulatorContext; - public constructor( - props: OnDeploySchema["props"], - context: ISimulatorContext - ) { + public constructor(props: OnDeploySchema["props"]) { this.functionHandle = props.functionHandle; - this.context = context; } - public async init(): Promise { - const functionClient = this.context.getClient( - this.functionHandle + public async init(context: ISimulatorContext): Promise { + const functionClient = context.getClient( + this.functionHandle, + true ) as IFunctionClient; - await this.context.withTrace({ + await context.withTrace({ message: "OnDeploy invoked.", activity: async () => { return functionClient.invoke(); @@ -36,6 +32,7 @@ export class OnDeploy implements IOnDeployClient, ISimulatorResourceInstance { public async save(): Promise {} public async plan() { - return UpdatePlan.AUTO; + // OnDeploy runs on every deployment, so always replace + return UpdatePlan.REPLACE; } } diff --git a/libs/wingsdk/src/target-sim/on-deploy.ts b/libs/wingsdk/src/target-sim/on-deploy.ts index 6ce6c767624..8d55e3ff565 100644 --- a/libs/wingsdk/src/target-sim/on-deploy.ts +++ b/libs/wingsdk/src/target-sim/on-deploy.ts @@ -1,4 +1,5 @@ import { Construct } from "constructs"; +import { Function as SimFunction } from "./function"; import { OnDeploySchema } from "./schema-resources"; import { simulatorHandleToken } from "./tokens"; import { bindSimulatorResource, makeSimulatorJsClient } from "./util"; @@ -20,6 +21,7 @@ export class OnDeploy extends cloud.OnDeploy { Node.of(this.fn).sourceModule = SDK_SOURCE_MODULE; this.node.addDependency(this.fn); + this.node.addDependency((this.fn as SimFunction).policy); for (const c of props.executeBefore ?? []) { c.node.addDependency(this); @@ -44,7 +46,7 @@ export class OnDeploy extends cloud.OnDeploy { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host); + bindSimulatorResource(__filename, this, host, ops); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/policy.inflight.ts b/libs/wingsdk/src/target-sim/policy.inflight.ts new file mode 100644 index 00000000000..7c05110d0f0 --- /dev/null +++ b/libs/wingsdk/src/target-sim/policy.inflight.ts @@ -0,0 +1,22 @@ +import { IPolicyClient } from "./policy"; +import { PolicySchema } from "./schema-resources"; +import { + ISimulatorContext, + ISimulatorResourceInstance, + UpdatePlan, +} from "../simulator"; + +export class Policy implements IPolicyClient, ISimulatorResourceInstance { + constructor(_props: PolicySchema["props"]) {} + public async init(_context: ISimulatorContext): Promise> { + return {}; + } + + public async cleanup(): Promise {} + + public async save(): Promise {} + + public async plan(): Promise { + return UpdatePlan.AUTO; + } +} diff --git a/libs/wingsdk/src/target-sim/policy.ts b/libs/wingsdk/src/target-sim/policy.ts new file mode 100644 index 00000000000..7c264237e48 --- /dev/null +++ b/libs/wingsdk/src/target-sim/policy.ts @@ -0,0 +1,72 @@ +import { Construct } from "constructs"; +import { ISimulatorResource } from "./resource"; +import { PolicySchema, PolicyStatement } from "./schema-resources"; +import { simulatorHandleToken } from "./tokens"; +import { fqnForType } from "../constants"; +import { BaseResourceSchema } from "../simulator"; +import { IResource, Node, Resource } from "../std"; + +export const POLICY_FQN = fqnForType("sim.Policy"); + +/** + * Options for `sim.Policy`. + */ +export interface PolicyProps { + /** + * The resource to which the policy is attached. + */ + readonly principal: IResource; +} + +/** + * Implementation of `sim.Policy`. + */ +export class Policy extends Resource implements ISimulatorResource { + private readonly statements: Map> = new Map(); + private readonly principal: IResource; + constructor(scope: Construct, id: string, props: PolicyProps) { + super(scope, id); + this.principal = props.principal; + Node.of(this).hidden = true; + Node.of(this).title = "Policy"; + Node.of(this).description = "A simulated resource policy"; + } + + /** + * Adds a statement to the policy. + */ + public addStatement(resource: IResource, op: string): void { + if (!this.statements.has(resource)) { + this.statements.set(resource, new Set()); + } + this.statements.get(resource)!.add(op); + } + + public toSimulator(): BaseResourceSchema { + const statements: Array = []; + for (const [resource, ops] of this.statements.entries()) { + for (const op of ops) { + statements.push({ + resourceHandle: simulatorHandleToken(resource), + operation: op, + }); + } + } + const schema: PolicySchema = { + type: POLICY_FQN, + path: this.node.path, + addr: this.node.addr, + props: { + principal: simulatorHandleToken(this.principal), + statements, + }, + attrs: {} as any, + }; + return schema; + } +} + +/** + * Inflight interface for `Policy`. + */ +export interface IPolicyClient {} diff --git a/libs/wingsdk/src/target-sim/queue.inflight.ts b/libs/wingsdk/src/target-sim/queue.inflight.ts index 3ab1683a2e9..ecd19aa7659 100644 --- a/libs/wingsdk/src/target-sim/queue.inflight.ts +++ b/libs/wingsdk/src/target-sim/queue.inflight.ts @@ -5,7 +5,7 @@ import { QueueSchema, QueueSubscriber, EventSubscription, - FunctionHandle, + ResourceHandle, } from "./schema-resources"; import { IFunctionClient, IQueueClient, QUEUE_FQN } from "../cloud"; import { @@ -21,18 +21,25 @@ export class Queue private readonly messages = new Array(); private readonly subscribers = new Array(); private readonly processLoop: LoopController; - private readonly context: ISimulatorContext; + private _context: ISimulatorContext | undefined; private readonly timeoutSeconds: number; private readonly retentionPeriod: number; - constructor(props: QueueSchema["props"], context: ISimulatorContext) { + constructor(props: QueueSchema["props"]) { this.timeoutSeconds = props.timeout; this.retentionPeriod = props.retentionPeriod; this.processLoop = runEvery(100, async () => this.processMessages()); // every 0.1 seconds - this.context = context; } - public async init(): Promise { + private get context(): ISimulatorContext { + if (!this._context) { + throw new Error("Cannot access context during class construction"); + } + return this._context; + } + + public async init(context: ISimulatorContext): Promise { + this._context = context; return {}; } @@ -47,7 +54,7 @@ export class Queue } public async addEventSubscription( - subscriber: FunctionHandle, + subscriber: ResourceHandle, subscriptionProps: EventSubscription ): Promise { const s = { @@ -58,7 +65,7 @@ export class Queue } public async removeEventSubscription( - subscriber: FunctionHandle + subscriber: ResourceHandle ): Promise { const index = this.subscribers.findIndex( (s) => s.functionHandle === subscriber diff --git a/libs/wingsdk/src/target-sim/queue.ts b/libs/wingsdk/src/target-sim/queue.ts index 632ea5dba0e..52077d72a30 100644 --- a/libs/wingsdk/src/target-sim/queue.ts +++ b/libs/wingsdk/src/target-sim/queue.ts @@ -2,7 +2,11 @@ import { join } from "path"; import { Construct } from "constructs"; import { App } from "./app"; import { EventMapping } from "./event-mapping"; -import { Function } from "./function"; +import { + Function, + FunctionInflightMethods as SimFunctionInflightMethods, +} from "./function"; +import { Policy } from "./policy"; import { ISimulatorResource } from "./resource"; import { QueueSchema } from "./schema-resources"; import { bindSimulatorResource, makeSimulatorJsClient } from "./util"; @@ -20,6 +24,7 @@ import { Duration, IInflightHost, Node, SDK_SOURCE_MODULE } from "../std"; export class Queue extends cloud.Queue implements ISimulatorResource { private readonly timeout: Duration; private readonly retentionPeriod: Duration; + private readonly policy: Policy; constructor(scope: Construct, id: string, props: cloud.QueueProps = {}) { super(scope, id, props); @@ -42,6 +47,8 @@ export class Queue extends cloud.Queue implements ISimulatorResource { "Retention period must be greater than or equal to timeout" ); } + + this.policy = new Policy(this, "Policy", { principal: this }); } /** @internal */ @@ -109,6 +116,12 @@ export class Queue extends cloud.Queue implements ISimulatorResource { name: "setConsumer()", }); + this.policy.addStatement(fn, cloud.FunctionInflightMethods.INVOKE); + this.policy.addStatement( + fn, + SimFunctionInflightMethods.HAS_AVAILABLE_WORKERS + ); + return fn; } @@ -127,7 +140,7 @@ export class Queue extends cloud.Queue implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host); + bindSimulatorResource(__filename, this, host, ops); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/react-app.inflight.ts b/libs/wingsdk/src/target-sim/react-app.inflight.ts index c0fe6c181bf..ecbea6d853a 100644 --- a/libs/wingsdk/src/target-sim/react-app.inflight.ts +++ b/libs/wingsdk/src/target-sim/react-app.inflight.ts @@ -12,7 +12,7 @@ import { import { TraceType } from "../std"; export class ReactApp implements IReactAppClient, ISimulatorResourceInstance { - private readonly context: ISimulatorContext; + private _context: ISimulatorContext | undefined; private readonly startCommand: string; private readonly path: string; private readonly environmentVariables: Record; @@ -21,8 +21,7 @@ export class ReactApp implements IReactAppClient, ISimulatorResourceInstance { private childProcess?: ChildProcess; private url: string; - constructor(props: ReactAppSchema["props"], context: ISimulatorContext) { - this.context = context; + constructor(props: ReactAppSchema["props"]) { this.path = props.path; this.startCommand = props.startCommand; this.environmentVariables = props.environmentVariables; @@ -31,7 +30,15 @@ export class ReactApp implements IReactAppClient, ISimulatorResourceInstance { this.url = props.url; } - public async init(): Promise { + private get context(): ISimulatorContext { + if (!this._context) { + throw new Error("Cannot access context during class construction"); + } + return this._context; + } + + public async init(context: ISimulatorContext): Promise { + this._context = context; this.addTrace(`Executing start command: ${this.startCommand}`); writeFileSync( diff --git a/libs/wingsdk/src/target-sim/react-app.ts b/libs/wingsdk/src/target-sim/react-app.ts index 825428ec240..78c96c77f46 100644 --- a/libs/wingsdk/src/target-sim/react-app.ts +++ b/libs/wingsdk/src/target-sim/react-app.ts @@ -61,7 +61,7 @@ export class ReactApp extends ex.ReactApp implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host); + bindSimulatorResource(__filename, this, host, ops); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/redis.inflight.ts b/libs/wingsdk/src/target-sim/redis.inflight.ts index b9d06b54cd8..7fc42111c57 100644 --- a/libs/wingsdk/src/target-sim/redis.inflight.ts +++ b/libs/wingsdk/src/target-sim/redis.inflight.ts @@ -15,14 +15,11 @@ export class Redis private connection?: IoRedis; private isCleanedUp = false; - public constructor( - private readonly props: RedisSchema["props"], - _context: ISimulatorContext - ) { + public constructor(private readonly props: RedisSchema["props"]) { super(); } - public async init(): Promise { + public async init(_context: ISimulatorContext): Promise { try { if (this.isCleanedUp) { return {}; diff --git a/libs/wingsdk/src/target-sim/redis.ts b/libs/wingsdk/src/target-sim/redis.ts index 908ee7f9ccb..a2d3c6fe886 100644 --- a/libs/wingsdk/src/target-sim/redis.ts +++ b/libs/wingsdk/src/target-sim/redis.ts @@ -50,7 +50,7 @@ export class Redis extends ex.Redis implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host); + bindSimulatorResource(__filename, this, host, ops); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/resource.ts b/libs/wingsdk/src/target-sim/resource.ts index d3dfd03d7de..2c861f5dc76 100644 --- a/libs/wingsdk/src/target-sim/resource.ts +++ b/libs/wingsdk/src/target-sim/resource.ts @@ -1,9 +1,29 @@ import { BaseResourceSchema } from "../simulator/simulator"; -import { IResource } from "../std"; +import { IInflightHost, IResource } from "../std"; /** - * Interfaces shared by all polycon implementations (preflight classes) - * targeting the simulator. + * Interfaces shared by all preflight classes that host inflight code. + */ +export interface ISimulatorInflightHost extends IInflightHost { + /** + * Add a simulated permission to this inflight host. + * @param resource The resource to add + * @param op The action to add + */ + addPermission(resource: IResource, op: string): void; +} + +export function isSimulatorInflightHost( + obj: any +): obj is ISimulatorInflightHost { + return ( + typeof obj == "object" && + typeof (obj as ISimulatorInflightHost).addPermission === "function" + ); +} + +/** + * Interfaces shared by all preflight classes targeting the simulator. */ export interface ISimulatorResource extends IResource { /** diff --git a/libs/wingsdk/src/target-sim/schedule.inflight.ts b/libs/wingsdk/src/target-sim/schedule.inflight.ts index b2bade5f30d..5c44bebbacb 100644 --- a/libs/wingsdk/src/target-sim/schedule.inflight.ts +++ b/libs/wingsdk/src/target-sim/schedule.inflight.ts @@ -17,17 +17,23 @@ import { TraceType } from "../std"; export class Schedule implements IScheduleClient, ISimulatorResourceInstance, IEventPublisher { - private readonly context: ISimulatorContext; + private _context: ISimulatorContext | undefined; private tasks = new Array(); private interval: CronExpression; private intervalTimeout?: NodeJS.Timeout; - constructor(props: ScheduleSchema["props"], context: ISimulatorContext) { - this.context = context; + constructor(props: ScheduleSchema["props"]) { this.interval = parseExpression(props.cronExpression, { utc: true }); this.scheduleFunction(); } + private get context(): ISimulatorContext { + if (!this._context) { + throw new Error("Cannot access context during class construction"); + } + return this._context; + } + // Calculate the delay for the next execution private nextDelay(interval: CronExpression) { return interval.next().toDate().getTime() - Date.now(); @@ -41,7 +47,8 @@ export class Schedule }, this.nextDelay(this.interval)); } - public async init(): Promise { + public async init(context: ISimulatorContext): Promise { + this._context = context; return {}; } diff --git a/libs/wingsdk/src/target-sim/schedule.ts b/libs/wingsdk/src/target-sim/schedule.ts index 31289df757a..807f24b5c74 100644 --- a/libs/wingsdk/src/target-sim/schedule.ts +++ b/libs/wingsdk/src/target-sim/schedule.ts @@ -3,6 +3,7 @@ import { Construct } from "constructs"; import { App } from "./app"; import { EventMapping } from "./event-mapping"; import { Function } from "./function"; +import { Policy } from "./policy"; import { ISimulatorResource } from "./resource"; import { ScheduleSchema } from "./schema-resources"; import { @@ -22,12 +23,14 @@ import { IInflightHost, Node, SDK_SOURCE_MODULE } from "../std"; */ export class Schedule extends cloud.Schedule implements ISimulatorResource { private readonly cronExpression: string; + private readonly policy: Policy; constructor(scope: Construct, id: string, props: cloud.ScheduleProps = {}) { super(scope, id, props); const { rate, cron } = props; this.cronExpression = cron ?? convertDurationToCronExpression(rate!); + this.policy = new Policy(this, "Policy", { principal: this }); } public onTick( @@ -60,6 +63,7 @@ export class Schedule extends cloud.Schedule implements ISimulatorResource { target: fn, name: "onTick()", }); + this.policy.addStatement(fn, cloud.FunctionInflightMethods.INVOKE); return fn; } @@ -83,7 +87,7 @@ export class Schedule extends cloud.Schedule implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host); + bindSimulatorResource(__filename, this, host, ops); super.onLift(host, ops); } } diff --git a/libs/wingsdk/src/target-sim/schema-resources.ts b/libs/wingsdk/src/target-sim/schema-resources.ts index 420843f531a..6da7f402ace 100644 --- a/libs/wingsdk/src/target-sim/schema-resources.ts +++ b/libs/wingsdk/src/target-sim/schema-resources.ts @@ -1,5 +1,7 @@ import { SIM_CONTAINER_FQN } from "./container"; import { EVENT_MAPPING_FQN } from "./event-mapping"; +import { POLICY_FQN } from "./policy"; +import { SERVICE_HELPER_FQN } from "./service"; import { STATE_FQN } from "./state"; import { API_FQN, @@ -26,8 +28,7 @@ import { } from "../simulator/simulator"; import { Json, TEST_RUNNER_FQN } from "../std"; -export type FunctionHandle = string; -export type PublisherHandle = string; +export type ResourceHandle = string; /** Schema for cloud.Api */ export interface ApiSchema extends BaseResourceSchema { @@ -95,8 +96,6 @@ export interface ServiceSchema extends BaseResourceSchema { readonly props: { /** The source code of the service */ readonly sourceCodeFile: string; - /** Whether the service should start when sim starts */ - readonly autoStart: boolean; /** A map of environment variables to run the function with. */ readonly environmentVariables: Record; }; @@ -105,6 +104,20 @@ export interface ServiceSchema extends BaseResourceSchema { /** Runtime attributes for cloud.Service */ export interface ServiceAttributes {} +/** Schema for sim.ServiceHelper */ +export interface ServiceHelperSchema extends BaseResourceSchema { + readonly type: typeof SERVICE_HELPER_FQN; + readonly props: { + /** The service. */ + readonly service: ResourceHandle; + /** Whether to auto-start the service */ + readonly autoStart: boolean; + }; +} + +/** Runtime attributes for sim.ServiceHelper */ +export interface ServiceHelperAttributes {} + /** Runtime attributes for cloud.Schedule */ export interface ScheduleAttributes {} @@ -120,7 +133,7 @@ export interface ScheduleSchema extends BaseResourceSchema { /** Schema for cloud.Queue.props.subscribers */ export interface ScheduleTask extends EventSubscription { /** Function that should be called. */ - readonly functionHandle: FunctionHandle; + readonly functionHandle: ResourceHandle; } export interface EventSubscription {} @@ -130,9 +143,9 @@ export interface EventMappingSchema extends BaseResourceSchema { readonly type: typeof EVENT_MAPPING_FQN; readonly props: { /** Function handle to call for subscriber */ - subscriber: FunctionHandle; + subscriber: ResourceHandle; /** Publisher handle of the event */ - publisher: PublisherHandle; + publisher: ResourceHandle; /** Additional properties of event subscription */ subscriptionProps: EventSubscription; }; @@ -147,7 +160,7 @@ export interface QueueAttributes {} /** Schema for cloud.Queue.props.subscribers */ export interface QueueSubscriber extends EventSubscription { /** Function that should be called. */ - readonly functionHandle: FunctionHandle; + readonly functionHandle: ResourceHandle; /** Maximum number of messages that will be batched together to the subscriber. */ readonly batchSize: number; } @@ -163,7 +176,7 @@ export interface TopicAttributes {} export interface TopicSubscriber extends EventSubscription { /** Function that should be called */ - readonly functionHandle: FunctionHandle; + readonly functionHandle: ResourceHandle; } /** Runtime attributes for cloud.Table */ @@ -213,7 +226,7 @@ export interface TestRunnerSchema extends BaseResourceSchema { readonly type: typeof TEST_RUNNER_FQN; readonly props: { /** A map from test functions to their handles. */ - readonly tests: Record; + readonly tests: Record; }; } @@ -288,7 +301,7 @@ export interface OnDeploySchema extends BaseResourceSchema { readonly type: typeof ON_DEPLOY_FQN; readonly props: { /** The function to run on deploy. */ - readonly functionHandle: FunctionHandle; + readonly functionHandle: ResourceHandle; }; } @@ -335,6 +348,9 @@ export interface EndpointSchema extends BaseResourceSchema { readonly attrs: EndpointAttributes & BaseResourceAttributes; } +/** Runtime attributes for sim.Policy */ +export interface PolicyAttributes {} + /** Schema for sim.Container */ export interface ContainerSchema extends BaseResourceSchema { readonly type: typeof SIM_CONTAINER_FQN; @@ -351,3 +367,22 @@ export interface ContainerSchema extends BaseResourceSchema { /** Runtime attributes for sim.Container */ export interface ContainerAttributes {} + +/** Schema for sim.Policy */ +export interface PolicySchema extends BaseResourceSchema { + readonly type: typeof POLICY_FQN; + readonly props: PolicySchemaProps; + readonly attrs: PolicyAttributes & BaseResourceAttributes; +} + +export interface PolicySchemaProps { + /** The resource which the policy is attached to. */ + readonly principal: ResourceHandle; + /** The statements in the policy. */ + readonly statements: PolicyStatement[]; +} + +export interface PolicyStatement { + readonly operation: string; + readonly resourceHandle: ResourceHandle; +} diff --git a/libs/wingsdk/src/target-sim/secret.inflight.ts b/libs/wingsdk/src/target-sim/secret.inflight.ts index 02791e12cf6..d178a7bee69 100644 --- a/libs/wingsdk/src/target-sim/secret.inflight.ts +++ b/libs/wingsdk/src/target-sim/secret.inflight.ts @@ -11,13 +11,11 @@ import { import { Json, TraceType } from "../std"; export class Secret implements ISecretClient, ISimulatorResourceInstance { - private readonly context: ISimulatorContext; + private _context: ISimulatorContext | undefined; private readonly secretsFile: string; private readonly name: string; - constructor(props: SecretSchema["props"], context: ISimulatorContext) { - this.context = context; - + constructor(props: SecretSchema["props"]) { this.secretsFile = path.join(os.homedir(), ".wing", "secrets.json"); if (!fs.existsSync(this.secretsFile)) { throw new Error( @@ -28,7 +26,15 @@ export class Secret implements ISecretClient, ISimulatorResourceInstance { this.name = props.name; } - public async init(): Promise { + private get context(): ISimulatorContext { + if (!this._context) { + throw new Error("Cannot access context during class construction"); + } + return this._context; + } + + public async init(context: ISimulatorContext): Promise { + this._context = context; return {}; } diff --git a/libs/wingsdk/src/target-sim/secret.ts b/libs/wingsdk/src/target-sim/secret.ts index aeee0c16a7f..97b2a366bfd 100644 --- a/libs/wingsdk/src/target-sim/secret.ts +++ b/libs/wingsdk/src/target-sim/secret.ts @@ -23,7 +23,7 @@ export class Secret extends cloud.Secret implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host); + bindSimulatorResource(__filename, this, host, ops); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/service.inflight.ts b/libs/wingsdk/src/target-sim/service.inflight.ts index fc705431671..4c6ced2f889 100644 --- a/libs/wingsdk/src/target-sim/service.inflight.ts +++ b/libs/wingsdk/src/target-sim/service.inflight.ts @@ -1,5 +1,9 @@ import { resolve } from "path"; -import { ServiceAttributes, ServiceSchema } from "./schema-resources"; +import { + ServiceAttributes, + ServiceHelperSchema, + ServiceSchema, +} from "./schema-resources"; import { IServiceClient, SERVICE_FQN } from "../cloud"; import { Bundle } from "../shared/bundling"; import { Sandbox } from "../shared/sandbox"; @@ -11,38 +15,45 @@ import { import { TraceType } from "../std"; export class Service implements IServiceClient, ISimulatorResourceInstance { - private readonly context: ISimulatorContext; - private readonly originalFile: string; - private readonly autoStart: boolean; + private _context: ISimulatorContext | undefined; + private readonly sourceCodeFile: string; + private resolvedSourceCodeFile!: string; private sandbox: Sandbox | undefined; private bundle: Bundle | undefined; - private createBundlePromise: Promise; private running: boolean = false; private environmentVariables: Record; + private createBundlePromise!: Promise; - constructor(props: ServiceSchema["props"], context: ISimulatorContext) { - this.context = context; - this.originalFile = resolve(context.simdir, props.sourceCodeFile); - this.autoStart = props.autoStart; + constructor(props: ServiceSchema["props"]) { + this.sourceCodeFile = props.sourceCodeFile; this.environmentVariables = props.environmentVariables ?? {}; + } - this.createBundlePromise = this.createBundle(); + private get context(): ISimulatorContext { + if (!this._context) { + throw new Error("Cannot access context during class construction"); + } + return this._context; } private async createBundle(): Promise { - this.bundle = await Sandbox.createBundle(this.originalFile, (msg) => { - this.addTrace(msg); - }); + this.bundle = await Sandbox.createBundle( + this.resolvedSourceCodeFile, + (msg) => { + this.addTrace(msg); + } + ); } - public async init(): Promise { - if (this.autoStart) { - await this.start(); - } + public async init(context: ISimulatorContext): Promise { + this._context = context; + this.resolvedSourceCodeFile = resolve(context.simdir, this.sourceCodeFile); + this.createBundlePromise = this.createBundle(); return {}; } public async cleanup(): Promise { + await this.createBundlePromise; await this.stop(); } @@ -71,6 +82,7 @@ export class Service implements IServiceClient, ISimulatorResourceInstance { env: { ...this.environmentVariables, WING_SIMULATOR_URL: this.context.serverUrl, + WING_SIMULATOR_CALLER: this.context.resourceHandle, }, log: (internal, _level, message) => { this.addTrace(message, internal); @@ -97,7 +109,7 @@ export class Service implements IServiceClient, ISimulatorResourceInstance { await this.sandbox.call("stop"); await this.sandbox.cleanup(); } catch (e: any) { - this.addTrace(`Failed to stop service: ${e.message}`); + this.addTrace(`Failed to stop service: ${e.message} ${e.stack}`); } } @@ -115,3 +127,41 @@ export class Service implements IServiceClient, ISimulatorResourceInstance { }); } } + +export class ServiceHelper implements ISimulatorResourceInstance { + private readonly serviceHandle: string; + private readonly autoStart: boolean; + private _context: ISimulatorContext | undefined; + + public constructor(props: ServiceHelperSchema["props"]) { + this.serviceHandle = props.service; + this.autoStart = props.autoStart; + } + + private get context(): ISimulatorContext { + if (!this._context) { + throw new Error("Cannot access context during class construction"); + } + return this._context; + } + + public async init(context: ISimulatorContext): Promise { + this._context = context; + if (this.autoStart) { + const service = context.getClient(this.serviceHandle, true) as Service; + await service.start(); + } + return {}; + } + + public async cleanup(): Promise { + const service = this.context.getClient(this.serviceHandle, true) as Service; + await service.stop(); + } + + public async save(): Promise {} + + public async plan(): Promise { + return UpdatePlan.AUTO; + } +} diff --git a/libs/wingsdk/src/target-sim/service.ts b/libs/wingsdk/src/target-sim/service.ts index d2c21f26a2a..1269ab419f8 100644 --- a/libs/wingsdk/src/target-sim/service.ts +++ b/libs/wingsdk/src/target-sim/service.ts @@ -1,15 +1,22 @@ import { relative } from "path"; import { Construct } from "constructs"; -import { ISimulatorResource } from "./resource"; -import { ServiceSchema } from "./schema-resources"; +import { Policy } from "./policy"; +import { ISimulatorInflightHost, ISimulatorResource } from "./resource"; +import { ServiceHelperSchema, ServiceSchema } from "./schema-resources"; +import { simulatorHandleToken } from "./tokens"; import { bindSimulatorResource, makeSimulatorJsClient } from "./util"; import * as cloud from "../cloud"; +import { fqnForType } from "../constants"; import { App } from "../core"; import { BaseResourceSchema } from "../simulator"; -import { IInflightHost } from "../std"; +import { IInflightHost, IResource, Resource, Node } from "../std"; -export class Service extends cloud.Service implements ISimulatorResource { - private readonly autoStart: boolean; +export class Service + extends cloud.Service + implements ISimulatorResource, ISimulatorInflightHost +{ + public readonly policy: Policy; + public _liftMap = undefined; constructor( scope: Construct, @@ -18,7 +25,18 @@ export class Service extends cloud.Service implements ISimulatorResource { props: cloud.ServiceProps = {} ) { super(scope, id, handler, props); - this.autoStart = props.autoStart ?? true; + this.policy = new Policy(this, "Policy", { principal: this }); + + const helper = new ServiceHelper(this, "Helper", { + service: this, + autoStart: props.autoStart ?? true, + }); + helper.node.addDependency(this); + helper.node.addDependency(this.policy); + } + + public addPermission(resource: IResource, op: string): void { + this.policy.addStatement(resource, op); } public toSimulator(): BaseResourceSchema { @@ -29,7 +47,6 @@ export class Service extends cloud.Service implements ISimulatorResource { props: { environmentVariables: this.env, sourceCodeFile: relative(App.of(this).outdir, this.entrypoint), - autoStart: this.autoStart, }, attrs: {} as any, }; @@ -46,7 +63,7 @@ export class Service extends cloud.Service implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host); + bindSimulatorResource(__filename, this, host, ops); super.onLift(host, ops); } @@ -54,3 +71,51 @@ export class Service extends cloud.Service implements ISimulatorResource { return makeSimulatorJsClient(__filename, this); } } + +/** @internal */ +export const SERVICE_HELPER_FQN = fqnForType("sim.ServiceHelper"); + +/** @internal */ +export interface ServiceHelperProps { + readonly service: Service; + readonly autoStart: boolean; +} + +/** + * This is a helper resource that automatically starts the service after the + * service is created in the simulator and shuts it down when the simulator + * stops. + * + * Suppose a service puts an object in a bucket when it starts. The policy + * (sim.Policy) that grants the service bucket permissions only takes effect + * after the service is created. Because of this, the service needs to be + * started after both the service and the policy are created. Vice versa, the + * service needs to be stopped before the policy is deleted. + * + * @internal + */ +export class ServiceHelper extends Resource implements ISimulatorResource { + private readonly service: Service; + private readonly autoStart: boolean; + + constructor(scope: Construct, id: string, props: ServiceHelperProps) { + super(scope, id); + this.service = props.service; + this.autoStart = props.autoStart; + Node.of(this).hidden = true; + } + + public toSimulator(): BaseResourceSchema { + const schema: ServiceHelperSchema = { + type: SERVICE_HELPER_FQN, + path: this.node.path, + addr: this.node.addr, + props: { + service: simulatorHandleToken(this.service), + autoStart: this.autoStart, + }, + attrs: {} as any, + }; + return schema; + } +} diff --git a/libs/wingsdk/src/target-sim/state.inflight.ts b/libs/wingsdk/src/target-sim/state.inflight.ts index ceb4f946acd..0472e417740 100644 --- a/libs/wingsdk/src/target-sim/state.inflight.ts +++ b/libs/wingsdk/src/target-sim/state.inflight.ts @@ -8,11 +8,18 @@ import { import { Json } from "../std"; export class State implements IStateClient, ISimulatorResourceInstance { - constructor( - _props: StateSchema["props"], - private readonly context: ISimulatorContext - ) {} - public async init(): Promise> { + private _context: ISimulatorContext | undefined; + constructor(_props: StateSchema["props"]) {} + + private get context(): ISimulatorContext { + if (!this._context) { + throw new Error("Cannot access context during class construction"); + } + return this._context; + } + + public async init(context: ISimulatorContext): Promise> { + this._context = context; return {}; } diff --git a/libs/wingsdk/src/target-sim/state.ts b/libs/wingsdk/src/target-sim/state.ts index 7f3ed33cc6e..3320bc50903 100644 --- a/libs/wingsdk/src/target-sim/state.ts +++ b/libs/wingsdk/src/target-sim/state.ts @@ -53,7 +53,7 @@ export class State extends Resource implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host); + bindSimulatorResource(__filename, this, host, ops); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/table.inflight.ts b/libs/wingsdk/src/target-sim/table.inflight.ts index 5e543fc1e7f..ed48673cf11 100644 --- a/libs/wingsdk/src/target-sim/table.inflight.ts +++ b/libs/wingsdk/src/target-sim/table.inflight.ts @@ -13,19 +13,26 @@ export class Table implements ITableClient, ISimulatorResourceInstance { private columns: { [key: string]: ColumnType }; private primaryKey: string; private table: Map; - private readonly context: ISimulatorContext; + private _context: ISimulatorContext | undefined; private readonly initialRows: Record; - public constructor(props: TableSchema["props"], context: ISimulatorContext) { + public constructor(props: TableSchema["props"]) { this.name = props.name; this.columns = props.columns; this.primaryKey = props.primaryKey; this.table = new Map(); - this.context = context; this.initialRows = props.initialRows ?? {}; } - public async init(): Promise { + private get context(): ISimulatorContext { + if (!this._context) { + throw new Error("Cannot access context during class construction"); + } + return this._context; + } + + public async init(context: ISimulatorContext): Promise { + this._context = context; for (const [key, row] of Object.entries(this.initialRows)) { await this.context.withTrace({ message: `Adding initial row (key=${key}).`, diff --git a/libs/wingsdk/src/target-sim/table.ts b/libs/wingsdk/src/target-sim/table.ts index 6663052eeed..58ed24b5f64 100644 --- a/libs/wingsdk/src/target-sim/table.ts +++ b/libs/wingsdk/src/target-sim/table.ts @@ -51,7 +51,7 @@ export class Table extends ex.Table implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host); + bindSimulatorResource(__filename, this, host, ops); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/test-runner.inflight.ts b/libs/wingsdk/src/target-sim/test-runner.inflight.ts index f17fd067c60..0a4447689b3 100644 --- a/libs/wingsdk/src/target-sim/test-runner.inflight.ts +++ b/libs/wingsdk/src/target-sim/test-runner.inflight.ts @@ -12,14 +12,21 @@ export class TestRunner { // A map from test paths to their corresponding function handles. private readonly tests: Map; - private readonly context: ISimulatorContext; + private _context: ISimulatorContext | undefined; - constructor(props: TestRunnerSchema["props"], context: ISimulatorContext) { + constructor(props: TestRunnerSchema["props"]) { this.tests = new Map(Object.entries(props.tests)); - this.context = context; } - public async init(): Promise { + private get context(): ISimulatorContext { + if (!this._context) { + throw new Error("Cannot access context during class construction"); + } + return this._context; + } + + public async init(context: ISimulatorContext): Promise { + this._context = context; return {}; } @@ -42,7 +49,10 @@ export class TestRunner if (!functionHandle) { throw new Error(`No test found at path "${path}"`); } - const fnClient = this.context.getClient(functionHandle) as IFunctionClient; + const fnClient = this.context.getClient( + functionHandle, + true + ) as IFunctionClient; let pass = false; let error: string | undefined; const previousTraces = this.context.listTraces().length; diff --git a/libs/wingsdk/src/target-sim/test-runner.ts b/libs/wingsdk/src/target-sim/test-runner.ts index edab23072ea..f2ebda594e7 100644 --- a/libs/wingsdk/src/target-sim/test-runner.ts +++ b/libs/wingsdk/src/target-sim/test-runner.ts @@ -32,7 +32,7 @@ export class TestRunner extends std.TestRunner implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource("test-runner", this, host); + bindSimulatorResource("test-runner", this, host, ops); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/topic.inflight.ts b/libs/wingsdk/src/target-sim/topic.inflight.ts index 4efffd0e1a0..cd532b343ef 100644 --- a/libs/wingsdk/src/target-sim/topic.inflight.ts +++ b/libs/wingsdk/src/target-sim/topic.inflight.ts @@ -4,7 +4,7 @@ import { TopicSchema, TopicSubscriber, EventSubscription, - FunctionHandle, + ResourceHandle, } from "./schema-resources"; import { IFunctionClient, ITopicClient, TOPIC_FQN } from "../cloud"; import { @@ -18,14 +18,19 @@ export class Topic implements ITopicClient, ISimulatorResourceInstance, IEventPublisher { private readonly subscribers = new Array(); - private readonly context: ISimulatorContext; + private _context: ISimulatorContext | undefined; - constructor(props: TopicSchema["props"], context: ISimulatorContext) { - this.context = context; - props; + constructor(_props: TopicSchema["props"]) {} + + private get context(): ISimulatorContext { + if (!this._context) { + throw new Error("Cannot access context during class construction"); + } + return this._context; } - public async init(): Promise { + public async init(context: ISimulatorContext): Promise { + this._context = context; return {}; } @@ -57,7 +62,7 @@ export class Topic } public async addEventSubscription( - subscriber: FunctionHandle, + subscriber: ResourceHandle, subscriptionProps: EventSubscription ): Promise { let s = { diff --git a/libs/wingsdk/src/target-sim/topic.ts b/libs/wingsdk/src/target-sim/topic.ts index a6a888e6470..df9a4863112 100644 --- a/libs/wingsdk/src/target-sim/topic.ts +++ b/libs/wingsdk/src/target-sim/topic.ts @@ -3,6 +3,7 @@ import { Construct } from "constructs"; import { App } from "./app"; import { EventMapping } from "./event-mapping"; import { Function } from "./function"; +import { Policy } from "./policy"; import { ISimulatorResource } from "./resource"; import { TopicSchema } from "./schema-resources"; import { bindSimulatorResource, makeSimulatorJsClient } from "./util"; @@ -20,8 +21,10 @@ const QUEUE_PUSH_METHOD = "push"; * @inflight `@winglang/sdk.cloud.ITopicClient` */ export class Topic extends cloud.Topic implements ISimulatorResource { + public readonly policy: Policy; constructor(scope: Construct, id: string, props: cloud.TopicProps = {}) { super(scope, id, props); + this.policy = new Policy(this, "Policy", { principal: this }); } public onMessage( @@ -55,6 +58,8 @@ export class Topic extends cloud.Topic implements ISimulatorResource { name: "onMessage()", }); + this.policy.addStatement(fn, cloud.FunctionInflightMethods.INVOKE_ASYNC); + return fn; } @@ -93,10 +98,12 @@ export class Topic extends cloud.Topic implements ISimulatorResource { target: fn, name: "subscribeQueue()", }); + + this.policy.addStatement(fn, cloud.FunctionInflightMethods.INVOKE_ASYNC); } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host); + bindSimulatorResource(__filename, this, host, ops); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/target-sim/util.ts b/libs/wingsdk/src/target-sim/util.ts index 17074dec81b..e31dfce9f47 100644 --- a/libs/wingsdk/src/target-sim/util.ts +++ b/libs/wingsdk/src/target-sim/util.ts @@ -2,6 +2,7 @@ import { access, constants } from "fs"; import { basename } from "path"; import { promisify } from "util"; import { IConstruct } from "constructs"; +import { isSimulatorInflightHost } from "./resource"; import { simulatorHandleToken } from "./tokens"; import { Duration, IInflightHost, Resource } from "../std"; @@ -31,13 +32,23 @@ function makeEnvVarName(type: string, resource: IConstruct): string { export function bindSimulatorResource( filename: string, resource: Resource, - host: IInflightHost + host: IInflightHost, + ops: string[] ) { + // Check if host implements ISimulatorInflightHost + if (!isSimulatorInflightHost(host)) { + throw new Error( + "Host resource must implement sim.ISimulatorInflightHost to bind simulator resources" + ); + } const type = basename(filename).split(".")[0]; const env = makeEnvVarName(type, resource); const handle = simulatorHandleToken(resource); host.addEnvironment(env, handle); host.node.addDependency(resource); + for (const op of ops) { + host.addPermission(resource, op); + } } export function makeSimulatorJsClient(filename: string, resource: Resource) { @@ -52,7 +63,11 @@ export function makeSimulatorJsClient(filename: string, resource: Resource) { if (!simulatorUrl) { throw new Error("Missing environment variable: WING_SIMULATOR_URL"); } - return require("@winglang/sdk/lib/simulator/client").makeSimulatorClient(simulatorUrl, handle); + const caller = process.env.WING_SIMULATOR_CALLER; + if (!caller) { + throw new Error("Missing environment variable: WING_SIMULATOR_CALLER"); + } + return require("@winglang/sdk/lib/simulator/client").makeSimulatorClient(simulatorUrl, handle, caller); })()`; } diff --git a/libs/wingsdk/src/target-sim/website.inflight.ts b/libs/wingsdk/src/target-sim/website.inflight.ts index aa11fe4eeff..f25472134e6 100644 --- a/libs/wingsdk/src/target-sim/website.inflight.ts +++ b/libs/wingsdk/src/target-sim/website.inflight.ts @@ -14,14 +14,12 @@ import { TraceType } from "../std"; const LOCALHOST_ADDRESS = "127.0.0.1"; export class Website implements IWebsiteClient, ISimulatorResourceInstance { - private readonly context: ISimulatorContext; + private _context: ISimulatorContext | undefined; private readonly app: express.Application; private server?: Server; private url?: string; - constructor(props: WebsiteSchema["props"], context: ISimulatorContext) { - this.context = context; - + constructor(props: WebsiteSchema["props"]) { // Set up an express server that handles the routes. this.app = express(); @@ -48,7 +46,15 @@ export class Website implements IWebsiteClient, ISimulatorResourceInstance { } } - public async init(): Promise { + private get context(): ISimulatorContext { + if (!this._context) { + throw new Error("Cannot access context during class construction"); + } + return this._context; + } + + public async init(context: ISimulatorContext): Promise { + this._context = context; // `server.address()` returns `null` until the server is listening // on a port. We use a promise to wait for the server to start // listening before returning the URL. diff --git a/libs/wingsdk/src/target-sim/website.ts b/libs/wingsdk/src/target-sim/website.ts index 8e90e25e231..4e4ca6accfb 100644 --- a/libs/wingsdk/src/target-sim/website.ts +++ b/libs/wingsdk/src/target-sim/website.ts @@ -63,7 +63,7 @@ export class Website extends cloud.Website implements ISimulatorResource { } public onLift(host: IInflightHost, ops: string[]): void { - bindSimulatorResource(__filename, this, host); + bindSimulatorResource(__filename, this, host, ops); super.onLift(host, ops); } diff --git a/libs/wingsdk/src/util/enhanced-error.ts b/libs/wingsdk/src/util/enhanced-error.ts index e3dbe7a37ca..ba8a541e4a5 100644 --- a/libs/wingsdk/src/util/enhanced-error.ts +++ b/libs/wingsdk/src/util/enhanced-error.ts @@ -79,8 +79,7 @@ export async function prettyPrintError( ) // special: remove the handler wrapper (See `cloud.Function` entrypoint for where this comes from) .filter( - (item) => - !normalPath(item.file).match(/\.wing\/handler_\w+(\.sandbox)?\.js$/) + (item) => !normalPath(item.file).match(/\.wing\/\w+(\.sandbox)?\.js$/) ) .withSourcesAsync(); diff --git a/libs/wingsdk/test/core/__snapshots__/connections.test.ts.snap b/libs/wingsdk/test/core/__snapshots__/connections.test.ts.snap index 94c737a6e30..df0506ae6ec 100644 --- a/libs/wingsdk/test/core/__snapshots__/connections.test.ts.snap +++ b/libs/wingsdk/test/core/__snapshots__/connections.test.ts.snap @@ -42,6 +42,16 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Bucket", }, + { + "addr": "c8b5ba55132964ee19331fb9f46241560e67fed76b", + "attrs": {}, + "path": "root/my_bucket/Policy", + "props": { + "principal": "\${wsim#root/my_bucket#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c85c4e0e66bf385ab6b159bab34fb32dd81aad0a1d", "attrs": {}, @@ -55,6 +65,16 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c8d421ed6ca2ddf857d835791bcde9240c8682a8d9", + "attrs": {}, + "path": "root/my_function/Policy", + "props": { + "principal": "\${wsim#root/my_function#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -130,6 +150,14 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -144,6 +172,21 @@ return class Handler { "tree": { "children": { "my_bucket": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_bucket/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -156,6 +199,21 @@ return class Handler { "path": "root/my_bucket", }, "my_function": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_function/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", diff --git a/libs/wingsdk/test/simulator/cleanup.test.ts b/libs/wingsdk/test/simulator/cleanup.test.ts index 9a62a311927..a85bcf9efd4 100644 --- a/libs/wingsdk/test/simulator/cleanup.test.ts +++ b/libs/wingsdk/test/simulator/cleanup.test.ts @@ -55,13 +55,12 @@ test("simulator cleanup", async () => { stdio: ["pipe", "pipe", "pipe"], }); - // Uncomment the following lines to see the output of the child process - // child.stdout?.on("data", (data) => { - // console.error(data.toString()); - // }); - // child.stderr?.on("data", (data) => { - // console.error(data.toString()); - // }); + child.stdout?.on("data", (data) => { + console.error(data.toString()); + }); + child.stderr?.on("data", (data) => { + console.error(data.toString()); + }); let stopped = false; @@ -72,6 +71,12 @@ test("simulator cleanup", async () => { resolve(undefined); } }); + child.stderr?.on("data", (data) => { + if (data.toString().includes("stopped!")) { + stopped = true; + resolve(undefined); + } + }); }); // Wait for the "Simulator started" message, then kill the child process @@ -82,6 +87,12 @@ test("simulator cleanup", async () => { resolve(undefined); } }); + child.stderr?.on("data", (data) => { + if (data.toString().includes("Simulator started")) { + child.kill("SIGTERM"); + resolve(undefined); + } + }); }); // Wait for the "stopped!" message from cloud.Service (running in a grandchild process) diff --git a/libs/wingsdk/test/simulator/on-trace.test.ts b/libs/wingsdk/test/simulator/on-trace.test.ts index ffab782d4ef..cee2e130f88 100644 --- a/libs/wingsdk/test/simulator/on-trace.test.ts +++ b/libs/wingsdk/test/simulator/on-trace.test.ts @@ -27,5 +27,5 @@ test("onTrace", async () => { await s.stop(); // THEN - expect(numTraces).toEqual(3); // create resources, put operation, delete resources + expect(numTraces).toBeGreaterThanOrEqual(3); // create resources, put operation, delete resources }); diff --git a/libs/wingsdk/test/simulator/simulator.test.ts b/libs/wingsdk/test/simulator/simulator.test.ts index 24015bc5ccd..634420c80bb 100644 --- a/libs/wingsdk/test/simulator/simulator.test.ts +++ b/libs/wingsdk/test/simulator/simulator.test.ts @@ -214,9 +214,15 @@ describe("in-place updates", () => { new Bucket(app, "Bucket1"); const sim = await app.startSimulator(stateDir); - expect(sim.listResources()).toEqual(["root/Bucket1"]); + expect(sim.listResources()).toEqual([ + "root/Bucket1", + "root/Bucket1/Policy", + ]); - expect(simTraces(sim)).toStrictEqual(["root/Bucket1 started"]); + expect(simTraces(sim)).toStrictEqual([ + "root/Bucket1 started", + "root/Bucket1/Policy started", + ]); const app2 = new SimApp(); new Bucket(app2, "Bucket1"); @@ -232,10 +238,14 @@ describe("in-place updates", () => { expect(simTraces(sim)).toStrictEqual([ "root/Bucket1 started", + "root/Bucket1/Policy started", "Update: 0 added, 0 updated, 0 deleted", ]); - expect(sim.listResources()).toEqual(["root/Bucket1"]); + expect(sim.listResources()).toEqual([ + "root/Bucket1", + "root/Bucket1/Policy", + ]); await sim.stop(); }); @@ -246,8 +256,14 @@ describe("in-place updates", () => { new Bucket(app, "Bucket1"); const sim = await app.startSimulator(stateDir); - expect(sim.listResources()).toEqual(["root/Bucket1"]); - expect(simTraces(sim)).toStrictEqual(["root/Bucket1 started"]); + expect(sim.listResources()).toEqual([ + "root/Bucket1", + "root/Bucket1/Policy", + ]); + expect(simTraces(sim)).toStrictEqual([ + "root/Bucket1 started", + "root/Bucket1/Policy started", + ]); const app2 = new SimApp(); new Bucket(app2, "Bucket1"); @@ -256,16 +272,23 @@ describe("in-place updates", () => { const app2Dir = app2.synth(); await sim.update(app2Dir); expect(updateTrace(sim)).toStrictEqual({ - added: ["root/Bucket2"], + added: ["root/Bucket2", "root/Bucket2/Policy"], deleted: [], updated: [], }); - expect(sim.listResources()).toEqual(["root/Bucket1", "root/Bucket2"]); + expect(sim.listResources()).toEqual([ + "root/Bucket1", + "root/Bucket1/Policy", + "root/Bucket2", + "root/Bucket2/Policy", + ]); expect(simTraces(sim)).toStrictEqual([ "root/Bucket1 started", - "Update: 1 added, 0 updated, 0 deleted", + "root/Bucket1/Policy started", + "Update: 2 added, 0 updated, 0 deleted", "root/Bucket2 started", + "root/Bucket2/Policy started", ]); await sim.stop(); @@ -278,10 +301,17 @@ describe("in-place updates", () => { new Bucket(app, "Bucket1"); new Bucket(app, "Bucket2"); const sim = await app.startSimulator(stateDir); - expect(sim.listResources()).toEqual(["root/Bucket1", "root/Bucket2"]); + expect(sim.listResources()).toEqual([ + "root/Bucket1", + "root/Bucket1/Policy", + "root/Bucket2", + "root/Bucket2/Policy", + ]); expect(simTraces(sim)).toStrictEqual([ "root/Bucket1 started", + "root/Bucket1/Policy started", "root/Bucket2 started", + "root/Bucket2/Policy started", ]); const app2 = new SimApp(); @@ -291,16 +321,22 @@ describe("in-place updates", () => { await sim.update(app2Dir); expect(updateTrace(sim)).toStrictEqual({ added: [], - deleted: ["root/Bucket2"], + deleted: ["root/Bucket2", "root/Bucket2/Policy"], updated: [], }); - expect(sim.listResources()).toEqual(["root/Bucket1"]); + expect(sim.listResources()).toEqual([ + "root/Bucket1", + "root/Bucket1/Policy", + ]); expect(simTraces(sim)).toStrictEqual([ "root/Bucket1 started", + "root/Bucket1/Policy started", "root/Bucket2 started", - "Update: 0 added, 0 updated, 1 deleted", + "root/Bucket2/Policy started", + "Update: 0 added, 0 updated, 2 deleted", + "root/Bucket2/Policy stopped", "root/Bucket2 stopped", ]); @@ -313,9 +349,15 @@ describe("in-place updates", () => { const app = new SimApp(); new Bucket(app, "Bucket1"); const sim = await app.startSimulator(stateDir); - expect(sim.listResources()).toEqual(["root/Bucket1"]); + expect(sim.listResources()).toEqual([ + "root/Bucket1", + "root/Bucket1/Policy", + ]); expect(sim.getResourceConfig("root/Bucket1").props.public).toBeFalsy(); - expect(simTraces(sim)).toStrictEqual(["root/Bucket1 started"]); + expect(simTraces(sim)).toStrictEqual([ + "root/Bucket1 started", + "root/Bucket1/Policy started", + ]); const app2 = new SimApp(); new Bucket(app2, "Bucket1", { public: true }); @@ -328,13 +370,19 @@ describe("in-place updates", () => { updated: ["root/Bucket1"], }); - expect(sim.listResources()).toEqual(["root/Bucket1"]); + expect(sim.listResources()).toEqual([ + "root/Bucket1", + "root/Bucket1/Policy", + ]); expect(simTraces(sim)).toStrictEqual([ "root/Bucket1 started", + "root/Bucket1/Policy started", "Update: 0 added, 1 updated, 0 deleted", + "root/Bucket1/Policy stopped", "root/Bucket1 stopped", "root/Bucket1 started", + "root/Bucket1/Policy started", ]); expect(sim.getResourceConfig("root/Bucket1").props.public).toBeTruthy(); @@ -350,9 +398,15 @@ describe("in-place updates", () => { const sim = await app.startSimulator(stateDir); - expect(simTraces(sim)).toStrictEqual(["root/Bucket1 started"]); + expect(simTraces(sim)).toStrictEqual([ + "root/Bucket1 started", + "root/Bucket1/Policy started", + ]); - expect(sim.listResources()).toEqual(["root/Bucket1"]); + expect(sim.listResources()).toEqual([ + "root/Bucket1", + "root/Bucket1/Policy", + ]); expect(sim.getResourceConfig("root/Bucket1").props.public).toBeFalsy(); const app2 = new SimApp(); @@ -369,26 +423,40 @@ describe("in-place updates", () => { await sim.update(app2Dir); expect(updateTrace(sim)).toStrictEqual({ - added: ["root/Api", "root/Api/Endpoint", "root/Function"], + added: [ + "root/Api", + "root/Api/Endpoint", + "root/Api/Policy", + "root/Function", + "root/Function/Policy", + ], deleted: [], updated: ["root/Bucket1"], }); expect(simTraces(sim)).toStrictEqual([ "root/Bucket1 started", - "Update: 3 added, 1 updated, 0 deleted", + "root/Bucket1/Policy started", + "Update: 5 added, 1 updated, 0 deleted", + "root/Bucket1/Policy stopped", "root/Bucket1 stopped", "root/Api started", "root/Bucket1 started", + "root/Bucket1/Policy started", "root/Api/Endpoint started", + "root/Api/Policy started", "root/Function started", + "root/Function/Policy started", ]); expect(sim.listResources()).toEqual([ "root/Api", "root/Api/Endpoint", + "root/Api/Policy", "root/Bucket1", + "root/Bucket1/Policy", "root/Function", + "root/Function/Policy", ]); const bucketClient = sim.getResource("root/Bucket1") as IBucketClient; @@ -443,15 +511,12 @@ describe("in-place updates", () => { const stateDir = mkdtemp(); const sim = await app.startSimulator(stateDir); - const urlBeforeUpdate = await sim - .getResource("root/Bucket1") - .get("url.txt"); - expect(urlBeforeUpdate.startsWith("http://127.0.0")).toBeTruthy(); - expect(simTraces(sim)).toEqual([ "root/Api1 started", "root/Api1/Endpoint started", + "root/Api1/Policy started", "root/Bucket1 started", + "root/Bucket1/Policy started", ]); // now lets change some configuration of Api1. we expect the bucket to be replaced as well @@ -461,35 +526,35 @@ describe("in-place updates", () => { const myBucket2 = new Bucket(app2, "Bucket1"); myBucket2.addObject("url.txt", myApi2.url); - // clear the state directory - fs.rmdirSync(stateDir, { recursive: true }); - const app2Dir = app2.synth(); await sim.update(app2Dir); expect(updateTrace(sim)).toStrictEqual({ added: [], deleted: [], - updated: ["root/Api1"], + updated: ["root/Api1"], // TODO: shouldn't Bucket also be listed here? }); expect(simTraces(sim)).toEqual([ "root/Api1 started", "root/Api1/Endpoint started", + "root/Api1/Policy started", "root/Bucket1 started", + "root/Bucket1/Policy started", "Update: 0 added, 1 updated, 0 deleted", "root/Api1/Endpoint stopped", + "root/Api1/Policy stopped", + "root/Bucket1/Policy stopped", "root/Bucket1 stopped", "root/Api1 stopped", "root/Api1 started", "root/Api1/Endpoint started", + "root/Api1/Policy started", "root/Bucket1 started", + "root/Bucket1/Policy started", ]); - const urlAfterUpdate = await ( - sim.getResource("root/Bucket1") as IBucketClient - ).get("url.txt"); - expect(urlAfterUpdate).not.toEqual(urlBeforeUpdate); + await sim.stop(); }); test("token value is changed across an update", async () => { @@ -551,15 +616,24 @@ describe("in-place updates", () => { expect(simTraces(sim)).toEqual([ "root/State started", - "root/State.my_value = bang", "root/Service started", + "root/Service/Policy started", + "root/State.my_value = bang", + "root/Service/Helper started", "root/Function started", + "root/Function/Policy started", "Update: 0 added, 2 updated, 0 deleted", + "root/Service/Helper stopped", + "root/Service/Policy stopped", "root/Service stopped", + "root/Function/Policy stopped", "root/Function stopped", - "root/State.my_value = bing", "root/Service started", + "root/Service/Policy started", + "root/State.my_value = bing", + "root/Service/Helper started", "root/Function started", + "root/Function/Policy started", ]); }); @@ -584,15 +658,21 @@ describe("in-place updates", () => { await sim.update(app2Dir); expect(simTraces(sim)).toEqual([ - "root/OnDeploy/Function started", "root/Bucket1 started", + "root/Bucket1/Policy started", + "root/OnDeploy/Function started", + "root/OnDeploy/Function/Policy started", "root/OnDeploy started", - "Update: 0 added, 2 updated, 0 deleted", + "Update: 0 added, 3 updated, 0 deleted", "root/OnDeploy stopped", + "root/OnDeploy/Function/Policy stopped", "root/OnDeploy/Function stopped", + "root/Bucket1/Policy stopped", "root/Bucket1 stopped", - "root/OnDeploy/Function started", "root/Bucket1 started", + "root/Bucket1/Policy started", + "root/OnDeploy/Function started", + "root/OnDeploy/Function/Policy started", "root/OnDeploy started", ]); }); @@ -612,9 +692,12 @@ describe("in-place updates", () => { expect(simTraces(sim)).toEqual([ "root/Function started", + "root/Function/Policy started", "Update: 0 added, 1 updated, 0 deleted", + "root/Function/Policy stopped", "root/Function stopped", "root/Function started", + "root/Function/Policy started", ]); }); @@ -633,9 +716,42 @@ describe("in-place updates", () => { expect(simTraces(sim)).toEqual([ "root/Service started", + "root/Service/Policy started", + "root/Service/Helper started", "Update: 0 added, 1 updated, 0 deleted", + "root/Service/Helper stopped", + "root/Service/Policy stopped", "root/Service stopped", "root/Service started", + "root/Service/Policy started", + "root/Service/Helper started", + ]); + }); + + test("cloud.OnDeploy is always replaced", async () => { + const app = new SimApp(); + const handler = Testing.makeHandler(`async handle() {}`); + new OnDeploy(app, "OnDeploy", handler); + + const sim = await app.startSimulator(); + + const app2 = new SimApp(); + new OnDeploy(app2, "OnDeploy", handler); + + const app2Dir = app2.synth(); + await sim.update(app2Dir); + + expect(simTraces(sim)).toEqual([ + "root/OnDeploy/Function started", + "root/OnDeploy/Function/Policy started", + "root/OnDeploy started", + "Update: 0 added, 2 updated, 0 deleted", + "root/OnDeploy stopped", + "root/OnDeploy/Function/Policy stopped", + "root/OnDeploy/Function stopped", + "root/OnDeploy/Function started", + "root/OnDeploy/Function/Policy started", + "root/OnDeploy started", ]); }); @@ -671,8 +787,12 @@ describe("in-place updates", () => { "root/Api started", "root/Api/Endpoint started", "root/Api/OnRequestHandler0 started", + "root/Api/Policy started", + "root/Api/OnRequestHandler0/Policy started", "root/Api/ApiEventMapping0 started", "Update: 0 added, 3 updated, 0 deleted", + "root/Api/Policy stopped", + "root/Api/OnRequestHandler0/Policy stopped", "root/Api/ApiEventMapping0 stopped", "root/Api/OnRequestHandler0 stopped", "root/Api/Endpoint stopped", @@ -680,6 +800,8 @@ describe("in-place updates", () => { "root/Api started", "root/Api/Endpoint started", "root/Api/OnRequestHandler0 started", + "root/Api/Policy started", + "root/Api/OnRequestHandler0/Policy started", "root/Api/ApiEventMapping0 started", ]); }); diff --git a/libs/wingsdk/test/target-sim/__snapshots__/api.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/api.test.ts.snap index ba00408b0af..d0341d9c345 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/api.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/api.test.ts.snap @@ -47,6 +47,31 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, + { + "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", + "attrs": {}, + "path": "root/my_api/Policy", + "props": { + "principal": "\${wsim#root/my_api#attrs.handle}", + "statements": [ + { + "operation": "invoke", + "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + }, + ], + }, + "type": "@winglang/sdk.sim.Policy", + }, + { + "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", + "attrs": {}, + "path": "root/my_api/OnRequestHandler0/Policy", + "props": { + "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -196,6 +221,14 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -235,6 +268,21 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/OnRequestHandler0/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -248,6 +296,19 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/Policy", + }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -279,11 +340,15 @@ exports[`api handler can read the request params 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", + "root/my_api/Policy started", + "root/my_api/OnRequestHandler0/Policy started", "root/my_api/ApiEventMapping0 started", "Processing "GET /hello" params={}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/hello\\",\\"query\\":{\\"foo\\":\\"bar\\",\\"bar\\":\\"baz\\"},\\"vars\\":{}}").", "GET /hello - 200.", "root/my_api/Endpoint stopped", + "root/my_api/Policy stopped", + "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "Closing server on http://127.0.0.1:", @@ -333,6 +398,31 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, + { + "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", + "attrs": {}, + "path": "root/my_api/Policy", + "props": { + "principal": "\${wsim#root/my_api#attrs.handle}", + "statements": [ + { + "operation": "invoke", + "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + }, + ], + }, + "type": "@winglang/sdk.sim.Policy", + }, + { + "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", + "attrs": {}, + "path": "root/my_api/OnRequestHandler0/Policy", + "props": { + "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -468,6 +558,14 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -507,6 +605,21 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/OnRequestHandler0/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -520,6 +633,19 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/Policy", + }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -551,11 +677,15 @@ exports[`api handler can read the request path 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", + "root/my_api/Policy started", + "root/my_api/OnRequestHandler0/Policy started", "root/my_api/ApiEventMapping0 started", "Processing "GET /hello" params={}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/hello\\",\\"query\\":{},\\"vars\\":{}}").", "GET /hello - 200.", "root/my_api/Endpoint stopped", + "root/my_api/Policy stopped", + "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "Closing server on http://127.0.0.1:", @@ -605,6 +735,31 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, + { + "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", + "attrs": {}, + "path": "root/my_api/Policy", + "props": { + "principal": "\${wsim#root/my_api#attrs.handle}", + "statements": [ + { + "operation": "invoke", + "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + }, + ], + }, + "type": "@winglang/sdk.sim.Policy", + }, + { + "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", + "attrs": {}, + "path": "root/my_api/OnRequestHandler0/Policy", + "props": { + "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -740,6 +895,14 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -779,6 +942,21 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/OnRequestHandler0/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -792,6 +970,19 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/Policy", + }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -823,11 +1014,15 @@ exports[`api handler can set response headers 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", + "root/my_api/Policy started", + "root/my_api/OnRequestHandler0/Policy started", "root/my_api/ApiEventMapping0 started", "Processing "GET /hello" params={}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"foo\\":\\"bar\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/hello\\",\\"query\\":{},\\"vars\\":{}}").", "GET /hello - 200.", "root/my_api/Endpoint stopped", + "root/my_api/Policy stopped", + "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "Closing server on http://127.0.0.1:", @@ -877,6 +1072,31 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, + { + "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", + "attrs": {}, + "path": "root/my_api/Policy", + "props": { + "principal": "\${wsim#root/my_api#attrs.handle}", + "statements": [ + { + "operation": "invoke", + "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + }, + ], + }, + "type": "@winglang/sdk.sim.Policy", + }, + { + "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", + "attrs": {}, + "path": "root/my_api/OnRequestHandler0/Policy", + "props": { + "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -1012,6 +1232,14 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1051,6 +1279,21 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/OnRequestHandler0/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1064,6 +1307,19 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/Policy", + }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -1095,11 +1351,15 @@ exports[`api response returns Content-Type header from inflight 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", + "root/my_api/Policy started", + "root/my_api/OnRequestHandler0/Policy started", "root/my_api/ApiEventMapping0 started", "Processing "GET /hello" params={}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/hello\\",\\"query\\":{},\\"vars\\":{}}").", "GET /hello - 200.", "root/my_api/Endpoint stopped", + "root/my_api/Policy stopped", + "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "Closing server on http://127.0.0.1:", @@ -1149,6 +1409,31 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, + { + "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", + "attrs": {}, + "path": "root/my_api/Policy", + "props": { + "principal": "\${wsim#root/my_api#attrs.handle}", + "statements": [ + { + "operation": "invoke", + "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + }, + ], + }, + "type": "@winglang/sdk.sim.Policy", + }, + { + "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", + "attrs": {}, + "path": "root/my_api/OnRequestHandler0/Policy", + "props": { + "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -1284,6 +1569,14 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1323,6 +1616,21 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/OnRequestHandler0/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1336,6 +1644,19 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/Policy", + }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -1367,11 +1688,15 @@ exports[`api response returns default Content-Type header 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", + "root/my_api/Policy started", + "root/my_api/OnRequestHandler0/Policy started", "root/my_api/ApiEventMapping0 started", "Processing "GET /hello" params={}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/hello\\",\\"query\\":{},\\"vars\\":{}}").", "GET /hello - 200.", "root/my_api/Endpoint stopped", + "root/my_api/Policy stopped", + "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "Closing server on http://127.0.0.1:", @@ -1421,6 +1746,31 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, + { + "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", + "attrs": {}, + "path": "root/my_api/Policy", + "props": { + "principal": "\${wsim#root/my_api#attrs.handle}", + "statements": [ + { + "operation": "invoke", + "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + }, + ], + }, + "type": "@winglang/sdk.sim.Policy", + }, + { + "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", + "attrs": {}, + "path": "root/my_api/OnRequestHandler0/Policy", + "props": { + "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -1556,6 +1906,14 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1595,6 +1953,21 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/OnRequestHandler0/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1608,6 +1981,19 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/Policy", + }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -1639,6 +2025,8 @@ exports[`api supports every method type 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", + "root/my_api/Policy started", + "root/my_api/OnRequestHandler0/Policy started", "root/my_api/ApiEventMapping0 started", "Processing "GET /hello" params={}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/hello\\",\\"query\\":{},\\"vars\\":{}}").", @@ -1662,6 +2050,8 @@ exports[`api supports every method type 1`] = ` "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\",\\"content-length\\":\\"0\\"},\\"body\\":\\"\\",\\"method\\":\\"PATCH\\",\\"path\\":\\"/hello\\",\\"query\\":{},\\"vars\\":{}}").", "PATCH /hello - 200.", "root/my_api/Endpoint stopped", + "root/my_api/Policy stopped", + "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "Closing server on http://127.0.0.1:", @@ -1741,6 +2131,31 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, + { + "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", + "attrs": {}, + "path": "root/my_api/Policy", + "props": { + "principal": "\${wsim#root/my_api#attrs.handle}", + "statements": [ + { + "operation": "invoke", + "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + }, + ], + }, + "type": "@winglang/sdk.sim.Policy", + }, + { + "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", + "attrs": {}, + "path": "root/my_api/OnRequestHandler0/Policy", + "props": { + "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -1960,6 +2375,14 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1999,6 +2422,21 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/OnRequestHandler0/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -2012,6 +2450,19 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/Policy", + }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -2043,11 +2494,15 @@ exports[`api with 'name' & 'age' parameter 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", + "root/my_api/Policy started", + "root/my_api/OnRequestHandler0/Policy started", "root/my_api/ApiEventMapping0 started", "Processing "GET /:name/:age" params={"name":"akhil","age":"23"}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/akhil/23\\",\\"query\\":{},\\"vars\\":{\\"name\\":\\"akhil\\",\\"age\\":\\"23\\"}}").", "GET /:name/:age - 200.", "root/my_api/Endpoint stopped", + "root/my_api/Policy stopped", + "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "Closing server on http://127.0.0.1:", @@ -2097,6 +2552,31 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, + { + "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", + "attrs": {}, + "path": "root/my_api/Policy", + "props": { + "principal": "\${wsim#root/my_api#attrs.handle}", + "statements": [ + { + "operation": "invoke", + "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + }, + ], + }, + "type": "@winglang/sdk.sim.Policy", + }, + { + "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", + "attrs": {}, + "path": "root/my_api/OnRequestHandler0/Policy", + "props": { + "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -2249,6 +2729,14 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -2288,6 +2776,21 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/OnRequestHandler0/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -2301,6 +2804,19 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/Policy", + }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -2332,11 +2848,15 @@ exports[`api with 'name' parameter 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", + "root/my_api/Policy started", + "root/my_api/OnRequestHandler0/Policy started", "root/my_api/ApiEventMapping0 started", "Processing "GET /:name" params={"name":"akhil"}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/akhil\\",\\"query\\":{},\\"vars\\":{\\"name\\":\\"akhil\\"}}").", "GET /:name - 200.", "root/my_api/Endpoint stopped", + "root/my_api/Policy stopped", + "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "Closing server on http://127.0.0.1:", @@ -2386,6 +2906,31 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, + { + "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", + "attrs": {}, + "path": "root/my_api/Policy", + "props": { + "principal": "\${wsim#root/my_api#attrs.handle}", + "statements": [ + { + "operation": "invoke", + "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + }, + ], + }, + "type": "@winglang/sdk.sim.Policy", + }, + { + "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", + "attrs": {}, + "path": "root/my_api/OnRequestHandler0/Policy", + "props": { + "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -2530,6 +3075,14 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -2569,6 +3122,21 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/OnRequestHandler0/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -2582,6 +3150,19 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/Policy", + }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -2649,6 +3230,31 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, + { + "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", + "attrs": {}, + "path": "root/my_api/Policy", + "props": { + "principal": "\${wsim#root/my_api#attrs.handle}", + "statements": [ + { + "operation": "invoke", + "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + }, + ], + }, + "type": "@winglang/sdk.sim.Policy", + }, + { + "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", + "attrs": {}, + "path": "root/my_api/OnRequestHandler0/Policy", + "props": { + "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -2800,6 +3406,14 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -2839,6 +3453,21 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/OnRequestHandler0/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -2852,6 +3481,19 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/Policy", + }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -2883,8 +3525,11 @@ exports[`api with multiple methods on same route 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", - "root/my_api/ApiEventMapping0 started", "root/my_api/OnRequestHandler1 started", + "root/my_api/Policy started", + "root/my_api/OnRequestHandler0/Policy started", + "root/my_api/ApiEventMapping0 started", + "root/my_api/OnRequestHandler1/Policy started", "root/my_api/ApiEventMapping1 started", "Processing "GET /hello" params={}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/hello\\",\\"query\\":{},\\"vars\\":{}}").", @@ -2893,11 +3538,14 @@ exports[`api with multiple methods on same route 1`] = ` "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\",\\"content-length\\":\\"0\\"},\\"body\\":\\"\\",\\"method\\":\\"POST\\",\\"path\\":\\"/hello\\",\\"query\\":{},\\"vars\\":{}}").", "POST /hello - 200.", "root/my_api/Endpoint stopped", + "root/my_api/Policy stopped", + "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "root/my_api/ApiEventMapping1 stopped", "Closing server on http://127.0.0.1:", "root/my_api stopped", + "root/my_api/OnRequestHandler1/Policy stopped", "root/my_api/OnRequestHandler1 stopped", ] `; @@ -2966,6 +3614,35 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, + { + "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", + "attrs": {}, + "path": "root/my_api/Policy", + "props": { + "principal": "\${wsim#root/my_api#attrs.handle}", + "statements": [ + { + "operation": "invoke", + "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + }, + { + "operation": "invoke", + "resourceHandle": "\${wsim#root/my_api/OnRequestHandler1#attrs.handle}", + }, + ], + }, + "type": "@winglang/sdk.sim.Policy", + }, + { + "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", + "attrs": {}, + "path": "root/my_api/OnRequestHandler0/Policy", + "props": { + "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -3036,6 +3713,16 @@ return class Handler { }, "type": "@winglang/sdk.sim.EventMapping", }, + { + "addr": "c8603fc16b367fc8cb05634fbb47b4a1e7f873b298", + "attrs": {}, + "path": "root/my_api/OnRequestHandler1/Policy", + "props": { + "principal": "\${wsim#root/my_api/OnRequestHandler1#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c84819d7712e30f38cf7731fcfbe96cbc39c7e75d3", "attrs": {}, @@ -3146,6 +3833,14 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -3196,6 +3891,21 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/OnRequestHandler0/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -3210,6 +3920,21 @@ return class Handler { "path": "root/my_api/OnRequestHandler0", }, "OnRequestHandler1": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/OnRequestHandler1/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -3223,6 +3948,19 @@ return class Handler { "id": "OnRequestHandler1", "path": "root/my_api/OnRequestHandler1", }, + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/Policy", + }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -3254,8 +3992,11 @@ exports[`api with multiple routes 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", - "root/my_api/ApiEventMapping0 started", "root/my_api/OnRequestHandler1 started", + "root/my_api/Policy started", + "root/my_api/OnRequestHandler0/Policy started", + "root/my_api/ApiEventMapping0 started", + "root/my_api/OnRequestHandler1/Policy started", "root/my_api/ApiEventMapping1 started", "Processing "GET /hello/world" params={}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/hello/world\\",\\"query\\":{},\\"vars\\":{}}").", @@ -3264,11 +4005,14 @@ exports[`api with multiple routes 1`] = ` "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/hello/wingnuts\\",\\"query\\":{},\\"vars\\":{}}").", "GET /hello/wingnuts - 200.", "root/my_api/Endpoint stopped", + "root/my_api/Policy stopped", + "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "root/my_api/ApiEventMapping1 stopped", "Closing server on http://127.0.0.1:", "root/my_api stopped", + "root/my_api/OnRequestHandler1/Policy stopped", "root/my_api/OnRequestHandler1 stopped", ] `; @@ -3337,6 +4081,35 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, + { + "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", + "attrs": {}, + "path": "root/my_api/Policy", + "props": { + "principal": "\${wsim#root/my_api#attrs.handle}", + "statements": [ + { + "operation": "invoke", + "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + }, + { + "operation": "invoke", + "resourceHandle": "\${wsim#root/my_api/OnRequestHandler1#attrs.handle}", + }, + ], + }, + "type": "@winglang/sdk.sim.Policy", + }, + { + "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", + "attrs": {}, + "path": "root/my_api/OnRequestHandler0/Policy", + "props": { + "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -3409,6 +4182,16 @@ return class Handler { }, "type": "@winglang/sdk.sim.EventMapping", }, + { + "addr": "c8603fc16b367fc8cb05634fbb47b4a1e7f873b298", + "attrs": {}, + "path": "root/my_api/OnRequestHandler1/Policy", + "props": { + "principal": "\${wsim#root/my_api/OnRequestHandler1#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c84819d7712e30f38cf7731fcfbe96cbc39c7e75d3", "attrs": {}, @@ -3519,6 +4302,14 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -3569,6 +4360,21 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/OnRequestHandler0/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -3583,6 +4389,21 @@ return class Handler { "path": "root/my_api/OnRequestHandler0", }, "OnRequestHandler1": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/OnRequestHandler1/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -3596,6 +4417,19 @@ return class Handler { "id": "OnRequestHandler1", "path": "root/my_api/OnRequestHandler1", }, + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/Policy", + }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -3627,11 +4461,15 @@ exports[`api with one GET route 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", + "root/my_api/Policy started", + "root/my_api/OnRequestHandler0/Policy started", "root/my_api/ApiEventMapping0 started", "Processing "GET /hello" params={}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/hello\\",\\"query\\":{},\\"vars\\":{}}").", "GET /hello - 200.", "root/my_api/Endpoint stopped", + "root/my_api/Policy stopped", + "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "Closing server on http://127.0.0.1:", @@ -3681,6 +4519,31 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, + { + "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", + "attrs": {}, + "path": "root/my_api/Policy", + "props": { + "principal": "\${wsim#root/my_api#attrs.handle}", + "statements": [ + { + "operation": "invoke", + "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + }, + ], + }, + "type": "@winglang/sdk.sim.Policy", + }, + { + "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", + "attrs": {}, + "path": "root/my_api/OnRequestHandler0/Policy", + "props": { + "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -3816,6 +4679,14 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -3855,6 +4726,21 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/OnRequestHandler0/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -3868,6 +4754,19 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/Policy", + }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -3899,11 +4798,15 @@ exports[`api with one GET route with request params 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", + "root/my_api/Policy started", + "root/my_api/OnRequestHandler0/Policy started", "root/my_api/ApiEventMapping0 started", "Processing "GET /users/:name" params={"name":"tsuf"}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":\\"\\",\\"method\\":\\"GET\\",\\"path\\":\\"/users/tsuf\\",\\"query\\":{},\\"vars\\":{\\"name\\":\\"tsuf\\"}}").", "GET /users/:name - 200.", "root/my_api/Endpoint stopped", + "root/my_api/Policy stopped", + "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "Closing server on http://127.0.0.1:", @@ -3953,6 +4856,31 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, + { + "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", + "attrs": {}, + "path": "root/my_api/Policy", + "props": { + "principal": "\${wsim#root/my_api#attrs.handle}", + "statements": [ + { + "operation": "invoke", + "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + }, + ], + }, + "type": "@winglang/sdk.sim.Policy", + }, + { + "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", + "attrs": {}, + "path": "root/my_api/OnRequestHandler0/Policy", + "props": { + "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -4097,6 +5025,14 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -4136,6 +5072,21 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/OnRequestHandler0/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -4149,6 +5100,19 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/Policy", + }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -4180,11 +5144,15 @@ exports[`api with one POST route, with body 1`] = ` "root/my_api started", "root/my_api/Endpoint started", "root/my_api/OnRequestHandler0 started", + "root/my_api/Policy started", + "root/my_api/OnRequestHandler0/Policy started", "root/my_api/ApiEventMapping0 started", "Processing "POST /hello" params={}).", "Invoke (payload="{\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"content-type\\":\\"application/json\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"node\\",\\"accept-encoding\\":\\"gzip, deflate\\",\\"content-length\\":\\"25\\"},\\"body\\":\\"{\\\\\\"message\\\\\\":\\\\\\"hello world\\\\\\"}\\",\\"method\\":\\"POST\\",\\"path\\":\\"/hello\\",\\"query\\":{},\\"vars\\":{}}").", "POST /hello - 200.", "root/my_api/Endpoint stopped", + "root/my_api/Policy stopped", + "root/my_api/OnRequestHandler0/Policy stopped", "root/my_api/ApiEventMapping0 stopped", "root/my_api/OnRequestHandler0 stopped", "Closing server on http://127.0.0.1:", @@ -4234,6 +5202,31 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Endpoint", }, + { + "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", + "attrs": {}, + "path": "root/my_api/Policy", + "props": { + "principal": "\${wsim#root/my_api#attrs.handle}", + "statements": [ + { + "operation": "invoke", + "resourceHandle": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + }, + ], + }, + "type": "@winglang/sdk.sim.Policy", + }, + { + "addr": "c8b0396e20397567e34feafb703cea1bc0b968dc05", + "attrs": {}, + "path": "root/my_api/OnRequestHandler0/Policy", + "props": { + "principal": "\${wsim#root/my_api/OnRequestHandler0#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c82d41b2501ac42e07e4565202a5b87a180a01c6a2", "attrs": {}, @@ -4369,6 +5362,14 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -4408,6 +5409,21 @@ return class Handler { "path": "root/my_api/Endpoint", }, "OnRequestHandler0": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/OnRequestHandler0/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -4421,6 +5437,19 @@ return class Handler { "id": "OnRequestHandler0", "path": "root/my_api/OnRequestHandler0", }, + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/Policy", + }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -4477,6 +5506,16 @@ exports[`create an api 1`] = ` }, "type": "@winglang/sdk.cloud.Endpoint", }, + { + "addr": "c8d2997625976ba9bc7be90fefe7930aebab104a2a", + "attrs": {}, + "path": "root/my_api/Policy", + "props": { + "principal": "\${wsim#root/my_api#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -4552,6 +5591,14 @@ exports[`create an api 1`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -4579,6 +5626,19 @@ exports[`create an api 1`] = ` "id": "Endpoint", "path": "root/my_api/Endpoint", }, + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_api/Policy", + }, }, "constructInfo": { "fqn": "constructs.Construct", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/bucket.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/bucket.test.ts.snap index a1f5c77fefd..56c148f70d8 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/bucket.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/bucket.test.ts.snap @@ -6,44 +6,60 @@ exports[`bucket on event creates 3 topics, and sends the right event and key in "root/my_bucket/onupdate started", "root/my_bucket/ondelete started", "root/my_bucket started", + "root/my_bucket/Policy started", "root/log_bucket started", "root/my_bucket/oncreate/OnMessage0 started", + "root/my_bucket/oncreate/Policy started", + "root/my_bucket/oncreate/OnMessage0/Policy started", "root/my_bucket/oncreate/TopicEventMapping0 started", "root/my_bucket/onupdate/OnMessage0 started", + "root/my_bucket/onupdate/Policy started", + "root/my_bucket/onupdate/OnMessage0/Policy started", "root/my_bucket/onupdate/TopicEventMapping0 started", "root/my_bucket/ondelete/OnMessage0 started", + "root/my_bucket/ondelete/Policy started", + "root/my_bucket/ondelete/OnMessage0/Policy started", "root/my_bucket/ondelete/TopicEventMapping0 started", + "root/log_bucket/Policy started", "Publish (message=a).", - "Sending message (message=a, subscriber=sim-5).", + "Sending message (message=a, subscriber=sim-6).", "InvokeAsync (payload="a").", "Put (key=a).", "Put (key=a).", "I am done", "Get (key=a).", "Publish (message=a).", - "Sending message (message=a, subscriber=sim-7).", + "Sending message (message=a, subscriber=sim-10).", "InvokeAsync (payload="a").", "Put (key=a).", "Put (key=a).", "I am done", "Get (key=a).", "Publish (message=a).", - "Sending message (message=a, subscriber=sim-9).", + "Sending message (message=a, subscriber=sim-14).", "InvokeAsync (payload="a").", "Delete (key=a).", "Put (key=a).", "I am done", "Get (key=a).", + "root/my_bucket/Policy stopped", "root/my_bucket stopped", + "root/my_bucket/oncreate/Policy stopped", "root/my_bucket/oncreate/TopicEventMapping0 stopped", "root/my_bucket/oncreate stopped", + "root/my_bucket/onupdate/Policy stopped", "root/my_bucket/onupdate/TopicEventMapping0 stopped", "root/my_bucket/onupdate stopped", + "root/my_bucket/ondelete/Policy stopped", "root/my_bucket/ondelete/TopicEventMapping0 stopped", "root/my_bucket/ondelete stopped", + "root/my_bucket/oncreate/OnMessage0/Policy stopped", "root/my_bucket/oncreate/OnMessage0 stopped", + "root/my_bucket/onupdate/OnMessage0/Policy stopped", "root/my_bucket/onupdate/OnMessage0 stopped", + "root/my_bucket/ondelete/OnMessage0/Policy stopped", "root/my_bucket/ondelete/OnMessage0 stopped", + "root/log_bucket/Policy stopped", "root/log_bucket stopped", ] `; @@ -52,9 +68,11 @@ exports[`can add file in preflight 1`] = ` [ "Adding object from preflight (key=test.txt).", "root/my_bucket started", + "root/my_bucket/Policy started", "Get (key=test.txt).", "Get (key=test.txt).", "List (prefix=null).", + "root/my_bucket/Policy stopped", "root/my_bucket stopped", ] `; @@ -80,6 +98,16 @@ exports[`can add file in preflight 2`] = ` }, "type": "@winglang/sdk.cloud.Bucket", }, + { + "addr": "c8b5ba55132964ee19331fb9f46241560e67fed76b", + "attrs": {}, + "path": "root/my_bucket/Policy", + "props": { + "principal": "\${wsim#root/my_bucket#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -155,6 +183,14 @@ exports[`can add file in preflight 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -169,6 +205,21 @@ exports[`can add file in preflight 2`] = ` "tree": { "children": { "my_bucket": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_bucket/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -197,9 +248,11 @@ exports[`can add object in preflight 1`] = ` [ "Adding object from preflight (key=greeting.txt).", "root/my_bucket started", + "root/my_bucket/Policy started", "Get (key=greeting.txt).", "Get (key=greeting.txt).", "List (prefix=null).", + "root/my_bucket/Policy stopped", "root/my_bucket stopped", ] `; @@ -225,6 +278,16 @@ exports[`can add object in preflight 2`] = ` }, "type": "@winglang/sdk.cloud.Bucket", }, + { + "addr": "c8b5ba55132964ee19331fb9f46241560e67fed76b", + "attrs": {}, + "path": "root/my_bucket/Policy", + "props": { + "principal": "\${wsim#root/my_bucket#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -300,6 +363,14 @@ exports[`can add object in preflight 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -314,6 +385,21 @@ exports[`can add object in preflight 2`] = ` "tree": { "children": { "my_bucket": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_bucket/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -357,6 +443,16 @@ exports[`create a bucket 1`] = ` }, "type": "@winglang/sdk.cloud.Bucket", }, + { + "addr": "c8b5ba55132964ee19331fb9f46241560e67fed76b", + "attrs": {}, + "path": "root/my_bucket/Policy", + "props": { + "principal": "\${wsim#root/my_bucket#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -432,6 +528,14 @@ exports[`create a bucket 1`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -446,6 +550,21 @@ exports[`create a bucket 1`] = ` "tree": { "children": { "my_bucket": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_bucket/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -473,7 +592,9 @@ exports[`create a bucket 1`] = ` exports[`get invalid object throws an error 1`] = ` [ "root/my_bucket started", + "root/my_bucket/Policy started", "Get (key=unknown.txt).", + "root/my_bucket/Policy stopped", "root/my_bucket stopped", ] `; @@ -497,6 +618,16 @@ exports[`get invalid object throws an error 2`] = ` }, "type": "@winglang/sdk.cloud.Bucket", }, + { + "addr": "c8b5ba55132964ee19331fb9f46241560e67fed76b", + "attrs": {}, + "path": "root/my_bucket/Policy", + "props": { + "principal": "\${wsim#root/my_bucket#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -572,6 +703,14 @@ exports[`get invalid object throws an error 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -586,6 +725,21 @@ exports[`get invalid object throws an error 2`] = ` "tree": { "children": { "my_bucket": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_bucket/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -613,12 +767,14 @@ exports[`get invalid object throws an error 2`] = ` exports[`list respects prefixes 1`] = ` [ "root/my_bucket started", + "root/my_bucket/Policy started", "Put (key=path/dir1/file1.txt).", "Put (key=path/dir2/file2.txt).", "List (prefix=null).", "List (prefix=path).", "List (prefix=path/dir1).", "List (prefix=path/dir2).", + "root/my_bucket/Policy stopped", "root/my_bucket stopped", ] `; @@ -626,6 +782,7 @@ exports[`list respects prefixes 1`] = ` exports[`objects can have keys that look like directories 1`] = ` [ "root/my_bucket started", + "root/my_bucket/Policy started", "Put (key=foo).", "Put (key=foo/).", "Put (key=foo/bar).", @@ -637,6 +794,7 @@ exports[`objects can have keys that look like directories 1`] = ` "List (prefix=foo/bar).", "List (prefix=foo/bar/).", "List (prefix=foo/bar/baz).", + "root/my_bucket/Policy stopped", "root/my_bucket stopped", ] `; @@ -644,12 +802,14 @@ exports[`objects can have keys that look like directories 1`] = ` exports[`put and get metadata of objects from bucket 1`] = ` [ "root/my_bucket started", + "root/my_bucket/Policy started", "Put (key=file1.main.w).", "Put (key=file2.txt).", "Put (key=file3.txt).", "Metadata (key=file1.main.w).", "Metadata (key=file2.txt).", "Metadata (key=file3.txt).", + "root/my_bucket/Policy stopped", "root/my_bucket stopped", ] `; @@ -657,8 +817,10 @@ exports[`put and get metadata of objects from bucket 1`] = ` exports[`put and get object from bucket 1`] = ` [ "root/my_bucket started", + "root/my_bucket/Policy started", "Put (key=greeting.txt).", "Get (key=greeting.txt).", + "root/my_bucket/Policy stopped", "root/my_bucket stopped", ] `; @@ -666,10 +828,12 @@ exports[`put and get object from bucket 1`] = ` exports[`put multiple json objects and list all from bucket 1`] = ` [ "root/my_bucket started", + "root/my_bucket/Policy started", "Put Json (key=greeting1.json).", "Put Json (key=greeting2.json).", "Put Json (key=greeting3.json).", "List (prefix=null).", + "root/my_bucket/Policy stopped", "root/my_bucket stopped", ] `; @@ -677,10 +841,12 @@ exports[`put multiple json objects and list all from bucket 1`] = ` exports[`put multiple objects and list all from bucket 1`] = ` [ "root/my_bucket started", + "root/my_bucket/Policy started", "Put (key=greeting1.txt).", "Put (key=greeting2.txt).", "Put (key=greeting3.txt).", "List (prefix=null).", + "root/my_bucket/Policy stopped", "root/my_bucket stopped", ] `; @@ -688,8 +854,10 @@ exports[`put multiple objects and list all from bucket 1`] = ` exports[`remove object from a bucket 1`] = ` [ "root/my_bucket started", + "root/my_bucket/Policy started", "Put (key=unknown.txt).", "Delete (key=unknown.txt).", + "root/my_bucket/Policy stopped", "root/my_bucket stopped", ] `; @@ -697,8 +865,10 @@ exports[`remove object from a bucket 1`] = ` exports[`remove object from a bucket with mustExist as option 1`] = ` [ "root/my_bucket started", + "root/my_bucket/Policy started", "Put (key=unknown.txt).", "Delete (key=unknown.txt).", + "root/my_bucket/Policy stopped", "root/my_bucket stopped", ] `; @@ -707,17 +877,23 @@ exports[`removing a key will call onDelete method 1`] = ` [ "root/my_bucket/ondelete started", "root/my_bucket started", + "root/my_bucket/Policy started", "root/my_bucket/ondelete/OnMessage0 started", + "root/my_bucket/ondelete/Policy started", + "root/my_bucket/ondelete/OnMessage0/Policy started", "root/my_bucket/ondelete/TopicEventMapping0 started", "Put (key=unknown.txt).", "Publish (message=unknown.txt).", - "Sending message (message=unknown.txt, subscriber=sim-2).", + "Sending message (message=unknown.txt, subscriber=sim-3).", "InvokeAsync (payload="unknown.txt").", "Delete (key=unknown.txt).", "Received unknown.txt", + "root/my_bucket/Policy stopped", "root/my_bucket stopped", + "root/my_bucket/ondelete/Policy stopped", "root/my_bucket/ondelete/TopicEventMapping0 stopped", "root/my_bucket/ondelete stopped", + "root/my_bucket/ondelete/OnMessage0/Policy stopped", "root/my_bucket/ondelete/OnMessage0 stopped", ] `; @@ -726,12 +902,23 @@ exports[`update an object in bucket 1`] = ` [ "root/my_bucket/oncreate started", "root/my_bucket started", + "root/my_bucket/Policy started", "root/my_bucket/oncreate/OnMessage0 started", + "root/my_bucket/oncreate/Policy started", + "root/my_bucket/oncreate/OnMessage0/Policy started", "root/my_bucket/oncreate/TopicEventMapping0 started", "Publish (message=1.txt).", - "Sending message (message=1.txt, subscriber=sim-2).", + "Sending message (message=1.txt, subscriber=sim-3).", "InvokeAsync (payload="1.txt").", "Put (key=1.txt).", "Put (key=1.txt).", + "I am done", + "root/my_bucket/Policy stopped", + "root/my_bucket stopped", + "root/my_bucket/oncreate/Policy stopped", + "root/my_bucket/oncreate/TopicEventMapping0 stopped", + "root/my_bucket/oncreate stopped", + "root/my_bucket/oncreate/OnMessage0/Policy stopped", + "root/my_bucket/oncreate/OnMessage0 stopped", ] `; diff --git a/libs/wingsdk/test/target-sim/__snapshots__/counter.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/counter.test.ts.snap index 0d77770e98b..6b2d6b9b8cc 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/counter.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/counter.test.ts.snap @@ -92,6 +92,14 @@ exports[`create a counter 1`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -233,6 +241,14 @@ exports[`dec 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -374,6 +390,14 @@ exports[`inc 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -515,6 +539,14 @@ exports[`key dec 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -656,6 +688,14 @@ exports[`key inc 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -795,6 +835,14 @@ exports[`key set to new value 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -934,6 +982,14 @@ exports[`set to new value 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/file-counter.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/file-counter.test.ts.snap index 6371f1c2e57..9d11f3f638d 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/file-counter.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/file-counter.test.ts.snap @@ -28,7 +28,11 @@ counter: (function() { if (!simulatorUrl) { throw new Error("Missing environment variable: WING_SIMULATOR_URL"); } - return require("@winglang/sdk/lib/simulator/client").makeSimulatorClient(simulatorUrl, handle); + const caller = process.env.WING_SIMULATOR_CALLER; + if (!caller) { + throw new Error("Missing environment variable: WING_SIMULATOR_CALLER"); + } + return require("@winglang/sdk/lib/simulator/client").makeSimulatorClient(simulatorUrl, handle, caller); })(), bucket: (function() { let handle = process.env.BUCKET_HANDLE_5f2a41c8; @@ -39,7 +43,11 @@ bucket: (function() { if (!simulatorUrl) { throw new Error("Missing environment variable: WING_SIMULATOR_URL"); } - return require("@winglang/sdk/lib/simulator/client").makeSimulatorClient(simulatorUrl, handle); + const caller = process.env.WING_SIMULATOR_CALLER; + if (!caller) { + throw new Error("Missing environment variable: WING_SIMULATOR_CALLER"); + } + return require("@winglang/sdk/lib/simulator/client").makeSimulatorClient(simulatorUrl, handle, caller); })() }), args: {} })); return await $handler.handle(event); @@ -66,6 +74,54 @@ bucket: (function() { }, "simulator.json": { "resources": [ + { + "addr": "c86eb36bbe6e764a632afaaea5db2d4bd693c92624", + "attrs": {}, + "path": "root/HelloWorld/Bucket/Policy", + "props": { + "principal": "\${wsim#root/HelloWorld/Bucket#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, + { + "addr": "c86b009930462795eeb90e647a56dbfc5356d9ea80", + "attrs": {}, + "path": "root/HelloWorld/Queue/Policy", + "props": { + "principal": "\${wsim#root/HelloWorld/Queue#attrs.handle}", + "statements": [ + { + "operation": "invoke", + "resourceHandle": "\${wsim#root/HelloWorld/Queue/SetConsumer0#attrs.handle}", + }, + { + "operation": "hasAvailableWorkers", + "resourceHandle": "\${wsim#root/HelloWorld/Queue/SetConsumer0#attrs.handle}", + }, + ], + }, + "type": "@winglang/sdk.sim.Policy", + }, + { + "addr": "c88f4eae8103e33f1cf696aa3dad78ce4f1e5a2caa", + "attrs": {}, + "path": "root/HelloWorld/Queue/SetConsumer0/Policy", + "props": { + "principal": "\${wsim#root/HelloWorld/Queue/SetConsumer0#attrs.handle}", + "statements": [ + { + "operation": "inc", + "resourceHandle": "\${wsim#root/HelloWorld/Counter#attrs.handle}", + }, + { + "operation": "put", + "resourceHandle": "\${wsim#root/HelloWorld/Bucket#attrs.handle}", + }, + ], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c87855e817fa3df0d5ce8ae290bf53c8ce4ecd8d46", "attrs": {}, @@ -208,6 +264,14 @@ bucket: (function() { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -224,6 +288,21 @@ bucket: (function() { "HelloWorld": { "children": { "Bucket": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/HelloWorld/Bucket/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -249,6 +328,19 @@ bucket: (function() { }, "Queue": { "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/HelloWorld/Queue/Policy", + }, "QueueEventMapping0": { "constructInfo": { "fqn": "constructs.Construct", @@ -261,6 +353,21 @@ bucket: (function() { "path": "root/HelloWorld/Queue/QueueEventMapping0", }, "SetConsumer0": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/HelloWorld/Queue/SetConsumer0/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/function.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/function.test.ts.snap index f15ffe22fb8..685cdcef273 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/function.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/function.test.ts.snap @@ -1,16 +1,5 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`__dirname and __filename cannot be used within inflight code 1`] = ` -[ - "root/Function.0 started", - "root/Function.1 started", - "Warning: __dirname and __filename cannot be used within bundled cloud functions. There may be unexpected behavior.", - "Warning: __dirname and __filename cannot be used within bundled cloud functions. There may be unexpected behavior.", - "Invoke (payload=undefined).", - "Invoke (payload=undefined).", -] -`; - exports[`create a function 1`] = ` { ".wing/my_function_c85c4e0e.js": ""use strict"; @@ -64,6 +53,16 @@ async handle(event) { }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c8d421ed6ca2ddf857d835791bcde9240c8682a8d9", + "attrs": {}, + "path": "root/my_function/Policy", + "props": { + "principal": "\${wsim#root/my_function#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -139,6 +138,14 @@ async handle(event) { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -153,6 +160,21 @@ async handle(event) { "tree": { "children": { "my_function": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_function/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -180,7 +202,9 @@ async handle(event) { exports[`invoke function fails 1`] = ` [ "root/my_function started", + "root/my_function/Policy started", "Invoke (payload="{\\"name\\":\\"alice\\"}").", + "root/my_function/Policy stopped", "root/my_function stopped", ] `; @@ -236,6 +260,16 @@ async handle(event) { }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c8d421ed6ca2ddf857d835791bcde9240c8682a8d9", + "attrs": {}, + "path": "root/my_function/Policy", + "props": { + "principal": "\${wsim#root/my_function#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -311,6 +345,14 @@ async handle(event) { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -325,6 +367,21 @@ async handle(event) { "tree": { "children": { "my_function": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_function/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -352,7 +409,9 @@ async handle(event) { exports[`invoke function succeeds 1`] = ` [ "root/my_function started", + "root/my_function/Policy started", "Invoke (payload="{\\"name\\":\\"Alice\\"}").", + "root/my_function/Policy stopped", "root/my_function stopped", ] `; @@ -408,6 +467,16 @@ async handle(event) { }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c8d421ed6ca2ddf857d835791bcde9240c8682a8d9", + "attrs": {}, + "path": "root/my_function/Policy", + "props": { + "principal": "\${wsim#root/my_function#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -483,6 +552,14 @@ async handle(event) { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -497,6 +574,21 @@ async handle(event) { "tree": { "children": { "my_function": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_function/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -524,7 +616,9 @@ async handle(event) { exports[`invoke function with environment variables 1`] = ` [ "root/my_function started", + "root/my_function/Policy started", "Invoke (payload="{\\"name\\":\\"Alice\\"}").", + "root/my_function/Policy stopped", "root/my_function stopped", ] `; @@ -582,6 +676,16 @@ async handle(event) { }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c8d421ed6ca2ddf857d835791bcde9240c8682a8d9", + "attrs": {}, + "path": "root/my_function/Policy", + "props": { + "principal": "\${wsim#root/my_function#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -657,6 +761,14 @@ async handle(event) { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -671,6 +783,21 @@ async handle(event) { "tree": { "children": { "my_function": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_function/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -698,7 +825,9 @@ async handle(event) { exports[`invoke function with process.exit(1) 1`] = ` [ "root/my_function started", + "root/my_function/Policy started", "Invoke (payload="{}").", + "root/my_function/Policy stopped", "root/my_function stopped", ] `; @@ -744,6 +873,16 @@ async handle() { }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c8d421ed6ca2ddf857d835791bcde9240c8682a8d9", + "attrs": {}, + "path": "root/my_function/Policy", + "props": { + "principal": "\${wsim#root/my_function#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -819,6 +958,14 @@ async handle() { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -833,6 +980,21 @@ async handle() { "tree": { "children": { "my_function": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_function/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -966,6 +1128,16 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c80ba70b2cdb9a19bee761f329d38a2f8fe60dfd96", + "attrs": {}, + "path": "root/Function.0/Policy", + "props": { + "principal": "\${wsim#root/Function.0#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c89ed254f66166d83153cc0a4952a15be63d47b0d2", "attrs": {}, @@ -979,6 +1151,16 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c82b947659316c604ceae225ba418b0d37542a5ba9", + "attrs": {}, + "path": "root/Function.1/Policy", + "props": { + "principal": "\${wsim#root/Function.1#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c8cd6c39da22910102d0cfeb2cb96f2160fa79e517", "attrs": {}, @@ -992,6 +1174,16 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c84e1c1344ab5edfebbe25048f337b36bf0c9aed39", + "attrs": {}, + "path": "root/Function.2/Policy", + "props": { + "principal": "\${wsim#root/Function.2#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c8badafa75a67ff66740e0c5fbbb392ab574b52b3c", "attrs": {}, @@ -1005,6 +1197,16 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c808a620b5341fa15dc763e8b6ba15ff0ebfcc6240", + "attrs": {}, + "path": "root/Function.3/Policy", + "props": { + "principal": "\${wsim#root/Function.3#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -1080,6 +1282,14 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1094,6 +1304,21 @@ return class Handler { "tree": { "children": { "Function.0": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/Function.0/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1106,6 +1331,21 @@ return class Handler { "path": "root/Function.0", }, "Function.1": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/Function.1/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1118,6 +1358,21 @@ return class Handler { "path": "root/Function.1", }, "Function.2": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/Function.2/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1130,6 +1385,21 @@ return class Handler { "path": "root/Function.2", }, "Function.3": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/Function.3/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/immutable-capture.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/immutable-capture.test.ts.snap index 048de7a441c..afd9b0a28a7 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/immutable-capture.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/immutable-capture.test.ts.snap @@ -43,6 +43,16 @@ my_capture: ["hello","dude"] }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", + "attrs": {}, + "path": "root/Function/Policy", + "props": { + "principal": "\${wsim#root/Function#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -118,6 +128,14 @@ my_capture: ["hello","dude"] "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -132,6 +150,21 @@ my_capture: ["hello","dude"] "tree": { "children": { "Function": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/Function/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -199,6 +232,16 @@ my_array: [(new (require("[REDACTED]/wingsdk/src/std/duration.js").Duration)(600 }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", + "attrs": {}, + "path": "root/Function/Policy", + "props": { + "principal": "\${wsim#root/Function#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -274,6 +317,14 @@ my_array: [(new (require("[REDACTED]/wingsdk/src/std/duration.js").Duration)(600 "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -288,6 +339,21 @@ my_array: [(new (require("[REDACTED]/wingsdk/src/std/duration.js").Duration)(600 "tree": { "children": { "Function": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/Function/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -354,6 +420,16 @@ my_array: [new Map([["foo",1],["bar",2]]),new Map([["foo",3],["bar",4]])] }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", + "attrs": {}, + "path": "root/Function/Policy", + "props": { + "principal": "\${wsim#root/Function#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -429,6 +505,14 @@ my_array: [new Map([["foo",1],["bar",2]]),new Map([["foo",3],["bar",4]])] "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -443,6 +527,21 @@ my_array: [new Map([["foo",1],["bar",2]]),new Map([["foo",3],["bar",4]])] "tree": { "children": { "Function": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/Function/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -508,6 +607,16 @@ my_capture: false }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", + "attrs": {}, + "path": "root/Function/Policy", + "props": { + "principal": "\${wsim#root/Function#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -583,6 +692,14 @@ my_capture: false "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -597,6 +714,21 @@ my_capture: false "tree": { "children": { "Function": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/Function/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -664,6 +796,16 @@ my_capture: (new (require("[REDACTED]/wingsdk/src/std/duration.js").Duration)(72 }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", + "attrs": {}, + "path": "root/Function/Policy", + "props": { + "principal": "\${wsim#root/Function#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -739,6 +881,14 @@ my_capture: (new (require("[REDACTED]/wingsdk/src/std/duration.js").Duration)(72 "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -753,6 +903,21 @@ my_capture: (new (require("[REDACTED]/wingsdk/src/std/duration.js").Duration)(72 "tree": { "children": { "Function": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/Function/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -822,6 +987,16 @@ my_capture: new Map([["foo",123],["bar",456]]) }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", + "attrs": {}, + "path": "root/Function/Policy", + "props": { + "principal": "\${wsim#root/Function#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -897,6 +1072,14 @@ my_capture: new Map([["foo",123],["bar",456]]) "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -911,6 +1094,21 @@ my_capture: new Map([["foo",123],["bar",456]]) "tree": { "children": { "Function": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/Function/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -982,6 +1180,16 @@ my_map: new Map([["foo",[1,2]],["bar",[3,4]]]) }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", + "attrs": {}, + "path": "root/Function/Policy", + "props": { + "principal": "\${wsim#root/Function#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -1057,6 +1265,14 @@ my_map: new Map([["foo",[1,2]],["bar",[3,4]]]) "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1071,6 +1287,21 @@ my_map: new Map([["foo",[1,2]],["bar",[3,4]]]) "tree": { "children": { "Function": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/Function/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1139,6 +1370,16 @@ my_map: new Map([["foo",[(new (require("[REDACTED]/wingsdk/src/std/duration.js") }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", + "attrs": {}, + "path": "root/Function/Policy", + "props": { + "principal": "\${wsim#root/Function#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -1214,6 +1455,14 @@ my_map: new Map([["foo",[(new (require("[REDACTED]/wingsdk/src/std/duration.js") "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1228,6 +1477,21 @@ my_map: new Map([["foo",[(new (require("[REDACTED]/wingsdk/src/std/duration.js") "tree": { "children": { "Function": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/Function/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1293,6 +1557,16 @@ my_capture: 123 }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", + "attrs": {}, + "path": "root/Function/Policy", + "props": { + "principal": "\${wsim#root/Function#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -1368,6 +1642,14 @@ my_capture: 123 "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1382,6 +1664,21 @@ my_capture: 123 "tree": { "children": { "Function": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/Function/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1450,6 +1747,16 @@ my_capture: new Set(["boom","bam","bang"]) }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", + "attrs": {}, + "path": "root/Function/Policy", + "props": { + "principal": "\${wsim#root/Function#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -1525,6 +1832,14 @@ my_capture: new Set(["boom","bam","bang"]) "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1539,6 +1854,21 @@ my_capture: new Set(["boom","bam","bang"]) "tree": { "children": { "Function": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/Function/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1606,6 +1936,16 @@ my_set: new Set([(new (require("[REDACTED]/wingsdk/src/std/duration.js").Duratio }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", + "attrs": {}, + "path": "root/Function/Policy", + "props": { + "principal": "\${wsim#root/Function#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -1681,6 +2021,14 @@ my_set: new Set([(new (require("[REDACTED]/wingsdk/src/std/duration.js").Duratio "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1695,6 +2043,21 @@ my_set: new Set([(new (require("[REDACTED]/wingsdk/src/std/duration.js").Duratio "tree": { "children": { "Function": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/Function/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1761,6 +2124,16 @@ my_capture: "bam bam bam" }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", + "attrs": {}, + "path": "root/Function/Policy", + "props": { + "principal": "\${wsim#root/Function#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -1836,6 +2209,14 @@ my_capture: "bam bam bam" "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1850,6 +2231,21 @@ my_capture: "bam bam bam" "tree": { "children": { "Function": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/Function/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1918,6 +2314,16 @@ my_capture: {"hello": "dude","world": "cup","foo": "bar",} }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", + "attrs": {}, + "path": "root/Function/Policy", + "props": { + "principal": "\${wsim#root/Function#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -1993,6 +2399,14 @@ my_capture: {"hello": "dude","world": "cup","foo": "bar",} "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -2007,6 +2421,21 @@ my_capture: {"hello": "dude","world": "cup","foo": "bar",} "tree": { "children": { "Function": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/Function/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -2075,6 +2504,16 @@ my_struct: {"foo": new Map([["foo",1],["bar",2]]),"bar": new Map([["foo",3],["ba }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c82c6881e1717b3b64913c3a5c4d7843012f2897e9", + "attrs": {}, + "path": "root/Function/Policy", + "props": { + "principal": "\${wsim#root/Function#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -2150,6 +2589,14 @@ my_struct: {"foo": new Map([["foo",1],["bar",2]]),"bar": new Map([["foo",3],["ba "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -2164,6 +2611,21 @@ my_struct: {"foo": new Map([["foo",1],["bar",2]]),"bar": new Map([["foo",3],["ba "tree": { "children": { "Function": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/Function/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/on-deploy.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/on-deploy.test.ts.snap index c8e80855916..8f0db48a5f3 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/on-deploy.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/on-deploy.test.ts.snap @@ -38,11 +38,22 @@ return class Handler { }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c84ce37dba3dd1bd3d5c4ab27cb72c54e2b1a75821", + "attrs": {}, + "path": "root/my_on_deploy/Function/Policy", + "props": { + "principal": "\${wsim#root/my_on_deploy/Function#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c8e2618b976544550a8396a3817f0bad07099f7050", "attrs": {}, "deps": [ "root/my_on_deploy/Function", + "root/my_on_deploy/Function/Policy", ], "path": "root/my_on_deploy", "props": { @@ -125,6 +136,14 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -141,6 +160,21 @@ return class Handler { "my_on_deploy": { "children": { "Function": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_on_deploy/Function/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -181,11 +215,13 @@ return class Handler { exports[`create an OnDeploy 2`] = ` [ "root/my_on_deploy/Function started", + "root/my_on_deploy/Function/Policy started", "super duper success", "Invoke (payload=undefined).", "OnDeploy invoked.", "root/my_on_deploy started", "root/my_on_deploy stopped", + "root/my_on_deploy/Function/Policy stopped", "root/my_on_deploy/Function stopped", ] `; diff --git a/libs/wingsdk/test/target-sim/__snapshots__/queue.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/queue.test.ts.snap index 642f485ebdc..cef3a1a4097 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/queue.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/queue.test.ts.snap @@ -18,6 +18,16 @@ exports[`create a queue 1`] = ` }, "type": "@winglang/sdk.cloud.Queue", }, + { + "addr": "c88a4c68047871c2d322479c886423828e8119d85c", + "attrs": {}, + "path": "root/my_queue/Policy", + "props": { + "principal": "\${wsim#root/my_queue#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -93,6 +103,14 @@ exports[`create a queue 1`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -107,6 +125,21 @@ exports[`create a queue 1`] = ` "tree": { "children": { "my_queue": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_queue/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -585,7 +618,9 @@ async handle(message) { exports[`push rejects empty message 1`] = ` [ "root/my_queue started", + "root/my_queue/Policy started", "Push (messages=).", + "root/my_queue/Policy stopped", "root/my_queue stopped", ] `; @@ -608,6 +643,16 @@ exports[`push rejects empty message 2`] = ` }, "type": "@winglang/sdk.cloud.Queue", }, + { + "addr": "c88a4c68047871c2d322479c886423828e8119d85c", + "attrs": {}, + "path": "root/my_queue/Policy", + "props": { + "principal": "\${wsim#root/my_queue#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -683,6 +728,14 @@ exports[`push rejects empty message 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -697,6 +750,21 @@ exports[`push rejects empty message 2`] = ` "tree": { "children": { "my_queue": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_queue/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -724,11 +792,13 @@ exports[`push rejects empty message 2`] = ` exports[`queue batch size of 2, purge the queue 1`] = ` [ "root/my_queue started", + "root/my_queue/Policy started", "Push (messages=A).", "Push (messages=B).", "ApproxSize ().", "Purge ().", "ApproxSize ().", + "root/my_queue/Policy stopped", "root/my_queue stopped", ] `; @@ -751,6 +821,16 @@ exports[`queue batch size of 2, purge the queue 2`] = ` }, "type": "@winglang/sdk.cloud.Queue", }, + { + "addr": "c88a4c68047871c2d322479c886423828e8119d85c", + "attrs": {}, + "path": "root/my_queue/Policy", + "props": { + "principal": "\${wsim#root/my_queue#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -826,6 +906,14 @@ exports[`queue batch size of 2, purge the queue 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -840,6 +928,21 @@ exports[`queue batch size of 2, purge the queue 2`] = ` "tree": { "children": { "my_queue": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_queue/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -895,7 +998,11 @@ queue: (function() { if (!simulatorUrl) { throw new Error("Missing environment variable: WING_SIMULATOR_URL"); } - return require("@winglang/sdk/lib/simulator/client").makeSimulatorClient(simulatorUrl, handle); + const caller = process.env.WING_SIMULATOR_CALLER; + if (!caller) { + throw new Error("Missing environment variable: WING_SIMULATOR_CALLER"); + } + return require("@winglang/sdk/lib/simulator/client").makeSimulatorClient(simulatorUrl, handle, caller); })() })); return await $handler.handle(event); @@ -939,6 +1046,35 @@ async handle(message) { }, "simulator.json": { "resources": [ + { + "addr": "c88a4c68047871c2d322479c886423828e8119d85c", + "attrs": {}, + "path": "root/my_queue/Policy", + "props": { + "principal": "\${wsim#root/my_queue#attrs.handle}", + "statements": [ + { + "operation": "invoke", + "resourceHandle": "\${wsim#root/my_queue/SetConsumer0#attrs.handle}", + }, + { + "operation": "hasAvailableWorkers", + "resourceHandle": "\${wsim#root/my_queue/SetConsumer0#attrs.handle}", + }, + ], + }, + "type": "@winglang/sdk.sim.Policy", + }, + { + "addr": "c850ec3b050199141fa07ce182e2e0711e60d2d193", + "attrs": {}, + "path": "root/my_queue/SetConsumer0/Policy", + "props": { + "principal": "\${wsim#root/my_queue/SetConsumer0#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c8e33b9b91c909e579b9d3d703146eb66c2a657ffc", "attrs": {}, @@ -997,11 +1133,27 @@ async handle(message) { }, "type": "@winglang/sdk.cloud.Function", }, + { + "addr": "c8a0157ce3fdc8f4da43f974ef4b722745f359650f", + "attrs": {}, + "path": "root/my_queue_messages/Function/Policy", + "props": { + "principal": "\${wsim#root/my_queue_messages/Function#attrs.handle}", + "statements": [ + { + "operation": "push", + "resourceHandle": "\${wsim#root/my_queue#attrs.handle}", + }, + ], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c8e2354407fd3536187725c2b37c5327f47bb841e9", "attrs": {}, "deps": [ "root/my_queue_messages/Function", + "root/my_queue_messages/Function/Policy", ], "path": "root/my_queue_messages", "props": { @@ -1084,6 +1236,14 @@ async handle(message) { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1099,6 +1259,19 @@ async handle(message) { "children": { "my_queue": { "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_queue/Policy", + }, "QueueEventMapping0": { "constructInfo": { "fqn": "constructs.Construct", @@ -1111,6 +1284,21 @@ async handle(message) { "path": "root/my_queue/QueueEventMapping0", }, "SetConsumer0": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_queue/SetConsumer0/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1138,6 +1326,21 @@ async handle(message) { "my_queue_messages": { "children": { "Function": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_queue_messages/Function/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -1211,6 +1414,35 @@ async handle(message) { }, "simulator.json": { "resources": [ + { + "addr": "c88a4c68047871c2d322479c886423828e8119d85c", + "attrs": {}, + "path": "root/my_queue/Policy", + "props": { + "principal": "\${wsim#root/my_queue#attrs.handle}", + "statements": [ + { + "operation": "invoke", + "resourceHandle": "\${wsim#root/my_queue/SetConsumer0#attrs.handle}", + }, + { + "operation": "hasAvailableWorkers", + "resourceHandle": "\${wsim#root/my_queue/SetConsumer0#attrs.handle}", + }, + ], + }, + "type": "@winglang/sdk.sim.Policy", + }, + { + "addr": "c850ec3b050199141fa07ce182e2e0711e60d2d193", + "attrs": {}, + "path": "root/my_queue/SetConsumer0/Policy", + "props": { + "principal": "\${wsim#root/my_queue/SetConsumer0#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c8e33b9b91c909e579b9d3d703146eb66c2a657ffc", "attrs": {}, @@ -1326,6 +1558,14 @@ async handle(message) { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -1341,6 +1581,19 @@ async handle(message) { "children": { "my_queue": { "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_queue/Policy", + }, "QueueEventMapping0": { "constructInfo": { "fqn": "constructs.Construct", @@ -1353,6 +1606,21 @@ async handle(message) { "path": "root/my_queue/QueueEventMapping0", }, "SetConsumer0": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_queue/SetConsumer0/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/redis.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/redis.test.ts.snap index f20b4825304..69133a45443 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/redis.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/redis.test.ts.snap @@ -104,6 +104,14 @@ exports[`create a Redis resource 1`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/schedule.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/schedule.test.ts.snap index c845a045772..1b3ff0eaf05 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/schedule.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/schedule.test.ts.snap @@ -17,6 +17,16 @@ exports[`create a schedule 1`] = ` }, "type": "@winglang/sdk.cloud.Schedule", }, + { + "addr": "c8c7f555c253f79a2cdcd8a13c6772cfd654e2bf0b", + "attrs": {}, + "path": "root/my_schedule/Policy", + "props": { + "principal": "\${wsim#root/my_schedule#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -92,6 +102,14 @@ exports[`create a schedule 1`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -106,6 +124,21 @@ exports[`create a schedule 1`] = ` "tree": { "children": { "my_schedule": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_schedule/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -164,6 +197,31 @@ console.log("Hello from schedule!"); }, "simulator.json": { "resources": [ + { + "addr": "c8c7f555c253f79a2cdcd8a13c6772cfd654e2bf0b", + "attrs": {}, + "path": "root/my_schedule/Policy", + "props": { + "principal": "\${wsim#root/my_schedule#attrs.handle}", + "statements": [ + { + "operation": "invoke", + "resourceHandle": "\${wsim#root/my_schedule/OnTick0#attrs.handle}", + }, + ], + }, + "type": "@winglang/sdk.sim.Policy", + }, + { + "addr": "c8d61fcab25f1c27fcb0f0ba29e4888a7041c8029f", + "attrs": {}, + "path": "root/my_schedule/OnTick0/Policy", + "props": { + "principal": "\${wsim#root/my_schedule/OnTick0#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c83eddbe8512d15b84969a611d4b5ca9ce55e1f808", "attrs": {}, @@ -276,6 +334,14 @@ console.log("Hello from schedule!"); "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -292,6 +358,21 @@ console.log("Hello from schedule!"); "my_schedule": { "children": { "OnTick0": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_schedule/OnTick0/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -315,6 +396,19 @@ console.log("Hello from schedule!"); "id": "OnTickMapping0", "path": "root/my_schedule/OnTickMapping0", }, + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_schedule/Policy", + }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -374,6 +468,31 @@ console.log("Hello from schedule!"); }, "simulator.json": { "resources": [ + { + "addr": "c8c7f555c253f79a2cdcd8a13c6772cfd654e2bf0b", + "attrs": {}, + "path": "root/my_schedule/Policy", + "props": { + "principal": "\${wsim#root/my_schedule#attrs.handle}", + "statements": [ + { + "operation": "invoke", + "resourceHandle": "\${wsim#root/my_schedule/OnTick0#attrs.handle}", + }, + ], + }, + "type": "@winglang/sdk.sim.Policy", + }, + { + "addr": "c8d61fcab25f1c27fcb0f0ba29e4888a7041c8029f", + "attrs": {}, + "path": "root/my_schedule/OnTick0/Policy", + "props": { + "principal": "\${wsim#root/my_schedule/OnTick0#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c83eddbe8512d15b84969a611d4b5ca9ce55e1f808", "attrs": {}, @@ -486,6 +605,14 @@ console.log("Hello from schedule!"); "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -502,6 +629,21 @@ console.log("Hello from schedule!"); "my_schedule": { "children": { "OnTick0": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_schedule/OnTick0/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -525,6 +667,19 @@ console.log("Hello from schedule!"); "id": "OnTickMapping0", "path": "root/my_schedule/OnTickMapping0", }, + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_schedule/Policy", + }, }, "constructInfo": { "fqn": "constructs.Construct", @@ -584,6 +739,31 @@ console.log("Hello from schedule!"); }, "simulator.json": { "resources": [ + { + "addr": "c8c7f555c253f79a2cdcd8a13c6772cfd654e2bf0b", + "attrs": {}, + "path": "root/my_schedule/Policy", + "props": { + "principal": "\${wsim#root/my_schedule#attrs.handle}", + "statements": [ + { + "operation": "invoke", + "resourceHandle": "\${wsim#root/my_schedule/OnTick0#attrs.handle}", + }, + ], + }, + "type": "@winglang/sdk.sim.Policy", + }, + { + "addr": "c8d61fcab25f1c27fcb0f0ba29e4888a7041c8029f", + "attrs": {}, + "path": "root/my_schedule/OnTick0/Policy", + "props": { + "principal": "\${wsim#root/my_schedule/OnTick0#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, { "addr": "c83eddbe8512d15b84969a611d4b5ca9ce55e1f808", "attrs": {}, @@ -696,6 +876,14 @@ console.log("Hello from schedule!"); "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -712,6 +900,21 @@ console.log("Hello from schedule!"); "my_schedule": { "children": { "OnTick0": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_schedule/OnTick0/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", @@ -735,6 +938,19 @@ console.log("Hello from schedule!"); "id": "OnTickMapping0", "path": "root/my_schedule/OnTickMapping0", }, + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_schedule/Policy", + }, }, "constructInfo": { "fqn": "constructs.Construct", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/secret.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/secret.test.ts.snap index 50ee1bf1a06..debe797f8d9 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/secret.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/secret.test.ts.snap @@ -92,6 +92,14 @@ exports[`create a secret 1`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/service.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/service.test.ts.snap index 8ec8e96fba0..f47c105b1ca 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/service.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/service.test.ts.snap @@ -45,12 +45,35 @@ return class Handler { "attrs": {}, "path": "root/my_service", "props": { - "autoStart": true, "environmentVariables": {}, "sourceCodeFile": ".wing/my_service_c815f66e.js", }, "type": "@winglang/sdk.cloud.Service", }, + { + "addr": "c845f08fe23811b5ba949f822a6bc3077a050f801b", + "attrs": {}, + "path": "root/my_service/Policy", + "props": { + "principal": "\${wsim#root/my_service#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, + { + "addr": "c810e24e6e3ab8b88ceddbbe1ac7323d46de30a969", + "attrs": {}, + "deps": [ + "root/my_service", + "root/my_service/Policy", + ], + "path": "root/my_service/Helper", + "props": { + "autoStart": true, + "service": "\${wsim#root/my_service#attrs.handle}", + }, + "type": "@winglang/sdk.sim.ServiceHelper", + }, ], "sdkVersion": "0.0.0", "types": { @@ -126,6 +149,14 @@ return class Handler { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -140,6 +171,32 @@ return class Handler { "tree": { "children": { "my_service": { + "children": { + "Helper": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "hidden": true, + }, + "id": "Helper", + "path": "root/my_service/Helper", + }, + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_service/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/table.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/table.test.ts.snap index 4ac0d3b25cd..470f510adec 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/table.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/table.test.ts.snap @@ -113,6 +113,14 @@ exports[`can add row in preflight 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -249,6 +257,14 @@ exports[`create a table 1`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -395,6 +411,14 @@ exports[`get row 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -539,6 +563,14 @@ exports[`insert row 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -685,6 +717,14 @@ exports[`list table 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -830,6 +870,14 @@ exports[`tryGet row 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -978,6 +1026,14 @@ exports[`update row 2`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/test.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/test.test.ts.snap index 9fa84c5ea50..05c7d3fded0 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/test.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/test.test.ts.snap @@ -55,6 +55,16 @@ async handle(event) { }, "type": "@winglang/sdk.std.TestRunner", }, + { + "addr": "c8e9f1ae266f81e04ffcbb951317b09fa72e8ad7cb", + "attrs": {}, + "path": "root/env0/test:my_test/Handler/Policy", + "props": { + "principal": "\${wsim#root/env0/test:my_test/Handler#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -130,6 +140,14 @@ async handle(event) { "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -161,6 +179,21 @@ async handle(event) { "test:my_test": { "children": { "Handler": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/env0/test:my_test/Handler/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/topic-producer.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/topic-producer.test.ts.snap index 22c43627674..56a208842d6 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/topic-producer.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/topic-producer.test.ts.snap @@ -2,16 +2,23 @@ exports[`publishing messages to topic 1`] = ` [ - "root/TopicTester/MyTopic/OnMessage0 started", "root/TopicTester/MyTopic started", + "root/TopicTester/MyTopic/OnMessage0 started", + "root/TopicTester/MyTopic/Policy started", + "root/TopicTester/MyTopic/OnMessage0/Policy started", "root/TopicTester/MyTopic/TopicEventMapping0 started", "root/TopicTester/Function started", + "root/TopicTester/Function/Policy started", "Publish (message=ABC).", - "Sending message (message=ABC, subscriber=sim-0).", + "Sending message (message=ABC, subscriber=sim-1).", "InvokeAsync (payload="ABC").", "Invoke (payload="ABC").", + "Message received", + "root/TopicTester/MyTopic/Policy stopped", + "root/TopicTester/MyTopic/OnMessage0/Policy stopped", "root/TopicTester/MyTopic/TopicEventMapping0 stopped", "root/TopicTester/MyTopic/OnMessage0 stopped", + "root/TopicTester/Function/Policy stopped", "root/TopicTester/Function stopped", "root/TopicTester/MyTopic stopped", ] diff --git a/libs/wingsdk/test/target-sim/__snapshots__/topic.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/topic.test.ts.snap index f846cbccf14..be384dbb3fb 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/topic.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/topic.test.ts.snap @@ -15,6 +15,16 @@ exports[`create a topic 1`] = ` "props": {}, "type": "@winglang/sdk.cloud.Topic", }, + { + "addr": "c8635ef174eab9aa010e5bed09a712307a6b70e731", + "attrs": {}, + "path": "root/my_topic/Policy", + "props": { + "principal": "\${wsim#root/my_topic#attrs.handle}", + "statements": [], + }, + "type": "@winglang/sdk.sim.Policy", + }, ], "sdkVersion": "0.0.0", "types": { @@ -90,6 +100,14 @@ exports[`create a topic 1`] = ` "className": "EventMapping", "sourcePath": "/event-mapping.inflight.js", }, + "@winglang/sdk.sim.Policy": { + "className": "Policy", + "sourcePath": "/policy.inflight.js", + }, + "@winglang/sdk.sim.ServiceHelper": { + "className": "ServiceHelper", + "sourcePath": "/service.inflight.js", + }, "@winglang/sdk.sim.State": { "className": "State", "sourcePath": "/state.inflight.js", @@ -104,6 +122,21 @@ exports[`create a topic 1`] = ` "tree": { "children": { "my_topic": { + "children": { + "Policy": { + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0", + }, + "display": { + "description": "A simulated resource policy", + "hidden": true, + "title": "Policy", + }, + "id": "Policy", + "path": "root/my_topic/Policy", + }, + }, "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0", diff --git a/libs/wingsdk/test/target-sim/app.test.ts b/libs/wingsdk/test/target-sim/app.test.ts index 13ddf565a43..b071c6f0526 100644 --- a/libs/wingsdk/test/target-sim/app.test.ts +++ b/libs/wingsdk/test/target-sim/app.test.ts @@ -48,7 +48,10 @@ test("tests do not synthesize functions when test mode is off", async () => { await s.stop(); // THEN - expect(resources.sort()).toEqual(["root/Default/my_bucket"]); + expect(resources.sort()).toEqual([ + "root/Default/my_bucket", + "root/Default/my_bucket/Policy", + ]); }); test("tests are synthesized into individual environments when test mode is on", async () => { @@ -73,8 +76,12 @@ test("tests are synthesized into individual environments when test mode is on", expect(resources.sort()).toEqual([ "root/cloud.TestRunner", "root/env0/my_bucket", + "root/env0/my_bucket/Policy", "root/env0/test:my_test1/Handler", + "root/env0/test:my_test1/Handler/Policy", "root/env1/my_bucket", + "root/env1/my_bucket/Policy", "root/env1/test:my_test2/Handler", + "root/env1/test:my_test2/Handler/Policy", ]); }); diff --git a/libs/wingsdk/test/target-sim/bucket.test.ts b/libs/wingsdk/test/target-sim/bucket.test.ts index 959449fac72..5d07e2f1a34 100644 --- a/libs/wingsdk/test/target-sim/bucket.test.ts +++ b/libs/wingsdk/test/target-sim/bucket.test.ts @@ -39,7 +39,9 @@ test("update an object in bucket", async () => { // GIVEN const app = new SimApp(); const bucket = new cloud.Bucket(app, "my_bucket"); - const testInflight = Testing.makeHandler("async handle() {}"); + const testInflight = Testing.makeHandler( + "async handle() { console.log('I am done'); }" + ); bucket.onCreate(testInflight); const s = await app.startSimulator(); @@ -48,13 +50,17 @@ test("update an object in bucket", async () => { // WHEN await client.put(KEY, JSON.stringify({ msg: "Hello world 1!" })); - await waitUntilTraceCount(s, 4, (trace) => trace.data.message.includes(KEY)); await client.put(KEY, JSON.stringify({ msg: "Hello world 2!" })); - await waitUntilTraceCount(s, 5, (trace) => trace.data.message.includes(KEY)); + await waitUntilTraceCount(s, 1, (trace) => + trace.data.message.includes(`I am done`) + ); // THEN - expect(listMessages(s)).toMatchSnapshot(); await s.stop(); + expect(listMessages(s)).toMatchSnapshot(); + // The bucket notification topic should only publish one message, since the + // second put() call counts as an update, not a create. + expect(listMessages(s).filter((m) => m.includes(`Publish`))).toHaveLength(1); }); test("bucket on event creates 3 topics, and sends the right event and key in the event handlers", async () => { @@ -331,7 +337,7 @@ test("get invalid object throws an error", async () => { await s.stop(); expect(listMessages(s)).toMatchSnapshot(); - expect(s.listTraces()[1].data.status).toEqual("failure"); + expect(s.listTraces()[2].data.status).toEqual("failure"); expect(app.snapshot()).toMatchSnapshot(); }); diff --git a/libs/wingsdk/test/target-sim/function.test.ts b/libs/wingsdk/test/target-sim/function.test.ts index a140e353e37..d791254362c 100644 --- a/libs/wingsdk/test/target-sim/function.test.ts +++ b/libs/wingsdk/test/target-sim/function.test.ts @@ -130,7 +130,7 @@ test("invoke function fails", async () => { await s.stop(); expect(listMessages(s)).toMatchSnapshot(); - expect(s.listTraces()[1].data.error).toMatchObject({ + expect(s.listTraces()[2].data.error).toMatchObject({ message: "Name must start with uppercase letter", }); expect(app.snapshot()).toMatchSnapshot(); @@ -190,13 +190,13 @@ test("invoke function with process.exit(1)", async () => { // WHEN const PAYLOAD = {}; await expect(client.invoke(JSON.stringify(PAYLOAD))).rejects.toThrow( - "Process exited with code 1" + "Process exited with code 1, signal null" ); // THEN await s.stop(); expect(listMessages(s)).toMatchSnapshot(); - expect(s.listTraces()[1].data.error).toMatchObject({ - message: "Process exited with code 1", + expect(s.listTraces()[2].data.error).toMatchObject({ + message: "Process exited with code 1, signal null", }); expect(app.snapshot()).toMatchSnapshot(); }); @@ -247,5 +247,13 @@ test("__dirname and __filename cannot be used within inflight code", async () => await dirnameInvoker(s); await filenameInvoker(s); - expect(listMessages(s)).toMatchSnapshot(); + await s.stop(); + + expect( + listMessages(s).filter((m) => + m.includes( + "Warning: __dirname and __filename cannot be used within bundled cloud functions." + ) + ) + ).toHaveLength(2); }); diff --git a/libs/wingsdk/test/target-sim/on-deploy.test.ts b/libs/wingsdk/test/target-sim/on-deploy.test.ts index 1aa9077b3fe..a2df5e6042e 100644 --- a/libs/wingsdk/test/target-sim/on-deploy.test.ts +++ b/libs/wingsdk/test/target-sim/on-deploy.test.ts @@ -18,7 +18,7 @@ test("create an OnDeploy", async () => { attrs: { handle: expect.any(String), }, - deps: ["root/my_on_deploy/Function"], + deps: ["root/my_on_deploy/Function", "root/my_on_deploy/Function/Policy"], path: "root/my_on_deploy", addr: expect.any(String), props: { diff --git a/libs/wingsdk/test/target-sim/queue.test.ts b/libs/wingsdk/test/target-sim/queue.test.ts index 8941c55c0bc..047e5ee6b4d 100644 --- a/libs/wingsdk/test/target-sim/queue.test.ts +++ b/libs/wingsdk/test/target-sim/queue.test.ts @@ -369,6 +369,6 @@ test("push rejects empty message", async () => { await s.stop(); expect(listMessages(s)).toMatchSnapshot(); - expect(s.listTraces()[1].data.status).toEqual("failure"); + expect(s.listTraces()[2].data.status).toEqual("failure"); expect(app.snapshot()).toMatchSnapshot(); }); diff --git a/libs/wingsdk/test/target-sim/service.test.ts b/libs/wingsdk/test/target-sim/service.test.ts index b783cc91e63..7848eacad36 100644 --- a/libs/wingsdk/test/target-sim/service.test.ts +++ b/libs/wingsdk/test/target-sim/service.test.ts @@ -32,7 +32,6 @@ test("create a service with on start method", async () => { props: { sourceCodeFile: expect.any(String), environmentVariables: {}, - autoStart: true, }, type: cloud.SERVICE_FQN, }); @@ -63,7 +62,6 @@ test("create a service with a on stop method", async () => { props: { sourceCodeFile: expect.any(String), environmentVariables: {}, - autoStart: true, }, type: cloud.SERVICE_FQN, }); @@ -76,8 +74,8 @@ test("create a service with a on stop method", async () => { .filter((v) => v.sourceType == cloud.SERVICE_FQN) .map((trace) => trace.data.message) ).toEqual([ - "start!", "root/my_service started", + "start!", "stop!", "root/my_service stopped", ]); @@ -106,7 +104,6 @@ test("create a service without autostart", async () => { props: { sourceCodeFile: expect.any(String), environmentVariables: {}, - autoStart: false, }, type: cloud.SERVICE_FQN, }); diff --git a/libs/wingsdk/test/target-sim/topic-producer.test.ts b/libs/wingsdk/test/target-sim/topic-producer.test.ts index 168ee5e95e7..afe43c76cb4 100644 --- a/libs/wingsdk/test/target-sim/topic-producer.test.ts +++ b/libs/wingsdk/test/target-sim/topic-producer.test.ts @@ -1,6 +1,6 @@ import { Construct } from "constructs"; import { test, expect } from "vitest"; -import { listMessages } from "./util"; +import { listMessages, waitUntilTraceCount } from "./util"; import * as cloud from "../../src/cloud"; import { Testing } from "../../src/simulator"; import { SimApp } from "../sim-app"; @@ -27,6 +27,7 @@ test("publishing messages to topic", async () => { const processor = Testing.makeHandler(`async handle(event) { if (event.message === "") throw new Error("No message recieved"); + console.log("Message received"); }`); topic.onMessage(processor); } @@ -44,6 +45,10 @@ test("publishing messages to topic", async () => { // WHEN await publisher.invoke("ABC"); + await waitUntilTraceCount(s, 1, (trace) => + trace.data.message.includes("Message received") + ); + // THEN await s.stop(); diff --git a/libs/wingsdk/test/target-sim/util.ts b/libs/wingsdk/test/target-sim/util.ts index de8c41ed6fb..07aab70729f 100644 --- a/libs/wingsdk/test/target-sim/util.ts +++ b/libs/wingsdk/test/target-sim/util.ts @@ -29,7 +29,7 @@ export interface IScopeCallback { (scope: Construct): void; } -export function listMessages(s: Simulator) { +export function listMessages(s: Simulator): string[] { const message = s.listTraces().map((trace) => trace.data.message); // Redact any messages containing port numbers return message.map((m) => diff --git a/libs/wingsdk/test/ui/__snapshots__/ui.test.ts.snap b/libs/wingsdk/test/ui/__snapshots__/ui.test.ts.snap index 013056fac0d..8fb72eef1b3 100644 --- a/libs/wingsdk/test/ui/__snapshots__/ui.test.ts.snap +++ b/libs/wingsdk/test/ui/__snapshots__/ui.test.ts.snap @@ -3,10 +3,14 @@ exports[`can obtain ui components 1`] = ` [ "root/MyClass/Button/Handler started", + "root/MyClass/Button/Handler/Policy started", "root/MyClass/Field/Handler started", + "root/MyClass/Field/Handler/Policy started", "Invoke (payload="").", "Invoke (payload="").", + "root/MyClass/Button/Handler/Policy stopped", "root/MyClass/Button/Handler stopped", + "root/MyClass/Field/Handler/Policy stopped", "root/MyClass/Field/Handler stopped", ] `; diff --git a/tools/hangar/__snapshots__/invalid.ts.snap b/tools/hangar/__snapshots__/invalid.ts.snap index a44e6108b80..72cf9c4ddd0 100644 --- a/tools/hangar/__snapshots__/invalid.ts.snap +++ b/tools/hangar/__snapshots__/invalid.ts.snap @@ -3558,6 +3558,32 @@ Test Files 1 failed (1) Duration " `; +exports[`simulator_permissions.test.w 1`] = ` +"fail ┌ simulator_permissions.test.wsim » root/env0/test:incorrect resource permission + │ Error: Resource \\"root/env0/test:incorrect resource permission/Handler\\" does not have permission to perform operation \\"put\\" on resource \\"root/env0/b1\\". + │ --> ../../../examples/tests/invalid/simulator_permissions.test.w:15:3 + │ | while i > 0 { + │ | i -= 1; + │ | } + │ 15 | buckets.at(i).put(\\"key\\", \\"value\\"); + │ | ^ + └ at /simulator_permissions.test.w:15:3 +fail ┌ simulator_permissions.test.wsim » root/env1/test:incorrect permission operation + │ Error: Resource \\"root/env1/test:incorrect permission operation/Handler\\" does not have permission to perform operation \\"put\\" on resource \\"root/env1/b1\\". + │ --> ../../../examples/tests/invalid/simulator_permissions.test.w:25:3 + │ | while i > 0 { + │ | i -= 1; + │ | } + │ 25 | buckets.at(i).put(\\"key\\", \\"value\\"); + │ | ^ + └ at /simulator_permissions.test.w:25:3 + + +Tests 2 failed (2) +Test Files 1 failed (1) +Duration " +`; + exports[`sorted_errors_no_span.test.w 1`] = ` "error: Expected type to be \\"num\\", but got \\"str\\" instead --> ../../../examples/tests/invalid/sorted_errors_no_span.test.w:1:14