@stripe/extensibility-dev-tools 0.24.3 → 0.25.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.
Files changed (61) hide show
  1. package/dist/bin/build-custom-object-definitions.cjs +165 -34
  2. package/dist/bin/build-custom-object-definitions.js +156 -25
  3. package/dist/bin/create-upload-image.cjs +164 -33
  4. package/dist/bin/create-upload-image.js +156 -25
  5. package/dist/bin/dev-tools-rpc.cjs +199 -59
  6. package/dist/bin/dev-tools-rpc.js +174 -34
  7. package/dist/bin/gen-workspace.cjs +187 -47
  8. package/dist/bin/gen-workspace.js +174 -34
  9. package/dist/bin/template-info.cjs +161 -30
  10. package/dist/bin/template-info.js +156 -25
  11. package/dist/custom-objects/generated/proto/custom_objects/pub/api/app_api/object_definitions_app_service.pb.d.ts +32 -0
  12. package/dist/custom-objects/generated/proto/custom_objects/pub/api/app_api/object_definitions_app_service.pb.d.ts.map +1 -1
  13. package/dist/custom-objects/generated/proto/google/protobuf/descriptor.pb.d.ts +2 -2
  14. package/dist/custom-objects/generated/proto/google/protobuf/wrappers.pb.d.ts +168 -0
  15. package/dist/custom-objects/generated/proto/google/protobuf/wrappers.pb.d.ts.map +1 -0
  16. package/dist/custom-objects/generated/proto/proto/extensions.pb.d.ts +4 -4
  17. package/dist/custom-objects/generated/proto/proto/extensions.pb.d.ts.map +1 -1
  18. package/dist/custom-objects/generated/proto/vendor/proto/model/common/common_model.pb.d.ts +1553 -0
  19. package/dist/custom-objects/generated/proto/vendor/proto/model/common/common_model.pb.d.ts.map +1 -0
  20. package/dist/custom-objects/generated/proto/vendor/proto/model/common/kronos_model.pb.d.ts +1372 -0
  21. package/dist/custom-objects/generated/proto/vendor/proto/model/common/kronos_model.pb.d.ts.map +1 -0
  22. package/dist/custom-objects/generated/proto/vendor/publicapi/api_group_enum.pb.d.ts +2 -0
  23. package/dist/custom-objects/generated/proto/vendor/publicapi/api_group_enum.pb.d.ts.map +1 -1
  24. package/dist/custom-objects/generated/proto/vendor/publicapi/extension_interface.pb.d.ts +2 -0
  25. package/dist/custom-objects/generated/proto/vendor/publicapi/extension_interface.pb.d.ts.map +1 -1
  26. package/dist/custom-objects/generated/proto/vendor/publicapi/feature_enum.pb.d.ts +14 -2
  27. package/dist/custom-objects/generated/proto/vendor/publicapi/feature_enum.pb.d.ts.map +1 -1
  28. package/dist/custom-objects/generated/proto/vendor/publicapi/http_error_status.pb.d.ts +6 -0
  29. package/dist/custom-objects/generated/proto/vendor/publicapi/http_error_status.pb.d.ts.map +1 -1
  30. package/dist/custom-objects/generated/proto/vendor/publicapi/rollout_configs.pb.d.ts +74 -0
  31. package/dist/custom-objects/generated/proto/vendor/publicapi/rollout_configs.pb.d.ts.map +1 -1
  32. package/dist/custom-objects/generated/proto/vendor/publicapi/v2ext.pb.d.ts +10 -3
  33. package/dist/custom-objects/generated/proto/vendor/publicapi/v2ext.pb.d.ts.map +1 -1
  34. package/dist/custom-objects/generated/proto/vendor/vext/privacy_unified_annotations.pb.d.ts +1 -0
  35. package/dist/custom-objects/generated/proto/vendor/vext/privacy_unified_annotations.pb.d.ts.map +1 -1
  36. package/dist/index.cjs +192 -52
  37. package/dist/index.js +174 -34
  38. package/dist/templates/extensions/billing.invoice_collection_options.d.ts +6 -0
  39. package/dist/templates/extensions/billing.invoice_collection_options.d.ts.map +1 -0
  40. package/dist/templates/index.cjs +174 -34
  41. package/dist/templates/index.js +172 -32
  42. package/dist/templates/root/index.d.ts.map +1 -1
  43. package/dist/tsconfig.build.tsbuildinfo +1 -1
  44. package/dist/workspace/index.cjs +183 -43
  45. package/dist/workspace/index.d.ts.map +1 -1
  46. package/dist/workspace/index.js +174 -34
  47. package/dist/workspace-versions.d.ts +26 -0
  48. package/dist/workspace-versions.d.ts.map +1 -0
  49. package/package.json +4 -4
  50. package/templates/extensions/billing.invoice_collection_options/index.test.ts +15 -0
  51. package/templates/extensions/billing.invoice_collection_options/index.ts +16 -0
  52. package/templates/root/custom-objects/eslint.config.mts +89 -0
  53. package/templates/root/custom-objects/package.json.mustache +2 -0
  54. package/templates/root/custom-objects/tsconfig.json +1 -0
  55. package/templates/root/custom-objects/vitest.config.mts +7 -0
  56. package/templates/root/package.json.mustache +1 -1
  57. package/templates/root/tools/test.mts +4 -2
  58. package/dist/templates/extensions/billing.invoice_collection_setting.d.ts +0 -6
  59. package/dist/templates/extensions/billing.invoice_collection_setting.d.ts.map +0 -1
  60. package/templates/extensions/billing.invoice_collection_setting/index.test.ts +0 -15
  61. package/templates/extensions/billing.invoice_collection_setting/index.ts +0 -16
