@tailor-platform/sdk 0.9.0 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,60 @@
1
1
  # @tailor-platform/sdk
2
2
 
3
+ ## 0.10.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#34](https://github.com/tailor-platform/sdk/pull/34) [`ed71900`](https://github.com/tailor-platform/sdk/commit/ed719007420794d50d26eb2a3f1f77c5bb3e60a9) Thanks [@remiposo](https://github.com/remiposo)! - Reference external resources
8
+
9
+ You can now add resources managed by Terraform or other SDK projects to your application's subgraph for shared use.
10
+ In this case, the resources themselves are not deployed.
11
+
12
+ ```typescript
13
+ defineConfig({
14
+ name: "ref-app",
15
+ db: {
16
+ "shared-db": { external: true },
17
+ },
18
+ resolver: { "shared-resolver": { external: true } },
19
+ auth: { name: "shared-auth", external: true },
20
+ idp: [{ name: "shared-idp", external: true }],
21
+ });
22
+ ```
23
+
24
+ - [#36](https://github.com/tailor-platform/sdk/pull/36) [`00701da`](https://github.com/tailor-platform/sdk/commit/00701da46ceb9624b58c123fcf0ff19e4dc513f5) Thanks [@remiposo](https://github.com/remiposo)! - Allow specifying the path where types are generated
25
+
26
+ By default, types are generated inside `node_modules/@tailor-platform/sdk` based on env and attribute settings, but you can now change the path with `TAILOR_PLATFORM_SDK_TYPE_PATH`.
27
+ This is primarily an option for developers, preventing type definitions from being overridden when working with multiple SDK projects simultaneously.
28
+
29
+ ## 0.10.0
30
+
31
+ ### Minor Changes
32
+
33
+ - [#25](https://github.com/tailor-platform/sdk/pull/25) [`50069ae`](https://github.com/tailor-platform/sdk/commit/50069aeebeb1c0e09cf66f660367cd26cc565f29) Thanks [@haru0017](https://github.com/haru0017)! - Define environment variables in `defineConfig()` and access them in resolvers and executors via the `env` parameter.
34
+
35
+ ```typescript
36
+ export default defineConfig({
37
+ name: "my-app",
38
+ env: { logLevel: "debug", cacheTtl: 3600 },
39
+ });
40
+
41
+ // Access in resolver
42
+ body: ({ input, env }) => {
43
+ // env.logLevel, env.cacheTtl available with full type safety
44
+ };
45
+ ```
46
+
47
+ ### Patch Changes
48
+
49
+ - [#33](https://github.com/tailor-platform/sdk/pull/33) [`1f73bd1`](https://github.com/tailor-platform/sdk/commit/1f73bd1d7abaa0a55358086a0d1b7f7c00cccbf3) Thanks [@remiposo](https://github.com/remiposo)! - Confirm important resource deletion
50
+
51
+ Added a confirmation prompt when attempting to delete resources that would result in data loss (tailordb and staticwebsite).
52
+ This can be skipped with the `--yes` flag.
53
+
54
+ - [#31](https://github.com/tailor-platform/sdk/pull/31) [`5fc5594`](https://github.com/tailor-platform/sdk/commit/5fc5594e0b7b1cdf72dadce505aa58a8ae2e5f4a) Thanks [@remiposo](https://github.com/remiposo)! - Make appName for the Executor's GraphQL target optional
55
+
56
+ The default value is its own application name.
57
+
3
58
  ## 0.9.0
4
59
 
5
60
  ### Minor Changes
@@ -1,6 +1,6 @@
1
1
  /// <reference path="./../plugin-generated.d.ts" />
2
2
 
3
- import { AppConfig, CodeGeneratorBase, Executor, Generator, Resolver, TailorDBTypeConfig } from "../types-CPcmGK_X.mjs";
3
+ import { AppConfig, CodeGeneratorBase, Executor, Generator, Resolver, TailorDBTypeConfig } from "../types-Dyhfh5b6.mjs";
4
4
  import "citty";
5
5
  import "zod";
6
6
  import "@bufbuild/protobuf/wkt";
package/dist/cli/api.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { apply, generate, generateUserTypes, loadConfig, machineUserList, machineUserToken, show, workspaceCreate, workspaceDelete, workspaceList } from "../token-DwKmpi9i.mjs";
1
+ import { apply, generate, generateUserTypes, loadConfig, machineUserList, machineUserToken, show, workspaceCreate, workspaceDelete, workspaceList } from "../token-LAqSDm3f.mjs";
2
2
  import "../auth-Di3vQUrT.mjs";
3
3
 
4
4
  export { apply, generate, generateUserTypes, loadConfig, machineUserList, machineUserToken, show, workspaceCreate, workspaceDelete, workspaceList };
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { PATScope, applyCommand, commonArgs, createCommand, deleteCommand, fetchAll, fetchLatestToken, formatArgs, generateCommand, initOperatorClient, listCommand as listCommand$4, listCommand$1 as listCommand, loadAccessToken, loadConfig, loadConfigPath, loadWorkspaceId, parseFormat, printWithFormat, readPackageJson, readPlatformConfig, showCommand, tokenCommand, userAgent, withCommonArgs, writePlatformConfig } from "../token-DwKmpi9i.mjs";
2
+ import { PATScope, applyCommand, commonArgs, createCommand, deleteCommand, fetchAll, fetchLatestToken, formatArgs, generateCommand, initOperatorClient, listCommand as listCommand$4, listCommand$1 as listCommand, loadAccessToken, loadConfig, loadConfigPath, loadWorkspaceId, parseFormat, printWithFormat, readPackageJson, readPlatformConfig, showCommand, tokenCommand, userAgent, withCommonArgs, writePlatformConfig } from "../token-LAqSDm3f.mjs";
3
3
  import "../auth-Di3vQUrT.mjs";
4
4
  import { register } from "node:module";
5
5
  import { defineCommand, runCommand, runMain } from "citty";
@@ -1,5 +1,5 @@
1
1
  /// <reference path="./../plugin-generated.d.ts" />
2
2
 
3
- import { AuthConfig, AuthServiceInput, BuiltinIdP, ExecutorServiceConfig, ExecutorServiceInput, IDToken, IdPConfig, IdProviderConfig, OAuth2Client, OAuth2ClientGrantType, OIDC, PermissionCondition, QueryType, Resolver, ResolverServiceConfig, ResolverServiceInput, SAML, SCIMAttribute, SCIMAttributeMapping, SCIMAttributeType, SCIMAuthorization, SCIMConfig, SCIMResource, StaticWebsiteConfig, TailorField, TailorTypeGqlPermission, TailorTypePermission, TailorUser, TenantProviderConfig, UserAttributeKey, UserAttributeListKey, UserAttributeMap, UsernameFieldKey, ValueOperand, db, defineAuth, defineConfig, defineGenerators, defineIdp, defineStaticWebSite, unauthenticatedTailorUser } from "../types-CPcmGK_X.mjs";
4
- import { FunctionOperation, GqlOperation, IncomingWebhookArgs, IncomingWebhookRequest, IncomingWebhookTrigger, Operation, RecordCreatedArgs, RecordDeletedArgs, RecordTrigger, RecordUpdatedArgs, ResolverExecutedArgs, ResolverExecutedTrigger, ScheduleTrigger, Trigger, WebhookOperation, createExecutor, createResolver, incomingWebhookTrigger, infer, output, recordCreatedTrigger, recordDeletedTrigger, recordUpdatedTrigger, resolverExecutedTrigger, scheduleTrigger, t } from "../index-DHpKRtq3.mjs";
5
- export { AuthConfig, AuthServiceInput, BuiltinIdP, ExecutorServiceConfig, ExecutorServiceInput, FunctionOperation, GqlOperation, IDToken, IdPConfig, IdProviderConfig, IncomingWebhookArgs, IncomingWebhookRequest, IncomingWebhookTrigger, OAuth2Client, OAuth2ClientGrantType, OIDC, Operation, PermissionCondition, QueryType, RecordCreatedArgs, RecordDeletedArgs, RecordTrigger, RecordUpdatedArgs, Resolver, ResolverExecutedArgs, ResolverExecutedTrigger, ResolverServiceConfig, ResolverServiceInput, SAML, SCIMAttribute, SCIMAttributeMapping, SCIMAttributeType, SCIMAuthorization, SCIMConfig, SCIMResource, ScheduleTrigger, StaticWebsiteConfig, TailorField, TailorTypeGqlPermission, TailorTypePermission, TailorUser, TenantProviderConfig, Trigger, UserAttributeKey, UserAttributeListKey, UserAttributeMap, UsernameFieldKey, ValueOperand, WebhookOperation, createExecutor, createResolver, db, defineAuth, defineConfig, defineGenerators, defineIdp, defineStaticWebSite, incomingWebhookTrigger, infer, output, recordCreatedTrigger, recordDeletedTrigger, recordUpdatedTrigger, resolverExecutedTrigger, scheduleTrigger, t, unauthenticatedTailorUser };
3
+ import { AuthConfig, AuthExternalConfig, AuthOwnConfig, AuthServiceInput, BuiltinIdP, ExecutorServiceConfig, ExecutorServiceInput, IDToken, IdPConfig, IdPExternalConfig, IdProviderConfig, OAuth2Client, OAuth2ClientGrantType, OIDC, PermissionCondition, QueryType, Resolver, ResolverExternalConfig, ResolverServiceConfig, ResolverServiceInput, SAML, SCIMAttribute, SCIMAttributeMapping, SCIMAttributeType, SCIMAuthorization, SCIMConfig, SCIMResource, StaticWebsiteConfig, TailorField, TailorTypeGqlPermission, TailorTypePermission, TailorUser, TenantProviderConfig, UserAttributeKey, UserAttributeListKey, UserAttributeMap, UsernameFieldKey, ValueOperand, db, defineAuth, defineConfig, defineGenerators, defineIdp, defineStaticWebSite, unauthenticatedTailorUser } from "../types-Dyhfh5b6.mjs";
4
+ import { FunctionOperation, GqlOperation, IncomingWebhookArgs, IncomingWebhookRequest, IncomingWebhookTrigger, Operation, RecordCreatedArgs, RecordDeletedArgs, RecordTrigger, RecordUpdatedArgs, ResolverExecutedArgs, ResolverExecutedTrigger, ScheduleTrigger, Trigger, WebhookOperation, createExecutor, createResolver, incomingWebhookTrigger, infer, output, recordCreatedTrigger, recordDeletedTrigger, recordUpdatedTrigger, resolverExecutedTrigger, scheduleTrigger, t } from "../index-DyBFt3bp.mjs";
5
+ export { AuthConfig, AuthExternalConfig, AuthOwnConfig, AuthServiceInput, BuiltinIdP, ExecutorServiceConfig, ExecutorServiceInput, FunctionOperation, GqlOperation, IDToken, IdPConfig, IdPExternalConfig, IdProviderConfig, IncomingWebhookArgs, IncomingWebhookRequest, IncomingWebhookTrigger, OAuth2Client, OAuth2ClientGrantType, OIDC, Operation, PermissionCondition, QueryType, RecordCreatedArgs, RecordDeletedArgs, RecordTrigger, RecordUpdatedArgs, Resolver, ResolverExecutedArgs, ResolverExecutedTrigger, ResolverExternalConfig, ResolverServiceConfig, ResolverServiceInput, SAML, SCIMAttribute, SCIMAttributeMapping, SCIMAttributeType, SCIMAuthorization, SCIMConfig, SCIMResource, ScheduleTrigger, StaticWebsiteConfig, TailorField, TailorTypeGqlPermission, TailorTypePermission, TailorUser, TenantProviderConfig, Trigger, UserAttributeKey, UserAttributeListKey, UserAttributeMap, UsernameFieldKey, ValueOperand, WebhookOperation, createExecutor, createResolver, db, defineAuth, defineConfig, defineGenerators, defineIdp, defineStaticWebSite, incomingWebhookTrigger, infer, output, recordCreatedTrigger, recordDeletedTrigger, recordUpdatedTrigger, resolverExecutedTrigger, scheduleTrigger, t, unauthenticatedTailorUser };
@@ -1,14 +1,25 @@
1
1
  /// <reference path="./plugin-generated.d.ts" />
2
2
 
3
- import { AllowedValues, AllowedValuesOutput, ArrayFieldOutput, ExecutorInput, FieldMetadata, FieldOptions, FieldOutput, FunctionOperation, GqlOperation, IncomingWebhookTrigger as IncomingWebhookTrigger$1, InferFieldsOutput, RecordTrigger as RecordTrigger$1, ResolverExecutedTrigger as ResolverExecutedTrigger$1, ResolverInput, ScheduleTriggerInput, TailorDBType, TailorField, TailorUser, WebhookOperation, output as output$1 } from "./types-CPcmGK_X.mjs";
3
+ import { AllowedValues, AllowedValuesOutput, ArrayFieldOutput, ExecutorInput, FieldMetadata, FieldOptions, FieldOutput, FunctionOperation, GqlOperation, IncomingWebhookTrigger as IncomingWebhookTrigger$1, InferFieldsOutput, RecordTrigger as RecordTrigger$1, ResolverExecutedTrigger as ResolverExecutedTrigger$1, ResolverInput, ScheduleTriggerInput, TailorDBType, TailorField, TailorUser, WebhookOperation, output as output$1 } from "./types-Dyhfh5b6.mjs";
4
4
  import { EmptyObject } from "type-fest";
5
5
  import { Client } from "@urql/core";
6
6
  import { StandardCRON } from "ts-cron-validator";
7
7
 
8
+ //#region src/configure/types/env.d.ts
9
+ declare global {
10
+ namespace TailorSDK {
11
+ interface Env {}
12
+ }
13
+ }
14
+ type InferredEnv = keyof TailorSDK.Env extends never ? Record<string, string> : TailorSDK.Env;
15
+ /** Represents environment variables in the Tailor platform. */
16
+ type TailorEnv = InferredEnv;
17
+ //#endregion
8
18
  //#region src/configure/services/resolver/resolver.d.ts
9
19
  type Context<Input extends Record<string, TailorField<any>> | undefined> = {
10
20
  input: Input extends Record<string, TailorField<any>> ? InferFieldsOutput<Input> : never;
11
21
  user: TailorUser;
22
+ env: TailorEnv;
12
23
  };
13
24
  type OutputType<O> = O extends TailorField<any> ? output$1<O> : O extends Record<string, TailorField<any>> ? InferFieldsOutput<O> : never;
14
25
  declare function createResolver<Input extends Record<string, TailorField<any>> | undefined = undefined, Output extends TailorField<any> | Record<string, TailorField<any>> = TailorField<any>>(config: Omit<ResolverInput, "input" | "output" | "body"> & Readonly<{
@@ -30,7 +41,9 @@ type ResolverConfig = ReturnType<typeof createResolver<any, any>>;
30
41
  //#endregion
31
42
  //#region src/configure/services/executor/operation.d.ts
32
43
  type FunctionOperation$1<Args> = Omit<FunctionOperation, "body"> & {
33
- body: (args: Args) => void | Promise<void>;
44
+ body: (args: Args & {
45
+ env: TailorEnv;
46
+ }) => void | Promise<void>;
34
47
  };
35
48
  type UrqlOperationArgs = Parameters<Client["query"] | Client["mutation"]>;
36
49
  type GqlOperation$1<Args> = Omit<GqlOperation, "query" | "variables"> & {
@@ -156,7 +156,7 @@ const FunctionOperationSchema = z.object({
156
156
  });
157
157
  const GqlOperationSchema = z.object({
158
158
  kind: z.literal("graphql"),
159
- appName: z.string(),
159
+ appName: z.string().optional(),
160
160
  query: z.string(),
161
161
  variables: functionSchema.optional(),
162
162
  invoker: InvokerSchema.optional()
@@ -467,9 +467,11 @@ var Application = class {
467
467
  _subgraphs = [];
468
468
  _executorService = void 0;
469
469
  _staticWebsiteServices = [];
470
+ _env = {};
470
471
  constructor(name, config) {
471
472
  this.name = name;
472
473
  this.config = config;
474
+ this._env = config.env || {};
473
475
  }
474
476
  addSubgraph(type, name) {
475
477
  this._subgraphs.push({
@@ -498,40 +500,50 @@ var Application = class {
498
500
  get staticWebsiteServices() {
499
501
  return this._staticWebsiteServices;
500
502
  }
503
+ get env() {
504
+ return this._env;
505
+ }
501
506
  get applications() {
502
507
  return [this];
503
508
  }
504
509
  defineTailorDB(config) {
505
510
  if (!config) return;
506
511
  for (const [namespace, serviceConfig] of Object.entries(config)) {
507
- const tailorDB = new TailorDBService(namespace, serviceConfig);
508
- this._tailorDBServices.push(tailorDB);
509
- this.addSubgraph("tailordb", tailorDB.namespace);
512
+ if (!("external" in serviceConfig)) {
513
+ const tailorDB = new TailorDBService(namespace, serviceConfig);
514
+ this._tailorDBServices.push(tailorDB);
515
+ }
516
+ this.addSubgraph("tailordb", namespace);
510
517
  }
511
518
  }
512
519
  defineResolver(config) {
513
520
  if (!config) return;
514
521
  for (const [namespace, serviceConfig] of Object.entries(config)) {
515
- const resolverService = new ResolverService(namespace, serviceConfig);
516
- this._resolverServices.push(resolverService);
517
- this.addSubgraph("pipeline", resolverService.namespace);
522
+ if (!("external" in serviceConfig)) {
523
+ const resolverService = new ResolverService(namespace, serviceConfig);
524
+ this._resolverServices.push(resolverService);
525
+ }
526
+ this.addSubgraph("pipeline", namespace);
518
527
  }
519
528
  }
520
529
  defineIdp(config) {
530
+ if (!config) return;
521
531
  const idpNames = /* @__PURE__ */ new Set();
522
- (config ?? []).forEach((idpConfig) => {
523
- const idp = IdPSchema.parse(idpConfig);
524
- if (idpNames.has(idp.name)) throw new Error(`IdP with name "${idp.name}" already defined.`);
525
- idpNames.add(idp.name);
526
- this._idpServices.push(idp);
527
- this.addSubgraph("idp", idp.name);
532
+ config.forEach((idpConfig) => {
533
+ const name = idpConfig.name;
534
+ if (idpNames.has(name)) throw new Error(`IdP with name "${name}" already defined.`);
535
+ idpNames.add(name);
536
+ if (!("external" in idpConfig)) {
537
+ const idp = IdPSchema.parse(idpConfig);
538
+ this._idpServices.push(idp);
539
+ }
540
+ this.addSubgraph("idp", name);
528
541
  });
529
542
  }
530
543
  defineAuth(config) {
531
544
  if (!config) return;
532
- const authService = new AuthService(config, this.tailorDBServices);
533
- this._authService = authService;
534
- this.addSubgraph("auth", authService.config.name);
545
+ if (!("external" in config)) this._authService = new AuthService(config, this.tailorDBServices);
546
+ this.addSubgraph("auth", config.name);
535
547
  }
536
548
  defineExecutor(config) {
537
549
  if (!config) return;
@@ -1579,15 +1591,23 @@ async function loadConfig(configPath) {
1579
1591
  function extractAttributesFromConfig(config) {
1580
1592
  return collectAttributesFromConfig(config);
1581
1593
  }
1582
- function generateTypeDefinition(attributeMap, attributeList) {
1594
+ function generateTypeDefinition(attributeMap, attributeList, env) {
1583
1595
  const mapFields = attributeMap ? Object.entries(attributeMap).map(([key, value]) => ` ${key}: ${value};`).join("\n") : "";
1584
1596
  const mapBody = !attributeMap || Object.keys(attributeMap).length === 0 ? "{}" : `{
1585
1597
  ${mapFields}
1586
1598
  }`;
1587
1599
  const listBody = `{
1588
1600
  __tuple?: ${attributeList ? `[${attributeList.map(() => "string").join(", ")}]` : "[]"};
1601
+ }`;
1602
+ const envFields = env ? Object.entries(env).map(([key, value]) => {
1603
+ const valueType = typeof value === "string" ? `"${value}"` : String(value);
1604
+ return ` ${key}: ${valueType};`;
1605
+ }).join("\n") : "";
1606
+ const envBody = !env || Object.keys(env).length === 0 ? "{}" : `{
1607
+ ${envFields}
1589
1608
  }`;
1590
1609
  return ml`
1610
+ /* eslint-disable @typescript-eslint/no-empty-object-type */
1591
1611
  // This file is auto-generated by @tailor-platform/sdk
1592
1612
  // Do not edit this file manually
1593
1613
  // Regenerated automatically when running 'tailor-sdk apply' or 'tailor-sdk generate'
@@ -1596,6 +1616,7 @@ declare global {
1596
1616
  namespace TailorSDK {
1597
1617
  interface AttributeMap ${mapBody}
1598
1618
  interface AttributeList ${listBody}
1619
+ interface Env ${envBody}
1599
1620
  }
1600
1621
  }
1601
1622
 
@@ -1632,6 +1653,8 @@ function collectAttributesFromConfig(config) {
1632
1653
  return {};
1633
1654
  }
1634
1655
  function resolveTypeDefinitionPath(configPath) {
1656
+ const typePath = process.env.TAILOR_PLATFORM_SDK_TYPE_PATH;
1657
+ if (typePath) return path.resolve(process.cwd(), typePath);
1635
1658
  const configDir = path.dirname(path.resolve(configPath));
1636
1659
  const packageDir = resolvePackageDirectory(configDir);
1637
1660
  if (!packageDir) return path.join(configDir, "node_modules", "@tailor-platform", "sdk", "dist", "plugin-generated.d.ts");
@@ -1640,13 +1663,12 @@ function resolveTypeDefinitionPath(configPath) {
1640
1663
  async function generateUserTypes(config, configPath) {
1641
1664
  try {
1642
1665
  const { attributeMap, attributeList } = extractAttributesFromConfig(config);
1643
- if (!attributeMap && !attributeList) {
1644
- console.log(styleText("cyan", "No attributes found in configuration"));
1645
- return;
1646
- }
1666
+ if (!attributeMap && !attributeList) console.log(styleText("cyan", "No attributes found in configuration"));
1647
1667
  if (attributeMap) console.log("Extracted AttributeMap:", attributeMap);
1648
1668
  if (attributeList) console.log("Extracted AttributeList:", attributeList);
1649
- const typeDefContent = generateTypeDefinition(attributeMap, attributeList);
1669
+ const env = config.env;
1670
+ if (env) console.log("Extracted Env:", env);
1671
+ const typeDefContent = generateTypeDefinition(attributeMap, attributeList, env);
1650
1672
  const outputPath = resolveTypeDefinitionPath(configPath);
1651
1673
  fs.mkdirSync(path.dirname(outputPath), { recursive: true });
1652
1674
  fs.writeFileSync(outputPath, typeDefContent);
@@ -2633,6 +2655,22 @@ async function planApplication({ client, workspaceId, application }) {
2633
2655
  authNamespace = application.authService.config.name;
2634
2656
  const idProvider = application.authService.config.idProvider;
2635
2657
  if (idProvider) authIdpConfigName = idProvider.name;
2658
+ } else if (application.config.auth) {
2659
+ authNamespace = application.config.auth.name;
2660
+ const idpConfigs = await fetchAll(async (pageToken) => {
2661
+ try {
2662
+ const { idpConfigs: idpConfigs$1, nextPageToken } = await client.listAuthIDPConfigs({
2663
+ workspaceId,
2664
+ namespaceName: authNamespace,
2665
+ pageToken
2666
+ });
2667
+ return [idpConfigs$1, nextPageToken];
2668
+ } catch (error) {
2669
+ if (error instanceof ConnectError && error.code === Code.NotFound) return [[], ""];
2670
+ throw error;
2671
+ }
2672
+ });
2673
+ if (idpConfigs.length > 0) authIdpConfigName = idpConfigs[0].name;
2636
2674
  }
2637
2675
  const metaRequest = await buildMetaRequest(trn$6(workspaceId, application.name), application.name);
2638
2676
  if (existingApplications.some((app) => app.name === application.name)) changeSet.updates.push({
@@ -3811,6 +3849,25 @@ async function confirmUnmanagedResources(resources, appName, yes) {
3811
3849
  To override, run again and confirm, or use --yes flag.
3812
3850
  `);
3813
3851
  }
3852
+ async function confirmImportantResourceDeletion(resources, yes) {
3853
+ if (resources.length === 0) return;
3854
+ consola.warn("The following resources will be deleted:");
3855
+ console.log(` ${chalk.cyan("Resources")}:`);
3856
+ for (const r of resources) console.log(` • ${chalk.bold(r.resourceType)} ${chalk.red(`"${r.resourceName}"`)}`);
3857
+ console.log("");
3858
+ console.log(chalk.yellow(" Deleting these resources will permanently remove all associated data."));
3859
+ if (yes) {
3860
+ consola.success("Deleting resources (--yes flag specified)...");
3861
+ return;
3862
+ }
3863
+ if (!await consola.prompt("Are you sure you want to delete these resources?", {
3864
+ type: "confirm",
3865
+ initial: false
3866
+ })) throw new Error(ml`
3867
+ Apply cancelled. Resources will not be deleted.
3868
+ To override, run again and confirm, or use --yes flag.
3869
+ `);
3870
+ }
3814
3871
 
3815
3872
  //#endregion
3816
3873
  //#region src/cli/apply/services/executor.ts
@@ -3871,7 +3928,7 @@ async function planExecutor({ client, workspaceId, application }) {
3871
3928
  name: executor.name,
3872
3929
  request: {
3873
3930
  workspaceId,
3874
- executor: protoExecutor(executor)
3931
+ executor: protoExecutor(application.name, executor, application.env)
3875
3932
  },
3876
3933
  metaRequest
3877
3934
  });
@@ -3880,7 +3937,7 @@ async function planExecutor({ client, workspaceId, application }) {
3880
3937
  name: executor.name,
3881
3938
  request: {
3882
3939
  workspaceId,
3883
- executor: protoExecutor(executor)
3940
+ executor: protoExecutor(application.name, executor, application.env)
3884
3941
  },
3885
3942
  metaRequest
3886
3943
  });
@@ -3904,7 +3961,7 @@ async function planExecutor({ client, workspaceId, application }) {
3904
3961
  resourceOwners
3905
3962
  };
3906
3963
  }
3907
- function protoExecutor(executor) {
3964
+ function protoExecutor(appName, executor, env) {
3908
3965
  const trigger = executor.trigger;
3909
3966
  let triggerType;
3910
3967
  let triggerConfig;
@@ -3993,7 +4050,7 @@ function protoExecutor(executor) {
3993
4050
  targetConfig = { config: {
3994
4051
  case: "tailorGraphql",
3995
4052
  value: {
3996
- appName: target.appName,
4053
+ appName: target.appName ?? appName,
3997
4054
  query: target.query,
3998
4055
  variables: target.variables ? { expr: `(${target.variables.toString()})(args)` } : void 0,
3999
4056
  invoker: target.invoker ? {
@@ -4014,7 +4071,7 @@ function protoExecutor(executor) {
4014
4071
  value: {
4015
4072
  name: `${executor.name}__target`,
4016
4073
  script,
4017
- variables: { expr: "({ ...args, appNamespace: args.namespaceName })" },
4074
+ variables: { expr: `({ ...args, appNamespace: args.namespaceName, env: ${JSON.stringify(env)} })` },
4018
4075
  invoker: target.invoker ? {
4019
4076
  namespace: target.invoker.authName,
4020
4077
  machineUserName: target.invoker.machineUser
@@ -4097,7 +4154,7 @@ async function planPipeline({ client, workspaceId, application }) {
4097
4154
  const executors = Object.values(await application.executorService?.loadExecutors() ?? {});
4098
4155
  const { changeSet: serviceChangeSet, conflicts, unmanaged, resourceOwners } = await planServices$1(client, workspaceId, application.name, pipelines);
4099
4156
  const deletedServices = serviceChangeSet.deletes.map((del) => del.name);
4100
- const resolverChangeSet = await planResolvers(client, workspaceId, pipelines, executors, deletedServices);
4157
+ const resolverChangeSet = await planResolvers(client, workspaceId, pipelines, executors, deletedServices, application.env);
4101
4158
  serviceChangeSet.print();
4102
4159
  resolverChangeSet.print();
4103
4160
  return {
@@ -4188,7 +4245,7 @@ async function planServices$1(client, workspaceId, appName, pipelines) {
4188
4245
  resourceOwners
4189
4246
  };
4190
4247
  }
4191
- async function planResolvers(client, workspaceId, pipelines, executors, deletedServices) {
4248
+ async function planResolvers(client, workspaceId, pipelines, executors, deletedServices, env) {
4192
4249
  const changeSet = new ChangeSet("Pipeline resolvers");
4193
4250
  const fetchResolvers = (namespaceName) => {
4194
4251
  return fetchAll(async (pageToken) => {
@@ -4219,7 +4276,7 @@ async function planResolvers(client, workspaceId, pipelines, executors, deletedS
4219
4276
  request: {
4220
4277
  workspaceId,
4221
4278
  namespaceName: pipeline.namespace,
4222
- pipelineResolver: processResolver(resolver, executorUsedResolvers)
4279
+ pipelineResolver: processResolver(resolver, executorUsedResolvers, env)
4223
4280
  }
4224
4281
  });
4225
4282
  existingNameSet.delete(resolver.name);
@@ -4228,7 +4285,7 @@ async function planResolvers(client, workspaceId, pipelines, executors, deletedS
4228
4285
  request: {
4229
4286
  workspaceId,
4230
4287
  namespaceName: pipeline.namespace,
4231
- pipelineResolver: processResolver(resolver, executorUsedResolvers)
4288
+ pipelineResolver: processResolver(resolver, executorUsedResolvers, env)
4232
4289
  }
4233
4290
  });
4234
4291
  existingNameSet.forEach((name) => {
@@ -4254,7 +4311,7 @@ async function planResolvers(client, workspaceId, pipelines, executors, deletedS
4254
4311
  });
4255
4312
  return changeSet;
4256
4313
  }
4257
- function processResolver(resolver, executorUsedResolvers) {
4314
+ function processResolver(resolver, executorUsedResolvers, env) {
4258
4315
  const functionPath = path.join(getDistDir(), "functions", `${resolver.name}__body.js`);
4259
4316
  let functionCode = "";
4260
4317
  try {
@@ -4268,7 +4325,7 @@ function processResolver(resolver, executorUsedResolvers) {
4268
4325
  description: `${resolver.name} function body`,
4269
4326
  operationType: PipelineResolver_OperationType.FUNCTION,
4270
4327
  operationSource: functionCode,
4271
- operationHook: { expr: `({ ...context.pipeline, input: context.args, user: ${tailorUserMap} });` },
4328
+ operationHook: { expr: `({ ...context.pipeline, input: context.args, user: ${tailorUserMap}, env: ${JSON.stringify(env)} });` },
4272
4329
  postScript: `args.body`
4273
4330
  }];
4274
4331
  const typeBaseName = inflection.camelize(resolver.name);
@@ -5012,6 +5069,7 @@ async function apply(options) {
5012
5069
  ...pipeline.conflicts,
5013
5070
  ...executor.conflicts
5014
5071
  ];
5072
+ await confirmOwnerConflict(allConflicts, application.name, yes);
5015
5073
  const allUnmanaged = [
5016
5074
  ...tailorDB.unmanaged,
5017
5075
  ...staticWebsite.unmanaged,
@@ -5020,8 +5078,17 @@ async function apply(options) {
5020
5078
  ...pipeline.unmanaged,
5021
5079
  ...executor.unmanaged
5022
5080
  ];
5023
- await confirmOwnerConflict(allConflicts, application.name, yes);
5024
5081
  await confirmUnmanagedResources(allUnmanaged, application.name, yes);
5082
+ const importantDeletions = [];
5083
+ for (const del of tailorDB.changeSet.type.deletes) importantDeletions.push({
5084
+ resourceType: "TailorDB type",
5085
+ resourceName: del.name
5086
+ });
5087
+ for (const del of staticWebsite.changeSet.deletes) importantDeletions.push({
5088
+ resourceType: "StaticWebsite",
5089
+ resourceName: del.name
5090
+ });
5091
+ await confirmImportantResourceDeletion(importantDeletions, yes);
5025
5092
  const resourceOwners = new Set([
5026
5093
  ...tailorDB.resourceOwners,
5027
5094
  ...staticWebsite.resourceOwners,
@@ -1,11 +1,11 @@
1
1
  /// <reference path="./plugin-generated.d.ts" />
2
2
 
3
- import * as zod34 from "zod";
3
+ import * as zod0 from "zod";
4
4
  import { z } from "zod";
5
5
  import { StandardSchemaV1 } from "@standard-schema/spec";
6
6
  import * as type_fest0 from "type-fest";
7
7
  import { IsAny, NonEmptyObject } from "type-fest";
8
- import * as zod_v4_core50 from "zod/v4/core";
8
+ import * as zod_v4_core0 from "zod/v4/core";
9
9
 
10
10
  //#region src/configure/types/helpers.d.ts
11
11
  type Prettify<T> = { [K in keyof T as string extends K ? never : K]: T[K] } & {};
@@ -617,7 +617,12 @@ declare function defineAuth<const Name extends string, const User extends Tailor
617
617
  readonly scim?: SCIMConfig;
618
618
  readonly tenantProvider?: TenantProviderConfig;
619
619
  } & AuthDefinitionBrand;
620
- type AuthConfig = ReturnType<typeof defineAuth<string, any, any, any, string>>;
620
+ type AuthExternalConfig = {
621
+ name: string;
622
+ external: true;
623
+ };
624
+ type AuthOwnConfig = ReturnType<typeof defineAuth<string, any, any, any, string>>;
625
+ type AuthConfig = AuthOwnConfig | AuthExternalConfig;
621
626
  //#endregion
622
627
  //#region src/configure/services/tailordb/permission.d.ts
623
628
  interface Permissions {
@@ -758,8 +763,11 @@ type TailorDBServiceConfig = {
758
763
  files: string[];
759
764
  ignores?: string[];
760
765
  };
766
+ type TailorDBExternalConfig = {
767
+ external: true;
768
+ };
761
769
  type TailorDBServiceInput = {
762
- [namespace: string]: TailorDBServiceConfig;
770
+ [namespace: string]: TailorDBServiceConfig | TailorDBExternalConfig;
763
771
  };
764
772
  type IndexDef<T extends {
765
773
  fields: Record<PropertyKey, unknown>;
@@ -1103,8 +1111,11 @@ type ResolverServiceConfig = {
1103
1111
  files: string[];
1104
1112
  ignores?: string[];
1105
1113
  };
1114
+ type ResolverExternalConfig = {
1115
+ external: true;
1116
+ };
1106
1117
  type ResolverServiceInput = {
1107
- [namespace: string]: ResolverServiceConfig;
1118
+ [namespace: string]: ResolverServiceConfig | ResolverExternalConfig;
1108
1119
  };
1109
1120
  //#endregion
1110
1121
  //#region src/parser/service/idp/schema.d.ts
@@ -1139,7 +1150,11 @@ declare function defineIdp<const TClients extends string[]>(name: string, config
1139
1150
  };
1140
1151
  readonly clients: TClients;
1141
1152
  } & IdpDefinitionBrand;
1142
- type IdPConfig = Omit<ReturnType<typeof defineIdp>, "provider">;
1153
+ type IdPExternalConfig = {
1154
+ name: string;
1155
+ external: true;
1156
+ };
1157
+ type IdPConfig = Omit<ReturnType<typeof defineIdp>, "provider"> | IdPExternalConfig;
1143
1158
  //#endregion
1144
1159
  //#region src/parser/service/staticwebsite/schema.d.ts
1145
1160
  declare const StaticWebsiteSchema: z.core.$ZodBranded<z.ZodObject<{
@@ -1252,8 +1267,9 @@ type GeneratorConfig = z.input<typeof BaseGeneratorConfigSchema>;
1252
1267
  type CodeGeneratorBase = z.output<typeof CodeGeneratorSchema>;
1253
1268
  //#endregion
1254
1269
  //#region src/configure/config.d.ts
1255
- interface AppConfig<Auth extends AuthConfig = AuthConfig, Idp extends IdPConfig[] = IdPConfig[], StaticWebsites extends StaticWebsiteConfig[] = StaticWebsiteConfig[]> {
1270
+ interface AppConfig<Auth extends AuthConfig = AuthConfig, Idp extends IdPConfig[] = IdPConfig[], StaticWebsites extends StaticWebsiteConfig[] = StaticWebsiteConfig[], Env extends Record<string, string | number | boolean> = Record<string, string | number | boolean>> {
1256
1271
  name: string;
1272
+ env?: Env;
1257
1273
  cors?: string[];
1258
1274
  allowedIPAddresses?: string[];
1259
1275
  disableIntrospection?: boolean;
@@ -1277,12 +1293,12 @@ declare function defineGenerators(...configs: GeneratorConfig[]): (["@tailor-pla
1277
1293
  }] | {
1278
1294
  id: string;
1279
1295
  description: string;
1280
- processType: zod_v4_core50.$InferInnerFunctionType<zod_v4_core50.$ZodFunctionArgs, zod_v4_core50.$ZodFunctionOut>;
1281
- processResolver: zod_v4_core50.$InferInnerFunctionType<zod_v4_core50.$ZodFunctionArgs, zod_v4_core50.$ZodFunctionOut>;
1282
- processExecutor: zod_v4_core50.$InferInnerFunctionType<zod_v4_core50.$ZodFunctionArgs, zod_v4_core50.$ZodFunctionOut>;
1283
- aggregate: zod_v4_core50.$InferInnerFunctionType<zod_v4_core50.$ZodFunctionArgs, zod34.ZodAny>;
1284
- processTailorDBNamespace?: zod_v4_core50.$InferInnerFunctionType<zod_v4_core50.$ZodFunctionArgs, zod_v4_core50.$ZodFunctionOut> | undefined;
1285
- processResolverNamespace?: zod_v4_core50.$InferInnerFunctionType<zod_v4_core50.$ZodFunctionArgs, zod_v4_core50.$ZodFunctionOut> | undefined;
1296
+ processType: zod_v4_core0.$InferInnerFunctionType<zod_v4_core0.$ZodFunctionArgs, zod_v4_core0.$ZodFunctionOut>;
1297
+ processResolver: zod_v4_core0.$InferInnerFunctionType<zod_v4_core0.$ZodFunctionArgs, zod_v4_core0.$ZodFunctionOut>;
1298
+ processExecutor: zod_v4_core0.$InferInnerFunctionType<zod_v4_core0.$ZodFunctionArgs, zod_v4_core0.$ZodFunctionOut>;
1299
+ aggregate: zod_v4_core0.$InferInnerFunctionType<zod_v4_core0.$ZodFunctionArgs, zod0.ZodAny>;
1300
+ processTailorDBNamespace?: zod_v4_core0.$InferInnerFunctionType<zod_v4_core0.$ZodFunctionArgs, zod_v4_core0.$ZodFunctionOut> | undefined;
1301
+ processResolverNamespace?: zod_v4_core0.$InferInnerFunctionType<zod_v4_core0.$ZodFunctionArgs, zod_v4_core0.$ZodFunctionOut> | undefined;
1286
1302
  })[];
1287
1303
  //#endregion
1288
1304
  //#region src/parser/service/executor/schema.d.ts
@@ -1321,7 +1337,7 @@ declare const FunctionOperationSchema: z.ZodObject<{
1321
1337
  }, z.core.$strip>;
1322
1338
  declare const GqlOperationSchema: z.ZodObject<{
1323
1339
  kind: z.ZodLiteral<"graphql">;
1324
- appName: z.ZodString;
1340
+ appName: z.ZodOptional<z.ZodString>;
1325
1341
  query: z.ZodString;
1326
1342
  variables: z.ZodOptional<z.ZodCustom<Function, Function>>;
1327
1343
  invoker: z.ZodOptional<z.ZodObject<{
@@ -1373,7 +1389,7 @@ declare const ExecutorSchema: z.ZodObject<{
1373
1389
  }, z.core.$strip>>;
1374
1390
  }, z.core.$strip>, z.ZodObject<{
1375
1391
  kind: z.ZodLiteral<"graphql">;
1376
- appName: z.ZodString;
1392
+ appName: z.ZodOptional<z.ZodString>;
1377
1393
  query: z.ZodString;
1378
1394
  variables: z.ZodOptional<z.ZodCustom<Function, Function>>;
1379
1395
  invoker: z.ZodOptional<z.ZodObject<{
@@ -1402,4 +1418,4 @@ type WebhookOperation = z.infer<typeof WebhookOperationSchema>;
1402
1418
  type Executor = z.infer<typeof ExecutorSchema>;
1403
1419
  type ExecutorInput = z.input<typeof ExecutorSchema>;
1404
1420
  //#endregion
1405
- export { AllowedValues, AllowedValuesOutput, AppConfig, ArrayFieldOutput, AuthConfig, type AuthServiceInput, type BuiltinIdP, CodeGeneratorBase, Executor, ExecutorInput, ExecutorServiceConfig, ExecutorServiceInput, FieldMetadata, FieldOptions, FieldOutput, FunctionOperation, Generator, GqlOperation, type IDToken, IdPConfig, type IdProviderConfig, IncomingWebhookTrigger, InferFieldsOutput, type OAuth2Client, type OAuth2ClientGrantType, type OIDC, PermissionCondition, QueryType, RecordTrigger, Resolver, ResolverExecutedTrigger, ResolverInput, ResolverServiceConfig, ResolverServiceInput, type SAML, type SCIMAttribute, type SCIMAttributeMapping, type SCIMAttributeType, type SCIMAuthorization, type SCIMConfig, type SCIMResource, ScheduleTriggerInput, StaticWebsiteConfig, TailorDBType, TailorDBTypeConfig, TailorField, TailorTypeGqlPermission, TailorTypePermission, TailorUser, type TenantProviderConfig, type UserAttributeKey, type UserAttributeListKey, type UserAttributeMap, type UsernameFieldKey, type ValueOperand, WebhookOperation, db, defineAuth, defineConfig, defineGenerators, defineIdp, defineStaticWebSite, output, unauthenticatedTailorUser };
1421
+ export { AllowedValues, AllowedValuesOutput, AppConfig, ArrayFieldOutput, AuthConfig, AuthExternalConfig, AuthOwnConfig, type AuthServiceInput, type BuiltinIdP, CodeGeneratorBase, Executor, ExecutorInput, ExecutorServiceConfig, ExecutorServiceInput, FieldMetadata, FieldOptions, FieldOutput, FunctionOperation, Generator, GqlOperation, type IDToken, IdPConfig, IdPExternalConfig, type IdProviderConfig, IncomingWebhookTrigger, InferFieldsOutput, type OAuth2Client, type OAuth2ClientGrantType, type OIDC, PermissionCondition, QueryType, RecordTrigger, Resolver, ResolverExecutedTrigger, ResolverExternalConfig, ResolverInput, ResolverServiceConfig, ResolverServiceInput, type SAML, type SCIMAttribute, type SCIMAttributeMapping, type SCIMAttributeType, type SCIMAuthorization, type SCIMConfig, type SCIMResource, ScheduleTriggerInput, StaticWebsiteConfig, TailorDBType, TailorDBTypeConfig, TailorField, TailorTypeGqlPermission, TailorTypePermission, TailorUser, type TenantProviderConfig, type UserAttributeKey, type UserAttributeListKey, type UserAttributeMap, type UsernameFieldKey, type ValueOperand, WebhookOperation, db, defineAuth, defineConfig, defineGenerators, defineIdp, defineStaticWebSite, output, unauthenticatedTailorUser };
@@ -1,7 +1,7 @@
1
1
  /// <reference path="./../../plugin-generated.d.ts" />
2
2
 
3
- import { TailorDBType, TailorField, TailorUser } from "../../types-CPcmGK_X.mjs";
4
- import { output } from "../../index-DHpKRtq3.mjs";
3
+ import { TailorDBType, TailorField, TailorUser } from "../../types-Dyhfh5b6.mjs";
4
+ import { output } from "../../index-DyBFt3bp.mjs";
5
5
  import { StandardSchemaV1 } from "@standard-schema/spec";
6
6
 
7
7
  //#region src/utils/test/index.d.ts
@@ -130,3 +130,34 @@ export default defineConfig({
130
130
  **description**: Description of the site.
131
131
 
132
132
  **allowedIPAddresses**: List of IP addresses allowed to access the site in CIDR format.
133
+
134
+ ### Environment Variables
135
+
136
+ Define environment variables that can be accessed in resolvers and executors:
137
+
138
+ ```typescript
139
+ export default defineConfig({
140
+ name: "my-app",
141
+ env: {
142
+ foo: 1,
143
+ bar: "hello",
144
+ baz: true,
145
+ },
146
+ });
147
+ ```
148
+
149
+ ```typescript
150
+ // In resolvers
151
+ body: ({ input, env }) => {
152
+ return {
153
+ result: input.multiplier * env.foo,
154
+ message: env.bar,
155
+ enabled: env.baz,
156
+ };
157
+ };
158
+
159
+ // In executors
160
+ body: ({ newRecord, env }) => {
161
+ console.log(`Environment: ${env.bar}, User: ${newRecord.name}`);
162
+ };
163
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tailor-platform/sdk",
3
- "version": "0.9.0",
3
+ "version": "0.10.1",
4
4
  "description": "Tailor Platform SDK - The SDK to work with Tailor Platform",
5
5
  "license": "MIT",
6
6
  "main": "./dist/configure/index.mjs",