This message was deleted.
# typescript
s
This message was deleted.
s
can you post a larger snippet of your code? maybe there's a better way to structure it to avoid dealing with these array outputs
c
Hmm I can try, I've been trying to keep the code somewhat "clean" meaning I try to separate the configuration part and the create pulumi objects part. The function that creates all clients, resourceservers and grants looks like this
Copy code
export async function setupApplications(
  auth0Provider: Auth0Provider,
  gcpProvider: GcpProvider,
  tenant: Tenant,
  project: Project,
  importResource: Importer,
) {
  const readSecret = secretAccessor(gcpProvider, "big-hero-0");

  const clients: Client[] = await setupClients(auth0Provider, readSecret, tenant, project, importResource);

  const resourceServers: ResourceServer[] = await setupResourceServers(auth0Provider, readSecret, project, importResource);

  const grants: ClientGrant[] = await setupClientGrants(
    auth0Provider,
    readSecret,
    tenant,
    project,
    importResource,
    clients,
    resourceServers,
  );
}
the setupClients and setupResourceServers both look like this
Copy code
async function setupClients(
  auth0Provider: Auth0Provider,
  readSecret: ReadSecret,
  tenant: Tenant,
  project: Project,
  importResource: Importer,
) {
  const definitions = await getAuth0ClientsForTenant(readSecret, tenant, project);
  return await Promise.all(
    definitions.map(
      async (client) =>
        new Client(client.name, client, {
          provider: auth0Provider,
          import: await importResource("client", client.name),
          // We never want to delete clients since this would destroy client id / secret, so protect them.
          protect: true,
        }),
    ),
  );
}
'definitions' are typescript types that modify the Pulumi auth0
RandomResourceTypeArgs
types to have a 'static' (non-output) name that is identifiable across tenants so that those can be used for importing existing resources
FYI I found a way to fix this. I started doing this pattern where, when I create resources, I create maps containing their
string
name and
Output<string>
id. Looks a bit like this
Copy code
async function setupResourceServers(
  auth0Provider: Auth0Provider,
  readSecret: ReadSecret,
  project: Project,
  importResource: Importer,
) {
  const definitions = await getAuth0Apis(readSecret, project);
  const entries = await Promise.all(
    definitions.map(async (resourceServer) => {
      const res = new ResourceServer(resourceServer.name, resourceServer, {
        provider: auth0Provider,
        import: await importResource("resource-server", resourceServer.name),
        // We never want to delete resource servers
        protect: true,
      });
      return [resourceServer.name, res.identifier] as const;
    }),
  );
  return new Map(entries);
}
So when I create resources depending on others, I can pass through those maps to access their id's 😄
s
glad you found a solution. want to point out though that in some cases it might be best to create resources adjacent to each other, e.g. start with an array of data and then create and return the client, resourceServer, and clientGrant within the
.map
so in the end you have an
Array<{client: Client, resourceServer: ResourceServer, clientGrant: ClientGrant}>
c
Yeah agreed. I tried to make the structure of the project align with how the auth0 management dashboard is organised so you could "easily" find what you need