Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Try split entries of date-adapters #4471

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .changeset/good-jokes-punch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
"@salt-ds/date-adapters": minor
---

Split date adapters into sub packages to help with peerDependencies resolution

```diff
- import { AdapterDateFns } from "@salt-ds/date-adapters";
- import { AdapterDayjs } from "@salt-ds/date-adapters";
- import { AdapterLuxon } from "@salt-ds/date-adapters";
- import { AdapterMoment } from "@salt-ds/date-adapters";
+ import { AdapterDateFns } from "@salt-ds/date-adapters/date-fns";
+ import { AdapterDayjs } from "@salt-ds/date-adapters/dayjs";
+ import { AdapterLuxon } from "@salt-ds/date-adapters/luxon";
+ import { AdapterMoment } from "@salt-ds/date-adapters/moment";
```
5 changes: 4 additions & 1 deletion cypress/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
"extends": "../tsconfig.json",
"compilerOptions": {
"jsx": "react-jsx",
"types": ["cypress"]
"types": ["cypress"],
"paths": {
"@salt-ds/date-adapters/*": ["../packages/date-adapters/src/*"]
}
},
"include": ["**/*.ts", "**/*.tsx"]
}
8 changes: 4 additions & 4 deletions docs/decorators/withLocalization.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { Decorator } from "@storybook/react";
import "dayjs/locale/en";
import { AdapterDateFns } from "@salt-ds/date-adapters";
import { AdapterDayjs } from "@salt-ds/date-adapters";
import { AdapterLuxon } from "@salt-ds/date-adapters";
import { AdapterMoment } from "@salt-ds/date-adapters";
import { AdapterDateFns } from "@salt-ds/date-adapters/date-fns";
import { AdapterDayjs } from "@salt-ds/date-adapters/dayjs";
import { AdapterLuxon } from "@salt-ds/date-adapters/luxon";
import { AdapterMoment } from "@salt-ds/date-adapters/moment";
import { LocalizationProvider } from "@salt-ds/lab";
import { enUS as dateFnsEnUs } from "date-fns/locale";

Expand Down
11 changes: 9 additions & 2 deletions packages/date-adapters/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@
"provenance": true
},
"scripts": {
"build": "yarn node ../../scripts/build.mjs"
}
"build": "yarn node ../../scripts/build.mjs && yarn build:entries",
"build:entries": "yarn node ./scripts/build.mjs"
},
"files": [
"/date-fns",
"/dayjs",
"/luxon",
"/moment"
]
}
131 changes: 131 additions & 0 deletions packages/date-adapters/scripts/build.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import path from "node:path";
import commonjs from "@rollup/plugin-commonjs";
import json from "@rollup/plugin-json";
import { nodeResolve } from "@rollup/plugin-node-resolve";
import browserslistToEsbuild from "browserslist-to-esbuild";
import fs from "fs-extra";
import { rollup } from "rollup";
import esbuild from "rollup-plugin-esbuild";
import postcss from "rollup-plugin-postcss";
import { makeTypings } from "./makeTypings.mjs";
// import { transformWorkspaceDeps } from "./transformWorkspaceDeps.mjs";
// import { distinct } from "./utils.mjs";

const cwd = process.cwd();

const packageJson = (
await import(path.join("file://", cwd, "package.json"), {
with: { type: "json" },
})
).default;

const FILES_TO_COPY = [];
// ["README.md", "LICENSE", "CHANGELOG.md"].concat(
// packageJson.files ?? [],
// );

const ENTRY_FOLDERS = ["date-fns", "dayjs", "luxon", "moment"];