@@ -28,7 +28,7 @@ var import_node_child_process2 = require("child_process");
28
28
  var fs3 = __toESM(require("fs"), 1);
29
29
  var os2 = __toESM(require("os"), 1);
30
30
  var path3 = __toESM(require("path"), 1);
31
- var import_extensibility_tool_utils8 = require("@stripe/extensibility-tool-utils");
31
+ var import_extensibility_tool_utils7 = require("@stripe/extensibility-tool-utils");
32
32
 
33
33
  // src/custom-objects/build-definitions.ts
34
34
  var fs2 = __toESM(require("fs"), 1);
@@ -392,35 +392,35 @@ export default class MyBalanceApp implements Billing.CustomerBalanceApplication<
392
392
  `
393
393
  },
394
394
  {
395
- path: "extensions/billing.invoice_collection_setting/index.test.ts",
395
+ path: "extensions/billing.invoice_collection_options/index.test.ts",
396
396
  content: `import { beforeEach, describe, it, expect } from 'vitest';
397
397
 
398
- import MyInvoiceCollectionSetting from './index.js';
398
+ import MyInvoiceCollectionOptions from './index.js';
399
399
 
400
- describe('MyInvoiceCollectionSetting', () => {
401
- let instance: MyInvoiceCollectionSetting;
400
+ describe('MyInvoiceCollectionOptions', () => {
401
+ let instance: MyInvoiceCollectionOptions;
402
402
 
403
403
  beforeEach(() => {
404
- instance = new MyInvoiceCollectionSetting();
404
+ instance = new MyInvoiceCollectionOptions();
405
405
  });
406
406
 
407
407
  it('should be constructable', () => {
408
- expect(instance).toBeInstanceOf(MyInvoiceCollectionSetting);
408
+ expect(instance).toBeInstanceOf(MyInvoiceCollectionOptions);
409
409
  });
410
410
  });
411
411
  `
412
412
  },
413
413
  {
414
- path: "extensions/billing.invoice_collection_setting/index.ts",
414
+ path: "extensions/billing.invoice_collection_options/index.ts",
415
415
  content: `import type { Billing, Context } from '@stripe/extensibility-sdk';
416
416
 
417
417
  // eslint-disable-next-line @typescript-eslint/no-empty-object-type
418
- interface MyInvoiceCollectionSettingConfig {}
418
+ interface MyInvoiceCollectionOptionsConfig {}
419
419
 
420
- export default class MyInvoiceCollectionSetting implements Billing.InvoiceCollectionSetting<MyInvoiceCollectionSettingConfig> {
421
- collectionOverride(
422
- _request: Billing.InvoiceCollectionSetting.InvoiceCollectionRequest,
423
- _config: MyInvoiceCollectionSettingConfig,
420
+ export default class MyInvoiceCollectionOptions implements Billing.InvoiceCollectionOptions<MyInvoiceCollectionOptionsConfig> {
421
+ overrideOptions(
422
+ _request: Billing.InvoiceCollectionOptions.InvoiceCollectionOptionsInput,
423
+ _config: MyInvoiceCollectionOptionsConfig,
424
424
  _context: Context
425
425
  ) {
426
426
  // TODO: implement your collection setting logic here
@@ -892,6 +892,99 @@ install-deps.log
892
892
 
893
893
  # generated schemas
894
894
  generated
895
+ `
896
+ },
897
+ {
898
+ path: "root/custom-objects/eslint.config.mts",
899
+ content: `import eslint from '@eslint/js';
900
+ import { defineConfig } from 'eslint/config';
901
+ import tseslint from 'typescript-eslint';
902
+ import eslintConfigPrettier from 'eslint-config-prettier/flat';
903
+
904
+ import globals from 'globals';
905
+
906
+ import stripeAppsConfig from '@stripe/extensibility-eslint-plugin';
907
+ import customObjectsConfig from '@stripe/extensibility-eslint-plugin/custom-objects';
908
+
909
+ export default defineConfig([
910
+ eslint.configs.recommended,
911
+ ...tseslint.configs.recommended,
912
+ ...stripeAppsConfig,
913
+ ...customObjectsConfig,
914
+
915
+ // Global ignores
916
+ {
917
+ ignores: ['dist', 'generated', 'node_modules'],
918
+ },
919
+
920
+ // TypeScript source files (with type-checking)
921
+ {
922
+ name: 'sources',
923
+ files: ['src/**/*.ts'],
924
+ ignores: ['**/*.test.ts', '**/__tests__/**'],
925
+ languageOptions: {
926
+ globals: {
927
+ ...globals.node,
928
+ },
929
+ parserOptions: {
930
+ projectService: true,
931
+ tsconfigRootDir: import.meta.dirname,
932
+ },
933
+ },
934
+ },
935
+
936
+ // Test files
937
+ {
938
+ name: 'tests',
939
+ files: ['src/**/*.test.ts', 'src/**/__tests__/**/*.ts'],
940
+ languageOptions: {
941
+ globals: {
942
+ ...globals.node,
943
+ },
944
+ parserOptions: {
945
+ projectService: true,
946
+ tsconfigRootDir: import.meta.dirname,
947
+ },
948
+ },
949
+ },
950
+
951
+ // Config files
952
+ {
953
+ name: 'ts-configs',
954
+ files: ['*.config.m?ts', 'eslint.config.mts'],
955
+ languageOptions: {
956
+ globals: {
957
+ ...globals.node,
958
+ },
959
+ parserOptions: {
960
+ projectService: false,
961
+ },
962
+ },
963
+ rules: {
964
+ '@typescript-eslint/no-unused-vars': 'off',
965
+ },
966
+ },
967
+
968
+ // JavaScript/MJS files (scripts, configs) \u2014 no TS project, so only
969
+ // disable the TS-parser-specific rule that doesn't apply without it.
970
+ {
971
+ name: 'js-configs',
972
+ files: ['**/*.js', '**/*.mjs'],
973
+ languageOptions: {
974
+ globals: {
975
+ ...globals.node,
976
+ },
977
+ parserOptions: {
978
+ projectService: false,
979
+ },
980
+ },
981
+ rules: {
982
+ '@typescript-eslint/no-require-imports': 'off',
983
+ },
984
+ },
985
+
986
+ eslintConfigPrettier,
987
+ ]);
895
988
  `
896
989
  },
897
990
  {
@@ -904,7 +997,9 @@ generated
904
997
  "private": true,
905
998
  "scripts": {
906
999
  "build": "test -d src && custom-objects-build --input src --output dist || true",
1000
+ "lint": "pnpm lint:types && pnpm lint:eslint",
907
1001
  "lint:types": "test ! -d src || tsc --noEmit",
1002
+ "lint:eslint": "eslint .",
908
1003
  "test": "vitest run"
909
1004
  },
910
1005
  "dependencies": {
@@ -927,8 +1022,20 @@ generated
927
1022
  "moduleResolution": "bundler",
928
1023
  "types": ["vitest/globals"]
929
1024
  },
1025
+ "include": ["src/**/*.ts"],
930
1026
  "exclude": ["dist"]
931
1027
  }
1028
+ `
1029
+ },
1030
+ {
1031
+ path: "root/custom-objects/vitest.config.mts",
1032
+ content: `import { defineConfig } from 'vitest/config';
1033
+
1034
+ export default defineConfig({
1035
+ test: {
1036
+ globals: true,
1037
+ },
1038
+ });
932
1039
  `
933
1040
  },
934
1041
  {
@@ -1046,7 +1153,7 @@ export default defineConfig([
1046
1153
  "build": "pnpm -r --if-present build",
1047
1154
  "lint": "pnpm lint:types && pnpm lint:eslint && pnpm lint:format",
1048
1155
  "lint:types": "pnpm -r --if-present lint:types",
1049
- "lint:eslint": "eslint . --ignore-pattern 'extensions/**' && pnpm -r --filter './extensions/*' --if-present lint:eslint",
1156
+ "lint:eslint": "eslint . --ignore-pattern 'extensions/**' && pnpm -r --filter './extensions/*' --if-present lint:eslint && pnpm -r --filter './custom-objects' --if-present lint:eslint",
1050
1157
  "lint:format": "prettier --check .",
1051
1158
  "fix:lint": "eslint --fix . --ignore-pattern 'extensions/**' && pnpm -r --filter './extensions/*' --if-present fix:lint",
1052
1159
  "fix:format": "prettier --write .",
@@ -1092,7 +1199,7 @@ declarations:
1092
1199
  content: `#!/usr/bin/env tsx
1093
1200
  /**
1094
1201
  * Runs tests across the workspace:
1095
- * - vitest for script extensions and custom objects (extensions/*)
1202
+ * - vitest for script extensions (extensions/*) and custom objects (custom-objects/)
1096
1203
  * - jest for UI extensions (ui/)
1097
1204
  */
1098
1205
  import { existsSync, readdirSync } from 'node:fs';
@@ -1102,6 +1209,8 @@ const hasExtensions =
1102
1209
  existsSync('extensions') &&
1103
1210
  readdirSync('extensions').some((name) => existsSync(\`extensions/\${name}/package.json\`));
1104
1211
 
1212
+ const hasCustomObjects = existsSync('custom-objects/package.json');
1213
+
1105
1214
  const hasUI = existsSync('ui/package.json');
1106
1215
 
1107
1216
  let exitCode = 0;
@@ -1114,7 +1223,7 @@ function run(cmd: string): void {
1114
1223
  }
1115
1224
  }
1116
1225
 
1117
- if (hasExtensions) {
1226
+ if (hasExtensions || hasCustomObjects) {
1118
1227
  run('vitest run');
1119
1228
  }
1120
1229
 
@@ -1266,11 +1375,33 @@ function _devNpmDep(name, version) {
1266
1375
  return { type: "dev-npm", name, version };
1267
1376
  }
1268
1377
 
1378
+ // src/workspace-versions.json
1379
+ var workspace_versions_default = {
1380
+ "@stripe/extensibility-custom-objects": "0.8.0",
1381
+ "@stripe/extensibility-custom-objects-tools": "0.42.1",
1382
+ "@stripe/extensibility-dev-tools": "0.25.1",
1383
+ "@stripe/extensibility-eslint-plugin": "0.17.1",
1384
+ "@stripe/extensibility-language-server": "0.3.4",
1385
+ "@stripe/extensibility-sdk": "0.27.1",
1386
+ "@stripe/extensibility-test-helpers": "0.2.7"
1387
+ };
1388
+
1389
+ // src/workspace-versions.ts
1390
+ var _workspaceVersions = workspace_versions_default;
1391
+ function _workspaceVersion(packageName) {
1392
+ const v = _workspaceVersions[packageName];
1393
+ if (v === void 0) {
1394
+ throw new Error(
1395
+ `Unknown workspace package "${packageName}". Check workspace-versions.json or run: tsx scripts/src/sync-workspace-versions.ts`
1396
+ );
1397
+ }
1398
+ return v;
1399
+ }
1400
+
1269
1401
  // src/templates/extensions/base.ts
1270
- var import_extensibility_tool_utils6 = require("@stripe/extensibility-tool-utils");
1271
1402
  var SDK_PACKAGE_NAME = "@stripe/extensibility-sdk";
1272
1403
  var LANGUAGE_SERVER_PACKAGE_NAME = "@stripe/extensibility-language-server";
1273
- var LANGUAGE_SERVER_PACKAGE_VERSION = `^${(0, import_extensibility_tool_utils6._workspaceVersion)(LANGUAGE_SERVER_PACKAGE_NAME)}`;
1404
+ var LANGUAGE_SERVER_PACKAGE_VERSION = `^${_workspaceVersion(LANGUAGE_SERVER_PACKAGE_NAME)}`;
1274
1405
  function _createExtensionEslintConfigFile(params, context) {
1275
1406
  const { id, extensionInterfaceId } = params;
1276
1407
  const { fs: fs4 } = context;
@@ -1313,7 +1444,7 @@ function _createBaseOutput(params, context) {
1313
1444
  dependencies: {
1314
1445
  // Exact pin (no caret) — the SDK is tightly coupled to dev-tools and
1315
1446
  // must match the version that generated the extension scaffolding.
1316
- runtime: [_npmDep(SDK_PACKAGE_NAME, (0, import_extensibility_tool_utils6._workspaceVersion)(SDK_PACKAGE_NAME))],
1447
+ runtime: [_npmDep(SDK_PACKAGE_NAME, _workspaceVersion(SDK_PACKAGE_NAME))],
1317
1448
  dev: [_devNpmDep(LANGUAGE_SERVER_PACKAGE_NAME, LANGUAGE_SERVER_PACKAGE_VERSION)]
1318
1449
  },
1319
1450
  postGenerationHooks: [
@@ -1572,14 +1703,14 @@ var billing_bill_discount_calculation_default = {
1572
1703
  [EXTENSION_INTERFACE_ID5]: discountCalculationTemplate
1573
1704
  };
1574
1705
 
1575
- // src/templates/extensions/billing.invoice_collection_setting.ts
1576
- var EXTENSION_INTERFACE_ID6 = "billing.invoice_collection_setting";
1577
- var invoiceCollectionSettingTemplate = {
1706
+ // src/templates/extensions/billing.invoice_collection_options.ts
1707
+ var EXTENSION_INTERFACE_ID6 = "billing.invoice_collection_options";
1708
+ var invoiceCollectionOptionsTemplate = {
1578
1709
  hidden: true,
1579
1710
  methods: {
1580
- collection_override: { implementation_types: ["script"] }
1711
+ override_options: { implementation_types: ["script"] }
1581
1712
  },
1582
- description: "Use Stripe Scripts to create custom invoice collection logic that controls how your integration handles invoices generated from subscriptions.",
1713
+ description: "Use Stripe Scripts to create custom invoice collection options that controls how your integration handles invoices generated from subscriptions.",
1583
1714
  generate: (params, context) => {
1584
1715
  const { id } = params;
1585
1716
  const { fs: fs4 } = context;
@@ -1607,15 +1738,15 @@ var invoiceCollectionSettingTemplate = {
1607
1738
  ...base.files
1608
1739
  ],
1609
1740
  methods: {
1610
- collection_override: {
1741
+ override_options: {
1611
1742
  implementation_type: "script"
1612
1743
  }
1613
1744
  }
1614
1745
  };
1615
1746
  }
1616
1747
  };
1617
- var billing_invoice_collection_setting_default = {
1618
- [EXTENSION_INTERFACE_ID6]: invoiceCollectionSettingTemplate
1748
+ var billing_invoice_collection_options_default = {
1749
+ [EXTENSION_INTERFACE_ID6]: invoiceCollectionOptionsTemplate
1619
1750
  };
1620
1751
 
1621
1752
  // src/templates/extensions/billing.prorations.ts
@@ -1723,7 +1854,7 @@ var DEFAULT_TEMPLATES = {
1723
1854
  ...extend_workflows_custom_action_default,
1724
1855
  ...billing_customer_balance_application_default,
1725
1856
  ...billing_bill_discount_calculation_default,
1726
- ...billing_invoice_collection_setting_default,
1857
+ ...billing_invoice_collection_options_default,
1727
1858
  ...billing_prorations_default,
1728
1859
  ...billing_recurring_billing_item_handling_default
1729
1860
  };
@@ -1949,9 +2080,9 @@ function toDefaultValue(value, dataType) {
1949
2080
  }
1950
2081
 
1951
2082
  // src/custom-objects/build-definitions.ts
1952
- var import_extensibility_tool_utils7 = require("@stripe/extensibility-tool-utils");
2083
+ var import_extensibility_tool_utils6 = require("@stripe/extensibility-tool-utils");
1953
2084
  async function analyzeAndInjectManifest(options) {
1954
- const context = options.context ?? (0, import_extensibility_tool_utils7._createCliContext)();
2085
+ const context = options.context ?? (0, import_extensibility_tool_utils6._createCliContext)();
1955
2086
  const manifestPath = options.manifestPath ?? "stripe-app.yaml";
1956
2087
  const projectRoot = options.projectRoot ?? path2.dirname(path2.resolve(manifestPath));
1957
2088
  const resolvedManifestPath = path2.resolve(manifestPath);
@@ -2036,7 +2167,7 @@ async function analyzeAndInjectManifest(options) {
2036
2167
  };
2037
2168
  }
2038
2169
  async function writeCustomObjectArtifacts(options, state) {
2039
- const context = options.context ?? (0, import_extensibility_tool_utils7._createCliContext)();
2170
+ const context = options.context ?? (0, import_extensibility_tool_utils6._createCliContext)();
2040
2171
  const targetPath = path2.resolve(options.targetPath);
2041
2172
  const { packageBuild, customObjects, coVersion, coDependencies, projectRoot } = state;
2042
2173
  for (const obj of customObjects) {
@@ -2112,9 +2243,9 @@ function readPackageDependencies(packageJsonPath) {
2112
2243
  }
2113
2244
 
2114
2245
  // src/bin/create-upload-image.ts
2115
- var logger = (0, import_extensibility_tool_utils8._createLogger)({ name: "create-upload-image" });
2246
+ var logger = (0, import_extensibility_tool_utils7._createLogger)({ name: "create-upload-image" });
2116
2247
  async function main() {
2117
- const ctx = (0, import_extensibility_tool_utils8._createCliContext)();
2248
+ const ctx = (0, import_extensibility_tool_utils7._createCliContext)();
2118
2249
  const targetPath = process.argv[2];
2119
2250
  if (!targetPath) {
2120
2251
  ctx.ux.error("Usage: create-upload-image <target-path>");
@@ -369,35 +369,35 @@ export default class MyBalanceApp implements Billing.CustomerBalanceApplication<
369
369
  `
370
370
  },
371
371
  {
372
- path: "extensions/billing.invoice_collection_setting/index.test.ts",
372
+ path: "extensions/billing.invoice_collection_options/index.test.ts",
373
373
  content: `import { beforeEach, describe, it, expect } from 'vitest';
374
374
 
375
- import MyInvoiceCollectionSetting from './index.js';
375
+ import MyInvoiceCollectionOptions from './index.js';
376
376
 
377
- describe('MyInvoiceCollectionSetting', () => {
378
- let instance: MyInvoiceCollectionSetting;
377
+ describe('MyInvoiceCollectionOptions', () => {
378
+ let instance: MyInvoiceCollectionOptions;
379
379
 
380
380
  beforeEach(() => {
381
- instance = new MyInvoiceCollectionSetting();
381
+ instance = new MyInvoiceCollectionOptions();
382
382
  });
383
383
 
384
384
  it('should be constructable', () => {
385
- expect(instance).toBeInstanceOf(MyInvoiceCollectionSetting);
385
+ expect(instance).toBeInstanceOf(MyInvoiceCollectionOptions);
386
386
  });
387
387
  });
388
388
  `
389
389
  },
390
390
  {
391
- path: "extensions/billing.invoice_collection_setting/index.ts",
391
+ path: "extensions/billing.invoice_collection_options/index.ts",
392
392
  content: `import type { Billing, Context } from '@stripe/extensibility-sdk';
393
393
 
394
394
  // eslint-disable-next-line @typescript-eslint/no-empty-object-type
395
- interface MyInvoiceCollectionSettingConfig {}
395
+ interface MyInvoiceCollectionOptionsConfig {}
396
396
 
397
- export default class MyInvoiceCollectionSetting implements Billing.InvoiceCollectionSetting<MyInvoiceCollectionSettingConfig> {
398
- collectionOverride(
399
- _request: Billing.InvoiceCollectionSetting.InvoiceCollectionRequest,
400
- _config: MyInvoiceCollectionSettingConfig,
397
+ export default class MyInvoiceCollectionOptions implements Billing.InvoiceCollectionOptions<MyInvoiceCollectionOptionsConfig> {
398
+ overrideOptions(
399
+ _request: Billing.InvoiceCollectionOptions.InvoiceCollectionOptionsInput,
400
+ _config: MyInvoiceCollectionOptionsConfig,
401
401
  _context: Context
402
402
  ) {
403
403
  // TODO: implement your collection setting logic here
@@ -869,6 +869,99 @@ install-deps.log
869
869
 
870
870
  # generated schemas
871
871
  generated
872
+ `
873
+ },
874
+ {
875
+ path: "root/custom-objects/eslint.config.mts",
876
+ content: `import eslint from '@eslint/js';
877
+ import { defineConfig } from 'eslint/config';
878
+ import tseslint from 'typescript-eslint';
879
+ import eslintConfigPrettier from 'eslint-config-prettier/flat';
880
+
881
+ import globals from 'globals';
882
+
883
+ import stripeAppsConfig from '@stripe/extensibility-eslint-plugin';
884
+ import customObjectsConfig from '@stripe/extensibility-eslint-plugin/custom-objects';
885
+
886
+ export default defineConfig([
887
+ eslint.configs.recommended,
888
+ ...tseslint.configs.recommended,
889
+ ...stripeAppsConfig,
890
+ ...customObjectsConfig,
891
+
892
+ // Global ignores
893
+ {
894
+ ignores: ['dist', 'generated', 'node_modules'],
895
+ },
896
+
897
+ // TypeScript source files (with type-checking)
898
+ {
899
+ name: 'sources',
900
+ files: ['src/**/*.ts'],
901
+ ignores: ['**/*.test.ts', '**/__tests__/**'],
902
+ languageOptions: {
903
+ globals: {
904
+ ...globals.node,
905
+ },
906
+ parserOptions: {
907
+ projectService: true,
908
+ tsconfigRootDir: import.meta.dirname,
909
+ },
910
+ },
911
+ },
912
+
913
+ // Test files
914
+ {
915
+ name: 'tests',
916
+ files: ['src/**/*.test.ts', 'src/**/__tests__/**/*.ts'],
917
+ languageOptions: {
918
+ globals: {
919
+ ...globals.node,
920
+ },
921
+ parserOptions: {
922
+ projectService: true,
923
+ tsconfigRootDir: import.meta.dirname,
924
+ },
925
+ },
926
+ },
927
+
928
+ // Config files
929
+ {
930
+ name: 'ts-configs',
931
+ files: ['*.config.m?ts', 'eslint.config.mts'],
932
+ languageOptions: {
933
+ globals: {
934
+ ...globals.node,
935
+ },
936
+ parserOptions: {
937
+ projectService: false,
938
+ },
939
+ },
940
+ rules: {
941
+ '@typescript-eslint/no-unused-vars': 'off',
942
+ },
943
+ },
944
+
945
+ // JavaScript/MJS files (scripts, configs) \u2014 no TS project, so only
946
+ // disable the TS-parser-specific rule that doesn't apply without it.
947
+ {
948
+ name: 'js-configs',
949
+ files: ['**/*.js', '**/*.mjs'],
950
+ languageOptions: {
951
+ globals: {
952
+ ...globals.node,
953
+ },
954
+ parserOptions: {
955
+ projectService: false,
956
+ },
957
+ },
958
+ rules: {
959
+ '@typescript-eslint/no-require-imports': 'off',
960
+ },
961
+ },
962
+
963
+ eslintConfigPrettier,
964
+ ]);
872
965
  `
873
966
  },
874
967
  {
@@ -881,7 +974,9 @@ generated
881
974
  "private": true,
882
975
  "scripts": {
883
976
  "build": "test -d src && custom-objects-build --input src --output dist || true",
977
+ "lint": "pnpm lint:types && pnpm lint:eslint",
884
978
  "lint:types": "test ! -d src || tsc --noEmit",
979
+ "lint:eslint": "eslint .",
885
980
  "test": "vitest run"
886
981
  },
887
982
  "dependencies": {
@@ -904,8 +999,20 @@ generated
904
999
  "moduleResolution": "bundler",
905
1000
  "types": ["vitest/globals"]
906
1001
  },
1002
+ "include": ["src/**/*.ts"],
907
1003
  "exclude": ["dist"]
908
1004
  }
1005
+ `
1006
+ },
1007
+ {
1008
+ path: "root/custom-objects/vitest.config.mts",
1009
+ content: `import { defineConfig } from 'vitest/config';
1010
+
1011
+ export default defineConfig({
1012
+ test: {
1013
+ globals: true,
1014
+ },
1015
+ });
909
1016
  `
910
1017
  },
911
1018
  {
@@ -1023,7 +1130,7 @@ export default defineConfig([
1023
1130
  "build": "pnpm -r --if-present build",
1024
1131
  "lint": "pnpm lint:types && pnpm lint:eslint && pnpm lint:format",
1025
1132
  "lint:types": "pnpm -r --if-present lint:types",
1026
- "lint:eslint": "eslint . --ignore-pattern 'extensions/**' && pnpm -r --filter './extensions/*' --if-present lint:eslint",
1133
+ "lint:eslint": "eslint . --ignore-pattern 'extensions/**' && pnpm -r --filter './extensions/*' --if-present lint:eslint && pnpm -r --filter './custom-objects' --if-present lint:eslint",
1027
1134
  "lint:format": "prettier --check .",
1028
1135
  "fix:lint": "eslint --fix . --ignore-pattern 'extensions/**' && pnpm -r --filter './extensions/*' --if-present fix:lint",
1029
1136
  "fix:format": "prettier --write .",
@@ -1069,7 +1176,7 @@ declarations:
1069
1176
  content: `#!/usr/bin/env tsx
1070
1177
  /**
1071
1178
  * Runs tests across the workspace:
1072
- * - vitest for script extensions and custom objects (extensions/*)
1179
+ * - vitest for script extensions (extensions/*) and custom objects (custom-objects/)
1073
1180
  * - jest for UI extensions (ui/)
1074
1181
  */
1075
1182
  import { existsSync, readdirSync } from 'node:fs';
@@ -1079,6 +1186,8 @@ const hasExtensions =
1079
1186
  existsSync('extensions') &&
1080
1187
  readdirSync('extensions').some((name) => existsSync(\`extensions/\${name}/package.json\`));
1081
1188
 
1189
+ const hasCustomObjects = existsSync('custom-objects/package.json');
1190
+
1082
1191
  const hasUI = existsSync('ui/package.json');
1083
1192
 
1084
1193
  let exitCode = 0;
@@ -1091,7 +1200,7 @@ function run(cmd: string): void {
1091
1200
  }
1092
1201
  }
1093
1202
 
1094
- if (hasExtensions) {
1203
+ if (hasExtensions || hasCustomObjects) {
1095
1204
  run('vitest run');
1096
1205
  }
1097
1206
 
@@ -1243,8 +1352,30 @@ function _devNpmDep(name, version) {
1243
1352
  return { type: "dev-npm", name, version };
1244
1353
  }
1245
1354
 
1355
+ // src/workspace-versions.json
1356
+ var workspace_versions_default = {
1357
+ "@stripe/extensibility-custom-objects": "0.8.0",
1358
+ "@stripe/extensibility-custom-objects-tools": "0.42.1",
1359
+ "@stripe/extensibility-dev-tools": "0.25.1",
1360
+ "@stripe/extensibility-eslint-plugin": "0.17.1",
1361
+ "@stripe/extensibility-language-server": "0.3.4",
1362
+ "@stripe/extensibility-sdk": "0.27.1",
1363
+ "@stripe/extensibility-test-helpers": "0.2.7"
1364
+ };
1365
+
1366
+ // src/workspace-versions.ts
1367
+ var _workspaceVersions = workspace_versions_default;
1368
+ function _workspaceVersion(packageName) {
1369
+ const v = _workspaceVersions[packageName];
1370
+ if (v === void 0) {
1371
+ throw new Error(
1372
+ `Unknown workspace package "${packageName}". Check workspace-versions.json or run: tsx scripts/src/sync-workspace-versions.ts`
1373
+ );
1374
+ }
1375
+ return v;
1376
+ }
1377
+
1246
1378
  // src/templates/extensions/base.ts
1247
- import { _workspaceVersion } from "@stripe/extensibility-tool-utils";
1248
1379
  var SDK_PACKAGE_NAME = "@stripe/extensibility-sdk";
1249
1380
  var LANGUAGE_SERVER_PACKAGE_NAME = "@stripe/extensibility-language-server";
1250
1381
  var LANGUAGE_SERVER_PACKAGE_VERSION = `^${_workspaceVersion(LANGUAGE_SERVER_PACKAGE_NAME)}`;
@@ -1549,14 +1680,14 @@ var billing_bill_discount_calculation_default = {
1549
1680
  [EXTENSION_INTERFACE_ID5]: discountCalculationTemplate
1550
1681
  };
1551
1682
 
1552
- // src/templates/extensions/billing.invoice_collection_setting.ts
1553
- var EXTENSION_INTERFACE_ID6 = "billing.invoice_collection_setting";
1554
- var invoiceCollectionSettingTemplate = {
1683
+ // src/templates/extensions/billing.invoice_collection_options.ts
1684
+ var EXTENSION_INTERFACE_ID6 = "billing.invoice_collection_options";
1685
+ var invoiceCollectionOptionsTemplate = {
1555
1686
  hidden: true,
1556
1687
  methods: {
1557
- collection_override: { implementation_types: ["script"] }
1688
+ override_options: { implementation_types: ["script"] }
1558
1689
  },
1559
- description: "Use Stripe Scripts to create custom invoice collection logic that controls how your integration handles invoices generated from subscriptions.",
1690
+ description: "Use Stripe Scripts to create custom invoice collection options that controls how your integration handles invoices generated from subscriptions.",
1560
1691
  generate: (params, context) => {
1561
1692
  const { id } = params;
1562
1693
  const { fs: fs4 } = context;
@@ -1584,15 +1715,15 @@ var invoiceCollectionSettingTemplate = {
1584
1715
  ...base.files
1585
1716
  ],
1586
1717
  methods: {
1587
- collection_override: {
1718
+ override_options: {
1588
1719
  implementation_type: "script"
1589
1720
  }
1590
1721
  }
1591
1722
  };
1592
1723
  }
1593
1724
  };
1594
- var billing_invoice_collection_setting_default = {
1595
- [EXTENSION_INTERFACE_ID6]: invoiceCollectionSettingTemplate
1725
+ var billing_invoice_collection_options_default = {
1726
+ [EXTENSION_INTERFACE_ID6]: invoiceCollectionOptionsTemplate
1596
1727
  };
1597
1728
 
1598
1729
  // src/templates/extensions/billing.prorations.ts
@@ -1700,7 +1831,7 @@ var DEFAULT_TEMPLATES = {
1700
1831
  ...extend_workflows_custom_action_default,
1701
1832
  ...billing_customer_balance_application_default,
1702
1833
  ...billing_bill_discount_calculation_default,
1703
- ...billing_invoice_collection_setting_default,
1834
+ ...billing_invoice_collection_options_default,
1704
1835
  ...billing_prorations_default,
1705
1836
  ...billing_recurring_billing_item_handling_default
1706
1837
  };