sdk(astro,nextjs): add astro sdk and ensure window.op always first on nextjs
This commit is contained in:
@@ -5,4 +5,3 @@
|
|||||||
- `clientSecret` - The client secret of your application (**only required for server-side events**)
|
- `clientSecret` - The client secret of your application (**only required for server-side events**)
|
||||||
- `filter` - A function that will be called before sending an event. If it returns false, the event will not be sent
|
- `filter` - A function that will be called before sending an event. If it returns false, the event will not be sent
|
||||||
- `disabled` - If true, the library will not send any events
|
- `disabled` - If true, the library will not send any events
|
||||||
- `waitForProfile` - If true, the library will wait for the profile to be set before sending events
|
|
||||||
|
|||||||
@@ -2,4 +2,132 @@
|
|||||||
title: Astro
|
title: Astro
|
||||||
---
|
---
|
||||||
|
|
||||||
You can use [script tag](/docs/sdks/script) or [Web SDK](/docs/sdks/web) to track events in Astro.
|
import { Step, Steps } from 'fumadocs-ui/components/steps';
|
||||||
|
import CommonSdkConfig from '@/components/common-sdk-config.mdx';
|
||||||
|
import WebSdkConfig from '@/components/web-sdk-config.mdx';
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
<Steps>
|
||||||
|
### Install dependencies
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm install @openpanel/astro
|
||||||
|
```
|
||||||
|
|
||||||
|
### Initialize
|
||||||
|
|
||||||
|
Add `OpenPanelComponent` to your root layout component.
|
||||||
|
|
||||||
|
```astro
|
||||||
|
---
|
||||||
|
import { OpenPanelComponent } from '@openpanel/astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<OpenPanelComponent
|
||||||
|
clientId="your-client-id"
|
||||||
|
trackScreenViews={true}
|
||||||
|
// trackAttributes={true}
|
||||||
|
// trackOutgoingLinks={true}
|
||||||
|
// If you have a user id, you can pass it here to identify the user
|
||||||
|
// profileId={'123'}
|
||||||
|
/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<slot />
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Options
|
||||||
|
|
||||||
|
<CommonSdkConfig />
|
||||||
|
<WebSdkConfig />
|
||||||
|
|
||||||
|
##### Astro options
|
||||||
|
|
||||||
|
- `profileId` - If you have a user id, you can pass it here to identify the user
|
||||||
|
- `cdnUrl` - The url to the OpenPanel SDK (default: `https://openpanel.dev/op1.js`)
|
||||||
|
- `filter` - This is a function that will be called before tracking an event. If it returns false the event will not be tracked. [Read more](#filter)
|
||||||
|
- `globalProperties` - This is an object of properties that will be sent with every event.
|
||||||
|
|
||||||
|
##### `filter`
|
||||||
|
|
||||||
|
This options needs to be a stringified function and cannot access any variables outside of the function.
|
||||||
|
|
||||||
|
```astro
|
||||||
|
<OpenPanelComponent
|
||||||
|
clientId="your-client-id"
|
||||||
|
filter={`
|
||||||
|
function filter(event) {
|
||||||
|
return event.name !== 'my_event';
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
To take advantage of typescript you can do the following. _Note `toString`_
|
||||||
|
```ts
|
||||||
|
import { type TrackHandlerPayload } from '@openpanel/astro';
|
||||||
|
|
||||||
|
const opFilter = ((event: TrackHandlerPayload) => {
|
||||||
|
return event.type === 'track' && event.payload.name === 'my_event';
|
||||||
|
}).toString();
|
||||||
|
|
||||||
|
<OpenPanelComponent
|
||||||
|
clientId="your-client-id"
|
||||||
|
filter={opFilter}
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
</Steps>
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Client-side Tracking
|
||||||
|
|
||||||
|
You can track events with the global op function or you can use data attributes.
|
||||||
|
|
||||||
|
```astro
|
||||||
|
<button onclick="window.op('track', 'clicky')">Click me</button>
|
||||||
|
<button data-track="clicky" data-prop1="prop1" data-prop2="prop2">Click me</button>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Identifying Users
|
||||||
|
|
||||||
|
To identify a user, you can use either the `identify` function or the `IdentifyComponent`.
|
||||||
|
|
||||||
|
```astro
|
||||||
|
---
|
||||||
|
import { IdentifyComponent } from '@openpanel/astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<IdentifyComponent
|
||||||
|
profileId="123"
|
||||||
|
firstName="Joe"
|
||||||
|
lastName="Doe"
|
||||||
|
email="joe@doe.com"
|
||||||
|
properties={{
|
||||||
|
tier: 'premium',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Setting Global Properties
|
||||||
|
|
||||||
|
You can set global properties that will be sent with every event using either the `setGlobalProperties` function or the `SetGlobalPropertiesComponent`.
|
||||||
|
|
||||||
|
```astro
|
||||||
|
---
|
||||||
|
import { SetGlobalPropertiesComponent } from '@openpanel/astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<SetGlobalPropertiesComponent
|
||||||
|
properties={{
|
||||||
|
app_version: '1.0.2',
|
||||||
|
environment: 'production',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
```
|
||||||
3
packages/sdks/astro/README.md
Normal file
3
packages/sdks/astro/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# OpenPanel Astro SDK
|
||||||
|
|
||||||
|
Read full documentation [here](https://openpanel.dev/docs/sdks/astro)
|
||||||
7
packages/sdks/astro/env.d.ts
vendored
Normal file
7
packages/sdks/astro/env.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
declare module '*.astro' {
|
||||||
|
import type { AstroComponentFactory } from 'astro';
|
||||||
|
const component: AstroComponentFactory;
|
||||||
|
export default component;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <reference types="astro/client" />
|
||||||
46
packages/sdks/astro/index.ts
Normal file
46
packages/sdks/astro/index.ts
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import type {
|
||||||
|
DecrementPayload,
|
||||||
|
IdentifyPayload,
|
||||||
|
IncrementPayload,
|
||||||
|
TrackProperties,
|
||||||
|
} from '@openpanel/web';
|
||||||
|
import IdentifyComponent from './src/IdentifyComponent.astro';
|
||||||
|
import OpenPanelComponent from './src/OpenPanelComponent.astro';
|
||||||
|
import SetGlobalPropertiesComponent from './src/SetGlobalPropertiesComponent.astro';
|
||||||
|
|
||||||
|
export * from '@openpanel/web';
|
||||||
|
|
||||||
|
export { OpenPanelComponent, IdentifyComponent, SetGlobalPropertiesComponent };
|
||||||
|
|
||||||
|
export function setGlobalProperties(properties: Record<string, unknown>) {
|
||||||
|
window.op?.('setGlobalProperties', properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function track(name: string, properties?: TrackProperties) {
|
||||||
|
window.op?.('track', name, properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function screenView(properties?: TrackProperties): void;
|
||||||
|
export function screenView(path: string, properties?: TrackProperties): void;
|
||||||
|
export function screenView(
|
||||||
|
pathOrProperties?: string | TrackProperties,
|
||||||
|
propertiesOrUndefined?: TrackProperties,
|
||||||
|
) {
|
||||||
|
window.op?.('screenView', pathOrProperties, propertiesOrUndefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function identify(payload: IdentifyPayload) {
|
||||||
|
window.op?.('identify', payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function increment(payload: IncrementPayload) {
|
||||||
|
window.op?.('increment', payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function decrement(payload: DecrementPayload) {
|
||||||
|
window.op('decrement', payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function clear() {
|
||||||
|
window.op?.('clear');
|
||||||
|
}
|
||||||
27
packages/sdks/astro/package.json
Normal file
27
packages/sdks/astro/package.json
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"name": "@openpanel/astro",
|
||||||
|
"version": "1.0.1-local",
|
||||||
|
"config": {
|
||||||
|
"transformPackageJson": false,
|
||||||
|
"transformEnvs": true
|
||||||
|
},
|
||||||
|
"exports": {
|
||||||
|
".": "./index.ts"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"typecheck": "tsc --noEmit"
|
||||||
|
},
|
||||||
|
"files": ["src", "index.ts"],
|
||||||
|
"keywords": ["astro-component"],
|
||||||
|
"dependencies": {
|
||||||
|
"@openpanel/web": "workspace:1.0.1-local"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"astro": "^5.7.7"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"astro": "^4.0.0 || ^5.0.0"
|
||||||
|
},
|
||||||
|
"private": false,
|
||||||
|
"type": "module"
|
||||||
|
}
|
||||||
9
packages/sdks/astro/src/IdentifyComponent.astro
Normal file
9
packages/sdks/astro/src/IdentifyComponent.astro
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
import type { IdentifyPayload } from '@openpanel/web';
|
||||||
|
import { filterProps } from './asto-utils';
|
||||||
|
interface Props extends IdentifyPayload {}
|
||||||
|
|
||||||
|
const props = Astro.props as Props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<script is:inline set:html={`window.op('identify', ${JSON.stringify(filterProps(props))});`} />
|
||||||
66
packages/sdks/astro/src/OpenPanelComponent.astro
Normal file
66
packages/sdks/astro/src/OpenPanelComponent.astro
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
---
|
||||||
|
import type {
|
||||||
|
OpenPanelMethodNames,
|
||||||
|
OpenPanelOptions
|
||||||
|
} from '@openpanel/web';
|
||||||
|
|
||||||
|
type Props = Omit<OpenPanelOptions, 'filter'> & {
|
||||||
|
profileId?: string;
|
||||||
|
cdnUrl?: string;
|
||||||
|
filter?: string;
|
||||||
|
globalProperties?: Record<string, unknown>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const { profileId, cdnUrl, globalProperties, ...options } = Astro.props;
|
||||||
|
|
||||||
|
const CDN_URL = 'https://openpanel.dev/op1.js';
|
||||||
|
|
||||||
|
const stringify = (obj: unknown) => {
|
||||||
|
if (typeof obj === 'object' && obj !== null && obj !== undefined) {
|
||||||
|
const entries = Object.entries(obj).map(([key, value]) => {
|
||||||
|
if (key === 'filter') {
|
||||||
|
return `"${key}":${value}`;
|
||||||
|
}
|
||||||
|
return `"${key}":${JSON.stringify(value)}`;
|
||||||
|
});
|
||||||
|
return `{${entries.join(',')}}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSON.stringify(obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
const methods: { name: OpenPanelMethodNames; value: unknown }[] = [
|
||||||
|
{
|
||||||
|
name: 'init',
|
||||||
|
value: {
|
||||||
|
...options,
|
||||||
|
sdk: 'astro',
|
||||||
|
sdkVersion: '1.0.1',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
if (profileId) {
|
||||||
|
methods.push({
|
||||||
|
name: 'identify',
|
||||||
|
value: {
|
||||||
|
profileId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (globalProperties) {
|
||||||
|
methods.push({
|
||||||
|
name: 'setGlobalProperties',
|
||||||
|
value: globalProperties,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const scriptContent = `window.op = window.op || function(...args) {(window.op.q = window.op.q || []).push(args)};
|
||||||
|
${methods
|
||||||
|
.map((method) => {
|
||||||
|
return `window.op('${method.name}', ${stringify(method.value)});`;
|
||||||
|
})
|
||||||
|
.join('\n')}`;
|
||||||
|
---
|
||||||
|
|
||||||
|
<script src={cdnUrl ?? CDN_URL} async defer />
|
||||||
|
<script is:inline set:html={scriptContent} />
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
import { filterProps } from './asto-utils';
|
||||||
|
|
||||||
|
type Props = Record<string, unknown>;
|
||||||
|
|
||||||
|
const props = Astro.props as Props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<script is:inline set:html={`window.op('setGlobalProperties', ${JSON.stringify(filterProps(props))});`} />
|
||||||
7
packages/sdks/astro/src/asto-utils.ts
Normal file
7
packages/sdks/astro/src/asto-utils.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
const BLACKLISTED_PROPS = ['class'];
|
||||||
|
|
||||||
|
export function filterProps(props: Record<string, unknown>) {
|
||||||
|
return Object.fromEntries(
|
||||||
|
Object.entries(props).filter(([key]) => !BLACKLISTED_PROPS.includes(key)),
|
||||||
|
);
|
||||||
|
}
|
||||||
13
packages/sdks/astro/tsconfig.json
Normal file
13
packages/sdks/astro/tsconfig.json
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"extends": "astro/tsconfigs/strict",
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "@astrojs/ts-plugin"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"include": [".astro/types.d.ts", "**/*"],
|
||||||
|
"exclude": ["dist"],
|
||||||
|
"compilerOptions": {
|
||||||
|
"jsx": "preserve"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -71,6 +71,7 @@ export function OpenPanelComponent({
|
|||||||
<>
|
<>
|
||||||
<Script src={cdnUrl ?? CDN_URL} async defer />
|
<Script src={cdnUrl ?? CDN_URL} async defer />
|
||||||
<Script
|
<Script
|
||||||
|
strategy="beforeInteractive"
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={{
|
||||||
__html: `window.op = window.op || function(...args) {(window.op.q = window.op.q || []).push(args)};
|
__html: `window.op = window.op || function(...args) {(window.op.q = window.op.q || []).push(args)};
|
||||||
${methods
|
${methods
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@openpanel/nextjs",
|
"name": "@openpanel/nextjs",
|
||||||
"version": "1.0.7-local",
|
"version": "1.0.8-local",
|
||||||
"module": "index.ts",
|
"module": "index.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rm -rf dist && tsup",
|
"build": "rm -rf dist && tsup",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { defineConfig } from 'tsup';
|
import { defineConfig } from 'tsup';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
|
format: ['cjs', 'esm'],
|
||||||
entry: ['index.tsx', 'server.ts'],
|
entry: ['index.tsx', 'server.ts'],
|
||||||
external: ['react', 'next'],
|
external: ['react', 'next'],
|
||||||
dts: true,
|
dts: true,
|
||||||
|
|||||||
1731
pnpm-lock.yaml
generated
1731
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"publish": "pnpm dlx ts-node publish.ts",
|
"publish": "jiti publish.ts",
|
||||||
"typecheck": "tsc --noEmit"
|
"typecheck": "tsc --noEmit"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { execSync } from 'node:child_process';
|
import { execSync } from 'node:child_process';
|
||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import path from 'node:path';
|
import { join, resolve } from 'node:path';
|
||||||
import arg from 'arg';
|
import arg from 'arg';
|
||||||
import type { ReleaseType } from 'semver';
|
import type { ReleaseType } from 'semver';
|
||||||
import semver, { RELEASE_TYPES } from 'semver';
|
import semver, { RELEASE_TYPES } from 'semver';
|
||||||
@@ -9,9 +9,14 @@ import semver, { RELEASE_TYPES } from 'semver';
|
|||||||
interface PackageJson {
|
interface PackageJson {
|
||||||
name: string;
|
name: string;
|
||||||
version: string;
|
version: string;
|
||||||
|
scripts?: Record<string, string>;
|
||||||
dependencies?: Record<string, string>;
|
dependencies?: Record<string, string>;
|
||||||
devDependencies?: Record<string, string>;
|
devDependencies?: Record<string, string>;
|
||||||
[key: string]: unknown;
|
[key: string]: unknown;
|
||||||
|
config?: {
|
||||||
|
transformPackageJson?: boolean;
|
||||||
|
transformEnvs: boolean;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PackageInfo extends PackageJson {
|
interface PackageInfo extends PackageJson {
|
||||||
@@ -21,15 +26,16 @@ interface PackageInfo extends PackageJson {
|
|||||||
|
|
||||||
interface PublishConfig {
|
interface PublishConfig {
|
||||||
registry: string;
|
registry: string;
|
||||||
test: boolean;
|
clear: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
const workspacePath = (relativePath: string) =>
|
const workspacePath = (relativePath: string) =>
|
||||||
path.resolve(__dirname, '../../', relativePath);
|
resolve(__dirname, '../../', relativePath);
|
||||||
|
|
||||||
const savePackageJson = (absPath: string, data: PackageJson) => {
|
const savePackageJson = (absPath: string, data: PackageJson) => {
|
||||||
fs.writeFileSync(absPath, JSON.stringify(data, null, 2), 'utf-8');
|
fs.writeFileSync(absPath, JSON.stringify(data, null, 2), 'utf-8');
|
||||||
|
execSync(`npx biome format ${absPath} --fix`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const exit = (message: string, error?: unknown) => {
|
const exit = (message: string, error?: unknown) => {
|
||||||
@@ -54,7 +60,7 @@ const getNextVersion = (version: string, type: ReleaseType): string => {
|
|||||||
const nextVersion = semver.inc(version, type);
|
const nextVersion = semver.inc(version, type);
|
||||||
if (!nextVersion) throw new Error('Invalid version');
|
if (!nextVersion) throw new Error('Invalid version');
|
||||||
return type.startsWith('pre')
|
return type.startsWith('pre')
|
||||||
? nextVersion.replace(/-.*$/, '-beta')
|
? nextVersion.replace(/-.*$/, '-rc')
|
||||||
: nextVersion;
|
: nextVersion;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -70,7 +76,7 @@ const loadPackages = (
|
|||||||
|
|
||||||
return Object.fromEntries(
|
return Object.fromEntries(
|
||||||
sdks.map((sdk) => {
|
sdks.map((sdk) => {
|
||||||
const pkgPath = path.join(sdksPath, sdk, 'package.json');
|
const pkgPath = join(sdksPath, sdk, 'package.json');
|
||||||
const pkgJson = JSON.parse(
|
const pkgJson = JSON.parse(
|
||||||
fs.readFileSync(pkgPath, 'utf-8'),
|
fs.readFileSync(pkgPath, 'utf-8'),
|
||||||
) as PackageJson;
|
) as PackageJson;
|
||||||
@@ -111,15 +117,32 @@ const updatePackageJsonForRelease = (
|
|||||||
dependents: string[],
|
dependents: string[],
|
||||||
): void => {
|
): void => {
|
||||||
const { nextVersion, localPath, ...restPkgJson } = packages[name]!;
|
const { nextVersion, localPath, ...restPkgJson } = packages[name]!;
|
||||||
const newPkgJson: PackageJson = {
|
let newPkgJson: PackageJson = {
|
||||||
...restPkgJson,
|
...restPkgJson,
|
||||||
private: false,
|
private: false,
|
||||||
type: 'module',
|
type: 'module',
|
||||||
|
version: nextVersion,
|
||||||
|
dependencies: Object.fromEntries(
|
||||||
|
Object.entries(restPkgJson.dependencies || {}).map(
|
||||||
|
([depName, depVersion]) => [
|
||||||
|
depName,
|
||||||
|
dependents.includes(depName)
|
||||||
|
? packages[depName]?.nextVersion ||
|
||||||
|
depVersion.replace(/-local$/, '').replace(/^workspace:/, '')
|
||||||
|
: depVersion.replace(/-local$/, '').replace(/^workspace:/, ''),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (packages[name]!.config?.transformPackageJson !== false) {
|
||||||
|
newPkgJson = {
|
||||||
|
...newPkgJson,
|
||||||
main: './dist/index.js',
|
main: './dist/index.js',
|
||||||
module: './dist/index.mjs',
|
module: './dist/index.mjs',
|
||||||
types: './dist/index.d.ts',
|
types: './dist/index.d.ts',
|
||||||
files: ['dist'],
|
files: ['dist'],
|
||||||
exports: {
|
exports: restPkgJson.exports ?? {
|
||||||
'.': {
|
'.': {
|
||||||
import: './dist/index.js',
|
import: './dist/index.js',
|
||||||
require: './dist/index.cjs',
|
require: './dist/index.cjs',
|
||||||
@@ -135,24 +158,57 @@ const updatePackageJsonForRelease = (
|
|||||||
}
|
}
|
||||||
: {}),
|
: {}),
|
||||||
},
|
},
|
||||||
version: nextVersion,
|
|
||||||
dependencies: Object.fromEntries(
|
|
||||||
Object.entries(restPkgJson.dependencies || {}).map(
|
|
||||||
([depName, depVersion]) => [
|
|
||||||
depName,
|
|
||||||
dependents.includes(depName)
|
|
||||||
? packages[depName]?.nextVersion ||
|
|
||||||
depVersion.replace(/-local$/, '')
|
|
||||||
: depVersion.replace(/-local$/, ''),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
savePackageJson(workspacePath(`${localPath}/package.json`), newPkgJson);
|
savePackageJson(workspacePath(`${localPath}/package.json`), newPkgJson);
|
||||||
packages[name]!.dependencies = newPkgJson.dependencies;
|
packages[name]!.dependencies = newPkgJson.dependencies;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const searchAndReplace = (path: string, search: RegExp, replace: string) => {
|
||||||
|
const files = fs.readdirSync(path);
|
||||||
|
for (const file of files) {
|
||||||
|
const fullpath = join(path, file);
|
||||||
|
if (file === 'node_modules') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (file.includes('.')) {
|
||||||
|
const content = fs.readFileSync(fullpath, {
|
||||||
|
encoding: 'utf-8',
|
||||||
|
});
|
||||||
|
|
||||||
|
const match = content.match(search);
|
||||||
|
if (match) {
|
||||||
|
console.log(`✏️ Will replace ${search} with ${replace} in ${file}`);
|
||||||
|
const newContent = content.replaceAll(search, replace);
|
||||||
|
fs.writeFileSync(fullpath, newContent, {
|
||||||
|
encoding: 'utf-8',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
searchAndReplace(fullpath, search, replace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const transformPackages = (
|
||||||
|
packages: Record<string, PackageInfo>,
|
||||||
|
dependents: string[],
|
||||||
|
): void => {
|
||||||
|
for (const dep of dependents) {
|
||||||
|
const pkg = packages[dep];
|
||||||
|
if (pkg && pkg.config?.transformEnvs === true) {
|
||||||
|
const currentVersion = pkg.version;
|
||||||
|
const nextVersion = pkg.nextVersion;
|
||||||
|
searchAndReplace(
|
||||||
|
workspacePath(pkg.localPath),
|
||||||
|
new RegExp(`${currentVersion}`, 'g'),
|
||||||
|
nextVersion,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const buildPackages = (
|
const buildPackages = (
|
||||||
packages: Record<string, PackageInfo>,
|
packages: Record<string, PackageInfo>,
|
||||||
dependents: string[],
|
dependents: string[],
|
||||||
@@ -166,6 +222,10 @@ const buildPackages = (
|
|||||||
});
|
});
|
||||||
|
|
||||||
for (const dep of dependents) {
|
for (const dep of dependents) {
|
||||||
|
if (!packages[dep]?.scripts?.build) {
|
||||||
|
console.log(`🔨 Skipping build for ${dep}`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
console.log(`🔨 Building ${dep}`);
|
console.log(`🔨 Building ${dep}`);
|
||||||
const cmd = `pnpm build ${versionEnvs.join(' ')}`;
|
const cmd = `pnpm build ${versionEnvs.join(' ')}`;
|
||||||
console.log(` Running: ${cmd}`);
|
console.log(` Running: ${cmd}`);
|
||||||
@@ -180,7 +240,7 @@ const publishPackages = (
|
|||||||
dependents: string[],
|
dependents: string[],
|
||||||
config: PublishConfig,
|
config: PublishConfig,
|
||||||
): void => {
|
): void => {
|
||||||
if (config.test) {
|
if (config.clear) {
|
||||||
execSync('rm -rf ~/.local/share/verdaccio/storage/@openpanel');
|
execSync('rm -rf ~/.local/share/verdaccio/storage/@openpanel');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,9 +263,8 @@ const restoreAndUpdateLocal = (
|
|||||||
dependents: string[],
|
dependents: string[],
|
||||||
): void => {
|
): void => {
|
||||||
const filesToRestore = dependents
|
const filesToRestore = dependents
|
||||||
.map((dep) => workspacePath(packages[dep]!.localPath))
|
.map((dep) => join(workspacePath(packages[dep]!.localPath), 'package.json'))
|
||||||
.join(' ');
|
.join(' ');
|
||||||
console.log(`git checkout ${filesToRestore}`);
|
|
||||||
|
|
||||||
execSync(`git checkout ${filesToRestore}`);
|
execSync(`git checkout ${filesToRestore}`);
|
||||||
|
|
||||||
@@ -221,9 +280,9 @@ const restoreAndUpdateLocal = (
|
|||||||
([depName, depVersion]) => [
|
([depName, depVersion]) => [
|
||||||
depName,
|
depName,
|
||||||
dependents.includes(depName)
|
dependents.includes(depName)
|
||||||
? `${packages[depName]!.nextVersion}-local`
|
? `workspace:${packages[depName]!.nextVersion}-local`
|
||||||
: packages[depName]
|
: packages[depName]
|
||||||
? `${packages[depName]!.version}-local`
|
? `workspace:${packages[depName]!.version}-local`
|
||||||
: depVersion,
|
: depVersion,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -251,9 +310,10 @@ function main() {
|
|||||||
const args = arg({
|
const args = arg({
|
||||||
'--name': String,
|
'--name': String,
|
||||||
'--publish': Boolean,
|
'--publish': Boolean,
|
||||||
'--test': Boolean,
|
'--npm': Boolean,
|
||||||
'--skip-git': Boolean,
|
'--skip-git': Boolean,
|
||||||
'--type': String,
|
'--type': String,
|
||||||
|
'--clear': Boolean,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!args['--skip-git']) {
|
if (!args['--skip-git']) {
|
||||||
@@ -287,14 +347,16 @@ function main() {
|
|||||||
updatePackageJsonForRelease(packages, dep, dependents);
|
updatePackageJsonForRelease(packages, dep, dependents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transformPackages(packages, dependents);
|
||||||
|
|
||||||
buildPackages(packages, dependents);
|
buildPackages(packages, dependents);
|
||||||
|
|
||||||
if (args['--publish']) {
|
if (args['--publish']) {
|
||||||
const config: PublishConfig = {
|
const config: PublishConfig = {
|
||||||
registry: args['--test']
|
registry: args['--npm']
|
||||||
? 'http://localhost:4873'
|
? 'https://registry.npmjs.org'
|
||||||
: 'https://registry.npmjs.org',
|
: 'http://localhost:4873',
|
||||||
test: args['--test'] || false,
|
clear: args['--clear'] || false,
|
||||||
};
|
};
|
||||||
|
|
||||||
publishPackages(packages, dependents, config);
|
publishPackages(packages, dependents, config);
|
||||||
|
|||||||
Reference in New Issue
Block a user