for (const entry of ENTRY_FOLDERS) {
const packageName = `${packageJson.name}/${entry}`;

const outputDir = path.join(packageJson.publishConfig.directory, entry);

console.log(`Building ${packageName}`);

await fs.mkdirp(outputDir);
await fs.emptyDir(outputDir);

await makeTypings(outputDir, entry);

const bundle = await rollup({
input: path.join(cwd, "src", entry, "index.ts"),
external: (id) => {
// via tsdx
// TODO: this should probably be included into deps instead
if (id === "babel-plugin-transform-async-to-promises/helpers") {
// we want to inline these helpers
return false;
}
// exclude any dependency that's not a realtive import
return !id.startsWith(".") && !path.isAbsolute(id);
},
treeshake: {
propertyReadSideEffects: false,
},
plugins: [
nodeResolve({
extensions: [".ts", ".tsx", ".js", ".jsx"],
browser: true,
mainFields: ["module", "main", "browser"],
}),
commonjs({ include: /\/node_modules\// }),
esbuild({
target: browserslistToEsbuild(),
minify: false,
sourceMap: true,
}),
postcss({ extract: false, inject: false }),
json(),
],
});

const transformSourceMap = (relativeSourcePath, sourceMapPath) => {
// make source map input files relative to the `${packagePath}/dist-${format}` within
// the package directory

const absoluteSourcepath = path.resolve(
path.dirname(sourceMapPath),
relativeSourcePath,
);
const packageRelativeSourcePath = path.relative(cwd, absoluteSourcepath);

return `../${packageRelativeSourcePath}`;
};

await bundle.write({
freeze: false,
sourcemap: true,
preserveModules: true,
dir: path.join(outputDir, "dist-cjs"),
format: "cjs",
exports: "auto",
sourcemapPathTransform: transformSourceMap,
});

await bundle.write({
freeze: false,
sourcemap: true,
preserveModules: true,
dir: path.join(outputDir, "dist-es"),
format: "es",
exports: "auto",
sourcemapPathTransform: transformSourceMap,
});

await bundle.close();

await fs.writeJSON(
path.join(outputDir, "package.json"),
{
sideEffects: false,
main: `dist-cjs/${entry}/index.js`,
module: `dist-es/${entry}/index.js`,
typings: `dist-types/${entry}/index.d.ts`,
},
{ spaces: 2 },
);

for (const file of FILES_TO_COPY) {
const filePath = path.join(cwd, file);
try {
await fs.copy(filePath, path.join(outputDir, file));
} catch (error) {
if (error.code !== "ENOENT") {
throw error;
}
}
}

console.log(`Built ${packageName} into ${outputDir}`);
}
128 changes: 128 additions & 0 deletions packages/date-adapters/scripts/makeTypings.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import path from "node:path";
import { isCI } from "ci-info";
import fse from "fs-extra";
import { getTsconfig } from "get-tsconfig";
import ts from "typescript";

const typescriptConfigFilename = "tsconfig.json";
const cwd = process.cwd();

export function reportTSDiagnostics(diagnostics) {
for (const diagnostic of diagnostics) {
let message = "Error";
if (diagnostic.file) {
const where = diagnostic.file.getLineAndCharacterOfPosition(
diagnostic.start,
);
message += ` ${diagnostic.file.fileName} ${where.line}, ${
where.character + 1
}`;
}
message += `: ${ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n")}`;
console.error(message);
}
}

export async function makeTypings(outDir, entryFolder) {
const typescriptConfig = await getTypescriptConfig(cwd, entryFolder);

console.log("generating .d.ts files");

// make a shallow copy of the configuration
const tsconfig = {
...typescriptConfig,
compilerOptions: {
...typescriptConfig.compilerOptions,
},
};

// then add our custom stuff
// Only include src files from the package to prevent already built
// files from interferring with the compile
tsconfig.include = [path.join(cwd, "src", entryFolder)];
tsconfig.compilerOptions = {
...tsconfig.compilerOptions,
noEmit: false,
declaration: true,
emitDeclarationOnly: true,
declarationDir: path.join(outDir, "dist-types"),
rootDir: path.join(cwd, "src"),
diagnostics: !isCI,
};

// Extract config information
const configParseResult = ts.parseJsonConfigFileContent(
tsconfig,
ts.sys,
path.dirname(typescriptConfigFilename),
);

if (configParseResult.errors.length > 0) {
reportTSDiagnostics(configParseResult.errors);
throw new Error("Could not parse Typescript configuration");
}

const host = ts.createCompilerHost(configParseResult.options);
host.writeFile = (fileName, contents) => {
fse.mkdirpSync(path.dirname(fileName));
fse.writeFileSync(fileName, contents);
};

// Compile
const program = ts.createProgram(
configParseResult.fileNames,
configParseResult.options,
host,
);

const emitResult = program.emit();

// Skip diagnostic reporting in CI
if (isCI) {
return;
}
const diagnostics = ts
.getPreEmitDiagnostics(program)
.concat(emitResult.diagnostics);
if (diagnostics.length > 0) {
reportTSDiagnostics(diagnostics);
throw new Error("Could not generate .d.ts files");
}
}

export function distinct(arr) {
return [...new Set(arr)];
}

export async function getTypescriptConfig(cwd, entryFolder) {
const typescriptConfig = {};

const result = getTsconfig(cwd);

Object.assign(typescriptConfig, result.config, {
include: [path.join(cwd, "src", entryFolder)],
exclude: distinct(
[
// all TS test files, regardless whether co-located or in test/ etc
"**/*.stories.ts",
"**/*.stories.tsx",
"**/*.spec.ts",
"**/*.test.ts",
"**/*.e2e.ts",
"**/*.spec.tsx",
"**/*.test.tsx",
"**/__tests__",
"**/dist-cjs",
"**/dist-es",
"**/dist-types",
// TS defaults below
"node_modules",
"bower_components",
"jspm_packages",
"tmp",
].concat(result.exclude ?? []),
),
});

return typescriptConfig;
}
3 changes: 2 additions & 1 deletion packages/date-adapters/src/__tests__/date-fns.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { isValid } from "date-fns";
import { enUS } from "date-fns/locale";
import { describe, expect, it } from "vitest";
import { AdapterDateFns, DateDetailErrorEnum } from "../index";
import { AdapterDateFns } from "../date-fns";
import { DateDetailErrorEnum } from "../index";

describe("GIVEN a AdapterDateFns", () => {
const adapter = new AdapterDateFns({ locale: enUS });
Expand Down
3 changes: 2 additions & 1 deletion packages/date-adapters/src/__tests__/dayjs.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import customParseFormat from "dayjs/plugin/customParseFormat";
import timezone from "dayjs/plugin/timezone";
import utc from "dayjs/plugin/utc";
import { describe, expect, it } from "vitest";
import { AdapterDayjs, DateDetailErrorEnum } from "../index";
import { AdapterDayjs } from "../dayjs";
import { DateDetailErrorEnum } from "../index";

// Extend dayjs with necessary plugins
dayjs.extend(utc);
Expand Down
3 changes: 2 additions & 1 deletion packages/date-adapters/src/__tests__/luxon.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { DateTime } from "luxon";
import { describe, expect, it } from "vitest";
import { AdapterLuxon, DateDetailErrorEnum } from "../index";
import { DateDetailErrorEnum } from "../index";
import { AdapterLuxon } from "../luxon";

describe("GIVEN a AdapterLuxon", () => {
const adapter = new AdapterLuxon({ locale: "en-US" });
Expand Down
3 changes: 2 additions & 1 deletion packages/date-adapters/src/__tests__/moment.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import moment from "moment";
import { describe, expect, it } from "vitest";
import "moment-timezone";
import { AdapterMoment, DateDetailErrorEnum } from "../index";
import { DateDetailErrorEnum } from "../index";
import { AdapterMoment } from "../moment";

describe("GIVEN a AdapterMoment", () => {
const adapter = new AdapterMoment({ locale: "en" });
Expand Down
5 changes: 0 additions & 5 deletions packages/date-adapters/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,4 @@
// biome-ignore lint/complexity/noBannedTypes: type augmented by configured adapters
export type DateFrameworkTypeMap = {};

export * from "./date-fns";
export * from "./dayjs";
export * from "./luxon";
export * from "./moment";

export * from "./types";
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { AdapterDateFns } from "@salt-ds/date-adapters";
import { AdapterDayjs } from "@salt-ds/date-adapters";
import { AdapterLuxon } from "@salt-ds/date-adapters";
import { AdapterMoment } from "@salt-ds/date-adapters";
import { AdapterDateFns } from "@salt-ds/date-adapters/date-fns";
import { AdapterDayjs } from "@salt-ds/date-adapters/dayjs";
import { AdapterLuxon } from "@salt-ds/date-adapters/luxon";
import { AdapterMoment } from "@salt-ds/date-adapters/moment";

import * as calendarStories from "@stories/calendar/calendar.stories";
import { composeStories } from "@storybook/react";
Expand Down
8 changes: 4 additions & 4 deletions packages/lab/src/__tests__/__e2e__/calendar/Calendar.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import type {
DateFrameworkType,
SaltDateAdapter,
} from "@salt-ds/date-adapters";
import { AdapterDateFns } from "@salt-ds/date-adapters";
import { AdapterDayjs } from "@salt-ds/date-adapters";
import { AdapterLuxon } from "@salt-ds/date-adapters";
import { AdapterMoment } from "@salt-ds/date-adapters";
import { AdapterDateFns } from "@salt-ds/date-adapters/date-fns";
import { AdapterDayjs } from "@salt-ds/date-adapters/dayjs";
import { AdapterLuxon } from "@salt-ds/date-adapters/luxon";
import { AdapterMoment } from "@salt-ds/date-adapters/moment";
import {
Calendar,
CalendarGrid,
Expand Down
Loading
Loading