diff --git a/.github/workflows/manual-publish-docs.yml b/.github/workflows/manual-publish-docs.yml index 49eefc5774..4d13ee2d92 100644 --- a/.github/workflows/manual-publish-docs.yml +++ b/.github/workflows/manual-publish-docs.yml @@ -12,6 +12,7 @@ on: - packages/shared/sdk-server-edge - packages/sdk/cloudflare - packages/sdk/server-node + - packages/sdk/vercel name: Publish Documentation jobs: build-publish: diff --git a/.github/workflows/manual-publish.yml b/.github/workflows/manual-publish.yml index bc1dd418a6..3c6134a5c2 100644 --- a/.github/workflows/manual-publish.yml +++ b/.github/workflows/manual-publish.yml @@ -13,6 +13,7 @@ on: - packages/shared/sdk-server-edge - packages/sdk/cloudflare - packages/sdk/server-node + - packages/sdk/vercel prerelease: description: 'Is this a prerelease. If so, then the latest tag will not be updated in npm.' type: boolean diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index b1e40dffb2..000735c7de 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -13,6 +13,7 @@ jobs: package-sdk-server-edge-released: ${{ steps.release.outputs['packages/shared/sdk-server-edge--release_created'] }} package-cloudflare-released: ${{ steps.release.outputs['packages/sdk/cloudflare--release_created'] }} package-server-node-released: ${{ steps.release.outputs['packages/sdk/server-node--release_created'] }} + package-vercel-released: ${{ steps.release.outputs['packages/sdk/vercel--release_created'] }} steps: - uses: google-github-actions/release-please-action@v3 id: release @@ -120,3 +121,23 @@ jobs: with: workspace_path: packages/sdk/server-node aws_assume_role: ${{ vars.AWS_ROLE_ARN }} + + release-vercel: + runs-on: ubuntu-latest + needs: ['release-please'] + permissions: + id-token: write + contents: write + if: ${{ needs.release-please.outputs.package-vercel-released }} + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 16.x + registry-url: 'https://registry.npmjs.org' + - id: release-common + name: Full release of packages/sdk/vercel + uses: ./actions/full-release + with: + workspace_path: packages/sdk/vercel + aws_assume_role: ${{ vars.AWS_ROLE_ARN }} diff --git a/.github/workflows/vercel.yml b/.github/workflows/vercel.yml new file mode 100644 index 0000000000..bb16a60e2d --- /dev/null +++ b/.github/workflows/vercel.yml @@ -0,0 +1,24 @@ +name: sdk/vercel + +on: + push: + branches: [main] + paths-ignore: + - '**.md' #Do not need to run CI for markdown changes. + pull_request: + branches: [main] + paths-ignore: + - '**.md' + +jobs: + build-test-vercel: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + - id: shared + name: Shared CI Steps + uses: ./actions/ci + with: + workspace_name: '@launchdarkly/vercel-server-sdk' + workspace_path: packages/sdk/vercel diff --git a/package.json b/package.json index e34ffeb346..5bee76a6f1 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "packages/shared/sdk-server-edge", "packages/sdk/server-node", "packages/sdk/cloudflare", - "packages/sdk/cloudflare/example" + "packages/sdk/cloudflare/example", + "packages/sdk/vercel" ], "private": true, "scripts": { diff --git a/packages/sdk/vercel/CHANGELOG.md b/packages/sdk/vercel/CHANGELOG.md new file mode 100644 index 0000000000..aa2119f903 --- /dev/null +++ b/packages/sdk/vercel/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog + +All notable changes to the LaunchDarkly SDK for Vercel Edge Config will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org). \ No newline at end of file diff --git a/packages/sdk/vercel/README.md b/packages/sdk/vercel/README.md new file mode 100644 index 0000000000..7137b4d2b5 --- /dev/null +++ b/packages/sdk/vercel/README.md @@ -0,0 +1,62 @@ +# LaunchDarkly Vercel Edge SDK + +This library supports using Vercel [Edge Config](https://vercel.com/docs/concepts/edge-network/edge-config) to replace the default in-memory feature store of the [LaunchDarkly Node.js SDK](https://github.com/launchdarkly/vercel-server-sdk). + +For more information, see the [SDK features guide](https://docs.launchdarkly.com/sdk/features/storing-data). + +## Install + +```shell +npm i @launchdarkly/vercel-server-sdk +``` + +or yarn: + +```shell +yarn add -D @launchdarkly/vercel-server-sdk +``` + +## Quickstart + +Initialize the ldClient with the [Vercel Edge SDK](https://vercel.com/docs/concepts/edge-network/edge-config/edge-config-sdk) and your LaunchDarkly client side sdk key: + +```typescript +import init from '@launchdarkly/vercel-server-sdk'; +import { createClient } from '@vercel/edge-config'; + +const edgeClient = createClient(process.env.EDGE_CONFIG); +const ldClient = init('YOUR CLIENT-SIDE SDK KEY', edgeClient); + +await ldClient.waitForInitialization(); +const ldContext = { + kind: 'org', + key: 'my-org-key', + someAttribute: 'my-attribute-value', +}; +const flagValue = await ldClient.variation('my-flag', ldContext, true); +``` + +To learn more, head straight to the [complete reference guide for this SDK](https://docs.launchdarkly.com/sdk/server-side/vercel). + +## Developing this SDK + +```shell +# at js-core repo root +yarn && yarn build && cd packages/sdk/vercel +# run tests +yarn test +``` + +## About LaunchDarkly + +- LaunchDarkly is a continuous delivery platform that provides feature flags as a service and allows developers to iterate quickly and safely. We allow you to easily flag your features and manage them from the LaunchDarkly dashboard. With LaunchDarkly, you can: + - Roll out a new feature to a subset of your users (like a group of users who opt-in to a beta tester group), gathering feedback and bug reports from real-world use cases. + - Gradually roll out a feature to an increasing percentage of users, and track the effect that the feature has on key metrics (for instance, how likely is a user to complete a purchase if they have feature A versus feature B?). + - Turn off a feature that you realize is causing performance problems in production, without needing to re-deploy, or even restart the application with a changed configuration file. + - Grant access to certain features based on user attributes, like payment plan (eg: users on the ‘gold’ plan get access to more features than users in the ‘silver’ plan). Disable parts of your application to facilitate maintenance, without taking everything offline. +- LaunchDarkly provides feature flag SDKs for a wide variety of languages and technologies. Read [our documentation](https://docs.launchdarkly.com/sdk) for a complete list. +- Explore LaunchDarkly + - [launchdarkly.com](https://www.launchdarkly.com/ 'LaunchDarkly Main Website') for more information + - [docs.launchdarkly.com](https://docs.launchdarkly.com/ 'LaunchDarkly Documentation') for our documentation and SDK reference guides + - [apidocs.launchdarkly.com](https://apidocs.launchdarkly.com/ 'LaunchDarkly API Documentation') for our API documentation + - [blog.launchdarkly.com](https://blog.launchdarkly.com/ 'LaunchDarkly Blog Documentation') for the latest product updates diff --git a/packages/sdk/vercel/jest.config.json b/packages/sdk/vercel/jest.config.json new file mode 100644 index 0000000000..6174807746 --- /dev/null +++ b/packages/sdk/vercel/jest.config.json @@ -0,0 +1,9 @@ +{ + "transform": { "^.+\\.ts?$": "ts-jest" }, + "testMatch": ["**/*.test.ts?(x)"], + "testPathIgnorePatterns": ["node_modules", "example", "dist"], + "modulePathIgnorePatterns": ["dist"], + "testEnvironment": "node", + "moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"], + "collectCoverageFrom": ["src/**/*.ts"] +} diff --git a/packages/sdk/vercel/package.json b/packages/sdk/vercel/package.json new file mode 100644 index 0000000000..de1ac7525e --- /dev/null +++ b/packages/sdk/vercel/package.json @@ -0,0 +1,53 @@ +{ + "name": "@launchdarkly/vercel-server-sdk", + "version": "0.1.0", + "description": "LaunchDarkly Server-Side SDK for Vercel Edge", + "packageManager": "yarn@3.4.1", + "keywords": [ + "launchdarkly", + "vercel", + "edge" + ], + "type": "module", + "exports": { + "require": "./dist/cjs/src/index.js", + "import": "./dist/esm/src/index.js" + }, + "main": "./dist/cjs/src/index.js", + "files": [ + "/dist" + ], + "scripts": { + "doc": "../../../scripts/build-doc.sh .", + "build": "../../../scripts/build-package.sh", + "tsw": "yarn tsc --watch", + "start": "rimraf dist && yarn tsw", + "lint": "eslint . --ext .ts", + "prettier": "prettier --write '**/*.@(js|ts|tsx|json|css)'", + "test": "jest --ci --runInBand --coverage", + "check": "yarn prettier && yarn lint && yarn build && yarn test && yarn doc" + }, + "dependencies": { + "@launchdarkly/js-server-sdk-common-edge": "0.0.2", + "crypto-js": "^4.1.1" + }, + "devDependencies": { + "@types/crypto-js": "^4.1.1", + "@types/jest": "^29.5.0", + "@typescript-eslint/eslint-plugin": "^5.57.0", + "@typescript-eslint/parser": "^5.57.0", + "@vercel/edge-config": "^0.1.7", + "eslint": "^8.37.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-airbnb-typescript": "^17.0.0", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-prettier": "^4.2.1", + "jest": "^29.5.0", + "launchdarkly-js-test-helpers": "^2.2.0", + "prettier": "^2.8.7", + "ts-jest": "^29.1.0", + "typedoc": "0.23.26", + "typescript": "^5.0.3" + } +} diff --git a/packages/sdk/vercel/src/createPlatformInfo.test.ts b/packages/sdk/vercel/src/createPlatformInfo.test.ts new file mode 100644 index 0000000000..fad14f69b6 --- /dev/null +++ b/packages/sdk/vercel/src/createPlatformInfo.test.ts @@ -0,0 +1,22 @@ +import { name, version } from '../package.json'; + +import createPlatformInfo from './createPlatformInfo'; + +describe('Vercel Platform Info', () => { + it('platformData shows correct information', () => { + const platformData = createPlatformInfo(); + + expect(platformData.platformData()).toEqual({ + name: 'Vercel Edge', + }); + }); + + it('sdkData shows correct information', () => { + const platformData = createPlatformInfo(); + + expect(platformData.sdkData()).toEqual({ + name, + version, + }); + }); +}); diff --git a/packages/sdk/vercel/src/createPlatformInfo.ts b/packages/sdk/vercel/src/createPlatformInfo.ts new file mode 100644 index 0000000000..4bcb2880ef --- /dev/null +++ b/packages/sdk/vercel/src/createPlatformInfo.ts @@ -0,0 +1,22 @@ +import type { Info, PlatformData, SdkData } from '@launchdarkly/js-server-sdk-common-edge'; + +import { name, version } from '../package.json'; + +class VercelPlatformInfo implements Info { + platformData(): PlatformData { + return { + name: 'Vercel Edge', + }; + } + + sdkData(): SdkData { + return { + name, + version, + }; + } +} + +const createPlatformInfo = () => new VercelPlatformInfo(); + +export default createPlatformInfo; diff --git a/packages/sdk/vercel/src/index.test.ts b/packages/sdk/vercel/src/index.test.ts new file mode 100644 index 0000000000..76706116fc --- /dev/null +++ b/packages/sdk/vercel/src/index.test.ts @@ -0,0 +1,51 @@ +import type { EdgeConfigValue } from '@vercel/edge-config'; +import { LDClient } from '@launchdarkly/js-server-sdk-common-edge'; +import { init } from './index'; +import * as testData from './utils/testData.json'; +import mockEdge from './utils/mockEdge'; + +const sdkKey = 'test-sdk-key'; +const flagKey = 'testFlag1'; +const context = { kind: 'user', key: 'test-user-key-1' }; + +describe('init', () => { + let ldClient: LDClient; + + beforeAll(async () => { + // I can't figure out a way around the generic types used in @vercel/edge-config causing us type issues here. + // The tests work as expected + // @ts-ignore + mockEdge.get = jest.fn(async () => testData as EdgeConfigValue); + ldClient = init(sdkKey, mockEdge); + await ldClient.waitForInitialization(); + }); + + afterAll(() => { + ldClient.close(); + }); + + test('variation', async () => { + const flagDetail = await ldClient.variation(flagKey, context, false); + expect(flagDetail).toBeTruthy(); + }); + + test('variationDetail', async () => { + const flagDetail = await ldClient.variationDetail(flagKey, context, false); + expect(flagDetail).toEqual({ reason: { kind: 'FALLTHROUGH' }, value: true, variationIndex: 0 }); + }); + + test('allFlags', async () => { + const allFlags = await ldClient.allFlagsState(context); + + expect(allFlags).toBeDefined(); + expect(allFlags.toJSON()).toEqual({ + $flagsState: { + testFlag1: { debugEventsUntilDate: null, variation: 0, version: 2 }, + testFlag2: { debugEventsUntilDate: null, variation: 1, version: 2 }, + }, + $valid: true, + testFlag1: true, + testFlag2: false, + }); + }); +}); diff --git a/packages/sdk/vercel/src/index.ts b/packages/sdk/vercel/src/index.ts new file mode 100644 index 0000000000..54056a6be7 --- /dev/null +++ b/packages/sdk/vercel/src/index.ts @@ -0,0 +1,53 @@ +/** + * This is the API reference for the Vercel LaunchDarkly SDK. + * + * In typical usage, you will call {@link init} once at startup time to obtain an instance of + * {@link LDClient}, which provides access to all of the SDK's functionality. + * + * For more information, see the SDK reference guide. + * + * @packageDocumentation + */ +import type { EdgeConfigClient } from '@vercel/edge-config'; +import { + BasicLogger, + init as initEdge, + LDClient, + LDOptions, +} from '@launchdarkly/js-server-sdk-common-edge'; +import VercelFeatureStore from './vercelFeatureStore'; +import createPlatformInfo from './createPlatformInfo'; + +export * from '@launchdarkly/js-server-sdk-common-edge'; + +export type { LDClient }; + +/** + * Creates an instance of the Vercel LaunchDarkly client. + * + * Applications should instantiate a single instance for the lifetime of the worker. + * The client will begin attempting to connect to the configured Vercel Edge Config as + * soon as it is created. To determine when it is ready to use, call {@link LDClient.waitForInitialization}. + * + * **Important:** Do **not** try to instantiate `LDClient` with its constructor + * (`new LDClient()/new LDClientImpl()/new LDClient()`); the SDK does not currently support + * this. + * + * @param edgeConfig + * The Vercel Edge Config client configured for LaunchDarkly. + * @param sdkKey + * The client side SDK key. This is only used to query the edgeConfig above, + * not to connect with LaunchDarkly servers. + * @param options + * Optional configuration settings. The only supported option is logger. + * @return + * The new {@link LDClient} instance. + */ +export const init = (sdkKey: string, edgeConfig: EdgeConfigClient, options: LDOptions = {}) => { + const logger = options.logger ?? BasicLogger.get(); + return initEdge(sdkKey, createPlatformInfo(), { + featureStore: new VercelFeatureStore(edgeConfig, sdkKey, logger), + logger, + ...options, + }); +}; diff --git a/packages/sdk/vercel/src/utils/mockEdge.ts b/packages/sdk/vercel/src/utils/mockEdge.ts new file mode 100644 index 0000000000..1d6d0b3e96 --- /dev/null +++ b/packages/sdk/vercel/src/utils/mockEdge.ts @@ -0,0 +1,10 @@ +import { EdgeConfigClient } from '@vercel/edge-config'; + +const mockEdge: EdgeConfigClient = { + get: jest.fn(), + getAll: jest.fn(), + digest: jest.fn(), + has: jest.fn(), +}; + +export default mockEdge; diff --git a/packages/sdk/vercel/src/utils/testData.json b/packages/sdk/vercel/src/utils/testData.json new file mode 100644 index 0000000000..e5ebbdb071 --- /dev/null +++ b/packages/sdk/vercel/src/utils/testData.json @@ -0,0 +1,50 @@ +{ + "flags": { + "testFlag1": { + "key": "testFlag1", + "on": true, + "prerequisites": [], + "targets": [], + "rules": [], + "fallthrough": { + "variation": 0 + }, + "offVariation": 1, + "variations": [true, false], + "clientSideAvailability": { + "usingMobileKey": true, + "usingEnvironmentId": true + }, + "clientSide": true, + "salt": "aef830243d6640d0a973be89988e008d", + "trackEvents": false, + "trackEventsFallthrough": false, + "debugEventsUntilDate": null, + "version": 2, + "deleted": false + }, + "testFlag2": { + "key": "testFlag2", + "on": false, + "prerequisites": [], + "targets": [], + "rules": [], + "fallthrough": { + "variation": 0 + }, + "offVariation": 1, + "variations": [true, false], + "clientSideAvailability": { + "usingMobileKey": true, + "usingEnvironmentId": true + }, + "clientSide": true, + "salt": "aef830243d6640d0a973be89988e008d", + "trackEvents": false, + "trackEventsFallthrough": false, + "debugEventsUntilDate": null, + "version": 2, + "deleted": false + } + } +} diff --git a/packages/sdk/vercel/src/vercelFeatureStore.test.ts b/packages/sdk/vercel/src/vercelFeatureStore.test.ts new file mode 100644 index 0000000000..956f41c70e --- /dev/null +++ b/packages/sdk/vercel/src/vercelFeatureStore.test.ts @@ -0,0 +1,111 @@ +import { AsyncStoreFacade, LDFeatureStore } from '@launchdarkly/js-server-sdk-common-edge'; +import VercelFeatureStore from './vercelFeatureStore'; + +import mockEdge from './utils/mockEdge'; +import * as testData from './utils/testData.json'; + +describe('VercelFeatureStore', () => { + const sdkKey = 'sdkKey'; + const configKey = `LD-Env-${sdkKey}`; + const mockLogger = { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + debug: jest.fn(), + }; + const mockGet = mockEdge.get as jest.Mock; + let featureStore: LDFeatureStore; + let asyncFeatureStore: AsyncStoreFacade; + + beforeEach(() => { + mockGet.mockImplementation(() => Promise.resolve(testData)); + featureStore = new VercelFeatureStore(mockEdge, sdkKey, mockLogger); + asyncFeatureStore = new AsyncStoreFacade(featureStore); + }); + + afterEach(() => { + jest.resetAllMocks(); + }); + + describe('get', () => { + test('get flag', async () => { + const flag = await asyncFeatureStore.get({ namespace: 'features' }, 'testFlag1'); + + expect(mockGet).toHaveBeenCalledWith(configKey); + expect(flag).toEqual(testData.flags.testFlag1); + }); + + test('invalid flag key', async () => { + const flag = await asyncFeatureStore.get({ namespace: 'features' }, 'invalid'); + + expect(flag).toBeUndefined(); + }); + + test('invalid namespace key', async () => { + const flag = await asyncFeatureStore.get({ namespace: 'invalid' }, 'testFlag1'); + + expect(flag).toBe(null); + }); + + test('invalid edge config key', async () => { + mockGet.mockImplementation(() => Promise.resolve(null)); + const flag = await asyncFeatureStore.get({ namespace: 'features' }, 'testFlag1'); + + expect(flag).toBeNull(); + }); + }); + + describe('all', () => { + test('all flags', async () => { + const flag = await asyncFeatureStore.all({ namespace: 'features' }); + + expect(mockGet).toHaveBeenCalledWith(configKey); + expect(flag).toEqual(testData.flags); + }); + + test('invalid DataKind', async () => { + const flag = await asyncFeatureStore.all({ namespace: 'InvalidDataKind' }); + + expect(flag).toBeUndefined(); + }); + + test('invalid edge config key', async () => { + mockGet.mockImplementation(() => Promise.resolve(null)); + const flag = await asyncFeatureStore.all({ namespace: 'flags11' }); + + expect(flag).toEqual({}); + }); + }); + + describe('initialized', () => { + test('is initialized', async () => { + const isInitialized = await asyncFeatureStore.initialized(); + + expect(mockGet).toHaveBeenCalledWith(configKey); + expect(isInitialized).toBeTruthy(); + }); + + test('not initialized', async () => { + mockGet.mockImplementation(() => Promise.resolve(null)); + const isInitialized = await asyncFeatureStore.initialized(); + + expect(mockGet).toHaveBeenCalledWith(configKey); + expect(isInitialized).toBeFalsy(); + }); + }); + + describe('init & getDescription', () => { + test('init', (done) => { + const cb = jest.fn(() => { + done(); + }); + featureStore.init(testData, cb); + }); + + test('getDescription', async () => { + const description = featureStore.getDescription?.(); + + expect(description).toEqual('Vercel Edge Config'); + }); + }); +}); diff --git a/packages/sdk/vercel/src/vercelFeatureStore.ts b/packages/sdk/vercel/src/vercelFeatureStore.ts new file mode 100644 index 0000000000..851b8ba31a --- /dev/null +++ b/packages/sdk/vercel/src/vercelFeatureStore.ts @@ -0,0 +1,84 @@ +import { EdgeConfigClient } from '@vercel/edge-config'; +import type { + DataKind, + LDLogger, + LDFeatureStore, + LDFeatureStoreDataStorage, + LDFeatureStoreItem, + LDFeatureStoreKindData, +} from '@launchdarkly/js-server-sdk-common-edge'; +import { noop } from '@launchdarkly/js-server-sdk-common-edge'; + +class VercelFeatureStore implements LDFeatureStore { + private edgeConfig: EdgeConfigClient; + + private configKey: string; + + private logger: LDLogger; + + constructor(edgeConfig: EdgeConfigClient, sdkKey: string, logger: LDLogger) { + this.edgeConfig = edgeConfig; + this.configKey = `LD-Env-${sdkKey}`; + this.logger = logger; + } + + async get( + kind: DataKind, + flagKey: string, + callback: (res: LDFeatureStoreItem | null) => void + ): Promise { + this.logger.debug(`Requesting ${flagKey} from ${this.configKey}`); + try { + const config = await this.edgeConfig.get(this.configKey); + if (config === null) { + this.logger.error('Feature data not found in Edge Config.'); + } + const kindKey = kind.namespace === 'features' ? 'flags' : kind.namespace; + const item = config as LDFeatureStoreItem; + callback(item[kindKey][flagKey]); + } catch (err) { + this.logger.error(err); + callback(null); + } + } + + async all(kind: DataKind, callback: (res: LDFeatureStoreKindData) => void = noop): Promise { + const kindKey = kind.namespace === 'features' ? 'flags' : kind.namespace; + this.logger.debug(`Requesting all ${kindKey} data from Edge Config.`); + try { + const config = await this.edgeConfig.get(this.configKey); + if (config === null) { + this.logger.error('Feature data not found in Edge Config.'); + } + const item = config as LDFeatureStoreItem; + callback(item[kindKey]); + } catch (err) { + this.logger.error(err); + callback({}); + } + } + + async initialized(callback: (isInitialized: boolean) => void = noop): Promise { + const config = await this.edgeConfig.get(this.configKey); + const result = config !== null; + this.logger.debug(`Is ${this.configKey} initialized? ${result}`); + callback(result); + } + + init(allData: LDFeatureStoreDataStorage, callback: () => void): void { + callback(); + } + + getDescription(): string { + return 'Vercel Edge Config'; + } + + // unused + close = noop; + + delete = noop; + + upsert = noop; +} + +export default VercelFeatureStore; diff --git a/packages/sdk/vercel/tsconfig.eslint.json b/packages/sdk/vercel/tsconfig.eslint.json new file mode 100644 index 0000000000..56c9b38305 --- /dev/null +++ b/packages/sdk/vercel/tsconfig.eslint.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.json", + "include": ["/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/packages/sdk/vercel/tsconfig.json b/packages/sdk/vercel/tsconfig.json new file mode 100644 index 0000000000..d52294d88d --- /dev/null +++ b/packages/sdk/vercel/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + // Uses "." so it can load package.json. + "rootDir": ".", + "outDir": "dist", + "target": "es6", + "lib": ["es6"], + "module": "commonjs", + "strict": true, + "noImplicitOverride": true, + "allowSyntheticDefaultImports": true, + "sourceMap": true, + "declaration": true, + "declarationMap": true, // enables importers to jump to source + "resolveJsonModule": true, + "stripInternal": true, + "moduleResolution": "node", + "types": ["jest", "node"], + "skipLibCheck": true + }, + "exclude": ["**/*.test.ts", "dist", "node_modules", "__tests__", "example"] +} diff --git a/packages/sdk/vercel/tsconfig.ref.json b/packages/sdk/vercel/tsconfig.ref.json new file mode 100644 index 0000000000..832c1d8dd7 --- /dev/null +++ b/packages/sdk/vercel/tsconfig.ref.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*", "package.json", "src/**/testData.json"], + "compilerOptions": { + "composite": true + } +} diff --git a/release-please-config.json b/release-please-config.json index 013f9dc94e..5cdb3b3cbc 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -14,6 +14,11 @@ }, "packages/sdk/cloudflare": { "bump-minor-pre-major": true + }, + "packages/type/my-package": { + "bump-minor-pre-major": true, + "release-as": "0.1.0", + "bootstrap-sha": "bc70619e59f88b6336cf84f79b1c28c55e54d44b" } }, "plugins": ["node-workspace"] diff --git a/scripts/build-package.sh b/scripts/build-package.sh index cebf3a3719..93e38fe009 100755 --- a/scripts/build-package.sh +++ b/scripts/build-package.sh @@ -23,7 +23,7 @@ ESM_PACKAGE_JSON=$( jq -n \ --arg type "module" \ '{ name: $name, version: $version, type: $type }' ) -tsc --module commonjs --outDir dist/cjs/ +tsc --module commonjs --outDir dist/cjs/ echo "$CJS_PACKAGE_JSON" > dist/cjs/package.json tsc --module es2022 --outDir dist/esm/ diff --git a/tsconfig.json b/tsconfig.json index dccf5ceb5a..e1eada5fb5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,6 +18,9 @@ }, { "path": "./packages/sdk/cloudflare/tsconfig.ref.json" + }, + { + "path": "./packages/sdk/vercel/tsconfig.ref.json" } ] }