",
18 | "bugs": {
19 | "url": "https://github.com/NativeScript/NativeScript/issues"
20 | },
21 | "homepage": "https://github.com/NativeScript/nativescript-app-templates",
22 | "dependencies": {
23 | "@nativescript/core": "~8.0.8",
24 | "@nativescript/theme": "~2.3.0",
25 | "nativescript-printer": "file:../src"
26 | },
27 | "devDependencies": {
28 | "@nativescript/ios": "8.0.0",
29 | "@nativescript/types": "~8.0.1",
30 | "@nativescript/webpack": "~3.0.0",
31 | "typescript": "~4.0.8"
32 | },
33 | "readme": "NativeScript Application",
34 | "scripts": {
35 | "build.plugin": "cd ../src && npm run build"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/demo/references.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/demo/src/app-root.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/demo/src/app.css:
--------------------------------------------------------------------------------
1 | /*
2 | In NativeScript, the app.css file is where you place CSS rules that
3 | you would like to apply to your entire application. Check out
4 | http://docs.nativescript.org/ui/styling for a full list of the CSS
5 | selectors and properties you can use to style UI components.
6 |
7 | /*
8 | In many cases you may want to use the NativeScript core theme instead
9 | of writing your own CSS rules. You can learn more about the
10 | NativeScript core theme at https://github.com/nativescript/theme
11 | The imported CSS rules must precede all other types of rules.
12 | */
13 | @import '~@nativescript/theme/css/core.css';
14 | @import '~@nativescript/theme/css/default.css';
15 |
16 | /* Place any CSS rules you want to apply on both iOS and Android here.
17 | This is where the vast majority of your CSS code goes. */
18 |
19 | /*
20 | The following CSS rule changes the font size of all Buttons that have the
21 | '-primary' class modifier.
22 | */
23 | Button.-primary {
24 | font-size: 18;
25 | }
26 |
--------------------------------------------------------------------------------
/demo/src/assets/pdf-test.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EddyVerbruggen/nativescript-printer/87647438396d20ac02346ad810ee42a05f973f75/demo/src/assets/pdf-test.pdf
--------------------------------------------------------------------------------
/demo/src/assets/printer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EddyVerbruggen/nativescript-printer/87647438396d20ac02346ad810ee42a05f973f75/demo/src/assets/printer.png
--------------------------------------------------------------------------------
/demo/src/data.json:
--------------------------------------------------------------------------------
1 | {
2 | "htmlView": "Maids table how learn drift but purse stand yet set \n\nEat imagine you chiefly few end ferrars compass. Be visitor females am ferrars inquiry. Latter law remark two lively thrown. Spot set they know rest its. Raptures law diverted believed jennings consider children the see. Had invited beloved carried the colonel. Occasional principles discretion it as he unpleasing boisterous. She bed sing dear now son half.
\n\nIn by an appetite no humoured returned informed. Possession so comparison inquietude he he conviction no decisively. Marianne jointure attended she hastened surprise but she. Ever lady son yet you very paid form away. He advantage of exquisite resolving if on tolerably. Become sister on in garden it barton waited on.
\n\nAmong going manor who did. Do ye is celebrated it sympathize considered. May ecstatic did surprise elegance the ignorant age. Own her miss cold last. It so numerous if he outlived disposal. How but sons mrs lady when. Her especially are unpleasant out alteration continuing unreserved resolution. Hence hopes noisy may china fully and. Am it regard stairs branch thirty length afford.
\n\nOh to talking improve produce in limited offices fifteen an. Wicket branch to answer do we. Place are decay men hours tiled. If or of ye throwing friendly required. Marianne interest in exertion as. Offering my branched confined oh dashwood.
\n\nNot him old music think his found enjoy merry. Listening acuteness dependent at or an. Apartments thoroughly unsatiable terminated sex how themselves. She are ten hours wrong walls stand early. Domestic perceive on an ladyship extended received do. Why jennings our whatever his learning gay perceive. Is against no he without subject. Bed connection unreserved preference partiality not unaffected. Years merit trees so think in hoped we as.
\n\nIs at purse tried jokes china ready decay an. Small its shy way had woody downs power. To denoting admitted speaking learning my exercise so in. Procured shutters mr it feelings. To or three offer house begin taken am at. As dissuade cheerful overcame so of friendly he indulged unpacked. Alteration connection to so as collecting me. Difficult in delivered extensive at direction allowance. Alteration put use diminution can considered sentiments interested discretion. An seeing feebly stairs am branch income me unable.
\n\nNeat own nor she said see walk. And charm add green you these. Sang busy in this drew ye fine. At greater prepare musical so attacks as on distant. Improving age our her cordially intention. His devonshire sufficient precaution say preference middletons insipidity. Since might water hence the her worse. Concluded it offending dejection do earnestly as me direction. Nature played thirty all him.
\n\nBarton did feebly change man she afford square add. Want eyes by neat so just must. Past draw tall up face show rent oh mr. Required is debating extended wondered as do. New get described applauded incommode shameless out extremity but. Resembled at perpetual no believing is otherwise sportsman. Is do he dispatched cultivated travelling astonished. Melancholy am considered possession on collecting everything.
\n\nNeeded feebly dining oh talked wisdom oppose at. Applauded use attempted strangers now are middleton concluded had. It is tried no added purse shall no on truth. Pleased anxious or as in by viewing forbade minutes prevent. Too leave had those get being led weeks blind. Had men rose from down lady able. Its son him ferrars proceed six parlors. Her say projection age announcing decisively men. Few gay sir those green men timed downs widow chief. Prevailed remainder may propriety can and.
\n",
3 | "textView": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In aliquam ipsum lacus, in viverra nisl maximus eu. Phasellus pulvinar iaculis nulla non suscipit. Suspendisse potenti. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer at fringilla metus, ut placerat ipsum. Nam blandit molestie mauris, at consequat mauris facilisis ac. Proin non quam auctor, tempor risus non, aliquet mi. Donec nec vestibulum sapien. Ut vitae lacus in dolor interdum sagittis a ut enim. Etiam a felis posuere, commodo lorem et, mollis tortor. Praesent sagittis posuere urna et efficitur. Donec mauris elit, volutpat vitae eleifend et, rhoncus vitae sem.\nMaecenas eget mauris dictum, accumsan quam eu, fermentum massa. Curabitur in maximus lectus. Nulla neque ante, rhoncus eu risus ut, aliquet volutpat purus. Phasellus non consectetur massa. Phasellus id dapibus arcu. Nullam eget enim nec purus sagittis faucibus. Etiam fringilla diam at diam malesuada accumsan. Nam rutrum rhoncus tristique. Donec nec ante sit amet elit scelerisque porttitor. Etiam a iaculis metus. Nullam non augue ac orci venenatis hendrerit vitae nec eros.\n\nCras a tempor urna. Nulla vehicula magna quis sem semper euismod. Sed vel molestie erat, lobortis placerat arcu. Nulla sem metus, viverra vitae condimentum ut, luctus vel est. Curabitur iaculis, arcu nec pharetra elementum, tortor nisl varius risus, vel pharetra libero leo ac dolor. Praesent quis sollicitudin tellus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent sagittis convallis est, non tristique turpis tincidunt eget. Morbi iaculis neque quis mi luctus, ac vehicula velit lacinia.\n\nMauris eu sagittis tortor, non aliquam odio. Vestibulum mollis magna at libero fermentum, non maximus nibh congue. Curabitur nec sapien nibh. Fusce felis magna, lobortis et scelerisque ac, sagittis et velit. Vivamus venenatis et ligula at mattis. Nulla tortor est, pellentesque a interdum in, auctor non dui. Nullam in augue in diam mattis volutpat eget eget urna. Morbi non mauris nec mi vestibulum eleifend. Quisque sed eleifend elit. Integer interdum purus quis lectus eleifend fringilla. Phasellus posuere congue mattis. Nulla aliquet sodales tempus. Etiam ornare iaculis nibh quis posuere.\n\nVestibulum lacinia fringilla lectus, sed condimentum lectus rutrum at. Aliquam sollicitudin justo eu efficitur ultrices. Integer accumsan quis massa et pulvinar. Aliquam faucibus risus nec urna volutpat lacinia. Aenean non ultrices ex. Sed volutpat mi tortor, in tempus lacus pharetra ac. Quisque dapibus lacus elit, nec scelerisque velit tempus vitae. In commodo sodales nunc at feugiat. Nam laoreet nunc ex, euismod feugiat eros lobortis ac. Vivamus at interdum justo. Donec a sollicitudin felis. Proin interdum molestie convallis. Aenean tristique ac lacus nec tempor. Maecenas ornare libero in orci ornare, sed accumsan velit accumsan."
4 | }
--------------------------------------------------------------------------------
/demo/src/main-page.ts:
--------------------------------------------------------------------------------
1 | import { EventData, Page } from '@nativescript/core';
2 | import { HelloWorldModel } from './main-view-model';
3 |
4 | export function navigatingTo(args: EventData) {
5 | const page = args.object;
6 | page.bindingContext = new HelloWorldModel();
7 | }
8 |
--------------------------------------------------------------------------------
/demo/src/main-page.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/demo/src/main-view-model.ts:
--------------------------------------------------------------------------------
1 | import { alert, isAndroid, ImageSource, knownFolders, Observable, View } from "@nativescript/core";
2 | import { Printer } from "nativescript-printer";
3 |
4 | let data = require('./data.json');
5 |
6 | export class HelloWorldModel extends Observable {
7 | private printer: Printer;
8 |
9 | htmlView: string = data.htmlView;
10 | textView: string = data.textView;
11 |
12 | constructor() {
13 | super();
14 | this.printer = new Printer();
15 | }
16 |
17 | public printingSupported() {
18 | this.printer.isSupported().then((supported) => {
19 | console.log("supported? " + supported);
20 | alert(supported ? "Yep!" : "Nope :(");
21 | }, (error) => {
22 | alert("Error: " + error);
23 | });
24 | }
25 |
26 | public printImage(args) {
27 | let appPath = knownFolders.currentApp().path;
28 | let imgPath = appPath + "/assets/printer.png";
29 | console.log(imgPath);
30 | let imgSrc = new ImageSource();
31 | imgSrc.loadFromFile(imgPath);
32 |
33 | this.printer.printImage({
34 | imageSrc: imgSrc
35 | }).then((success) => {
36 | HelloWorldModel.feedback(success);
37 | }, (error) => {
38 | alert("Error: " + error);
39 | });
40 | }
41 |
42 | public printScreen(args) {
43 | this.printer.printScreen().then((success) => {
44 | HelloWorldModel.feedback(success);
45 | }, (error) => {
46 | alert("Error: " + error);
47 | });
48 | }
49 |
50 | public printScreenPortion(args) {
51 | let view: View = args.object.page.getViewById("lines");
52 | this.printer.printScreen({
53 | view: view
54 | }).then((success) => {
55 | HelloWorldModel.feedback(success);
56 | }, (error) => {
57 | alert("Error: " + error);
58 | });
59 | }
60 |
61 | public printWebView(args) {
62 | let view: View = args.object.page.getViewById("webView");
63 | this.printer.printScreen({
64 | view: view
65 | }).then((success) => {
66 | HelloWorldModel.feedback(success);
67 | }, (error) => {
68 | alert("Error: " + error);
69 | });
70 | }
71 |
72 | public printPDF(args) {
73 | this.printer.printPDF({
74 | // online files are no currently supported
75 | // pdfPath: "https://www.orimi.com/pdf-test.pdf"
76 | pdfPath: knownFolders.currentApp().path + "/assets/pdf-test.pdf"
77 | }).then((success) => {
78 | HelloWorldModel.feedback(success);
79 | }, (error) => {
80 | alert("Error: " + error);
81 | });
82 | }
83 |
84 | public printHtmlView(args) {
85 | let view: View = args.object.page.getViewById("htmlView");
86 | this.printer.printScreen({
87 | view: view
88 | }).then((success) => {
89 | HelloWorldModel.feedback(success);
90 | }, (error) => {
91 | alert("Error: " + error);
92 | });
93 | }
94 |
95 | public printLabel(args) {
96 | let view: View = args.object.page.getViewById("labelView");
97 | this.printer.printScreen({
98 | view: view
99 | }).then((success) => {
100 | HelloWorldModel.feedback(success);
101 | }, (error) => {
102 | alert("Error: " + error);
103 | });
104 | }
105 |
106 | public printTextView(args) {
107 | let view: View = args.object.page.getViewById("textView");
108 | this.printer.printScreen({
109 | view: view
110 | }).then((success) => {
111 | HelloWorldModel.feedback(success);
112 | }, (error) => {
113 | alert("Error: " + error);
114 | });
115 | }
116 |
117 | private static feedback(success: boolean) {
118 | // on Android there's no way to know whether or not printing succeeded
119 | if (!isAndroid) {
120 | alert(success ? "Printed!" : "Not printed");
121 | }
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/demo/src/main.ts:
--------------------------------------------------------------------------------
1 | /*
2 | In NativeScript, the app.ts file is the entry point to your application.
3 | You can use this file to perform app-level initialization, but the primary
4 | purpose of the file is to pass control to the app’s first module.
5 | */
6 |
7 | import { Application } from '@nativescript/core';
8 |
9 | Application.run({ moduleName: 'app-root' });
10 |
11 | /*
12 | Do not place any code after the application has been started as it will not
13 | be executed on iOS.
14 | */
15 |
--------------------------------------------------------------------------------
/demo/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "esnext",
4 | "target": "es2017",
5 | "moduleResolution": "node",
6 | "experimentalDecorators": true,
7 | "emitDecoratorMetadata": true,
8 | "noEmitHelpers": true,
9 | "noEmitOnError": true,
10 | "skipLibCheck": true,
11 | "lib": [
12 | "es2017",
13 | "dom",
14 | "es6"
15 | ],
16 | "baseUrl": ".",
17 | "paths": {
18 | "~/*": [
19 | "app/*"
20 | ]
21 | }
22 | },
23 | "exclude": [
24 | "node_modules",
25 | "platforms"
26 | ]
27 | }
--------------------------------------------------------------------------------
/demo/webpack.config.js:
--------------------------------------------------------------------------------
1 | const { join, relative, resolve, sep } = require("path");
2 | const fs = require('fs');
3 |
4 | const webpack = require("webpack");
5 | const nsWebpack = require("@nativescript/webpack");
6 | const nativescriptTarget = require("@nativescript/webpack/nativescript-target");
7 | const { getNoEmitOnErrorFromTSConfig } = require("@nativescript/webpack/utils/tsconfig-utils");
8 | const { CleanWebpackPlugin } = require("clean-webpack-plugin");
9 | const CopyWebpackPlugin = require("copy-webpack-plugin");
10 | const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
11 | const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
12 | const { NativeScriptWorkerPlugin } = require("nativescript-worker-loader/NativeScriptWorkerPlugin");
13 | const TerserPlugin = require("terser-webpack-plugin");
14 | const hashSalt = Date.now().toString();
15 |
16 | module.exports = env => {
17 | // Add your custom Activities, Services and other Android app components here.
18 | const appComponents = env.appComponents || [];
19 | appComponents.push(...[
20 | "@nativescript/core/ui/frame",
21 | "@nativescript/core/ui/frame/activity",
22 | ]);
23 |
24 | const platform = env && (env.android && "android" || env.ios && "ios" || env.platform);
25 | if (!platform) {
26 | throw new Error("You need to provide a target platform!");
27 | }
28 |
29 | const platforms = ["ios", "android"];
30 | const projectRoot = __dirname;
31 |
32 | if (env.platform) {
33 | platforms.push(env.platform);
34 | }
35 |
36 | // Default destination inside platforms//...
37 | const dist = resolve(projectRoot, nsWebpack.getAppPath(platform, projectRoot));
38 |
39 | const {
40 | // The 'appPath' and 'appResourcesPath' values are fetched from
41 | // the nsconfig.json configuration file.
42 | appPath = "src",
43 | appResourcesPath = "App_Resources",
44 |
45 | // You can provide the following flags when running 'tns run android|ios'
46 | snapshot, // --env.snapshot
47 | production, // --env.production
48 | uglify, // --env.uglify
49 | report, // --env.report
50 | sourceMap, // --env.sourceMap
51 | hiddenSourceMap, // --env.hiddenSourceMap
52 | hmr, // --env.hmr,
53 | unitTesting, // --env.unitTesting,
54 | testing, // --env.testing
55 | verbose, // --env.verbose
56 | snapshotInDocker, // --env.snapshotInDocker
57 | skipSnapshotTools, // --env.skipSnapshotTools
58 | compileSnapshot // --env.compileSnapshot
59 | } = env;
60 |
61 | const useLibs = compileSnapshot;
62 | const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap;
63 | const externals = nsWebpack.getConvertedExternals(env.externals);
64 |
65 | let appFullPath = resolve(projectRoot, appPath);
66 | if (!fs.existsSync(appFullPath)) {
67 | // some apps use 'app' directory
68 | appFullPath = resolve(projectRoot, 'app');
69 | }
70 | const hasRootLevelScopedModules = nsWebpack.hasRootLevelScopedModules({ projectDir: projectRoot });
71 | let coreModulesPackageName = "tns-core-modules";
72 | const alias = env.alias || {};
73 | alias['~/package.json'] = resolve(projectRoot, 'package.json');
74 | alias['~'] = appFullPath;
75 |
76 | if (hasRootLevelScopedModules) {
77 | coreModulesPackageName = "@nativescript/core";
78 | alias["tns-core-modules"] = coreModulesPackageName;
79 | }
80 | const appResourcesFullPath = resolve(projectRoot, appResourcesPath);
81 |
82 | const copyIgnore = { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] };
83 |
84 | const entryModule = nsWebpack.getEntryModule(appFullPath, platform);
85 | const entryPath = `.${sep}${entryModule}.ts`;
86 | const entries = env.entries || {};
87 | entries.bundle = entryPath;
88 |
89 | const tsConfigPath = resolve(projectRoot, "tsconfig.json");
90 |
91 | const areCoreModulesExternal = Array.isArray(env.externals) && env.externals.some(e => e.indexOf("@nativescript") > -1);
92 | if (platform === "ios" && !areCoreModulesExternal && !testing) {
93 | entries["tns_modules/@nativescript/core/inspector_modules"] = "inspector_modules";
94 | };
95 |
96 | let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist);
97 |
98 | const itemsToClean = [`${dist}/**/*`];
99 | if (platform === "android") {
100 | itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "src", "main", "assets", "snapshots")}`);
101 | itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "build", "configurations", "nativescript-android-snapshot")}`);
102 | }
103 |
104 | const noEmitOnErrorFromTSConfig = getNoEmitOnErrorFromTSConfig(tsConfigPath);
105 |
106 | nsWebpack.processAppComponents(appComponents, platform);
107 | const config = {
108 | mode: production ? "production" : "development",
109 | context: appFullPath,
110 | externals,
111 | watchOptions: {
112 | ignored: [
113 | appResourcesFullPath,
114 | // Don't watch hidden files
115 | "**/.*",
116 | ]
117 | },
118 | target: nativescriptTarget,
119 | entry: entries,
120 | output: {
121 | pathinfo: false,
122 | path: dist,
123 | sourceMapFilename,
124 | libraryTarget: "commonjs2",
125 | filename: "[name].js",
126 | globalObject: "global",
127 | hashSalt
128 | },
129 | resolve: {
130 | extensions: [".ts", ".js", ".scss", ".css"],
131 | // Resolve {N} system modules from @nativescript/core
132 | modules: [
133 | resolve(__dirname, `node_modules/${coreModulesPackageName}`),
134 | resolve(__dirname, "node_modules"),
135 | `node_modules/${coreModulesPackageName}`,
136 | "node_modules",
137 | ],
138 | alias,
139 | // resolve symlinks to symlinked modules
140 | symlinks: true
141 | },
142 | resolveLoader: {
143 | // don't resolve symlinks to symlinked loaders
144 | symlinks: false
145 | },
146 | node: {
147 | // Disable node shims that conflict with NativeScript
148 | "http": false,
149 | "timers": false,
150 | "setImmediate": false,
151 | "fs": "empty",
152 | "__dirname": false,
153 | },
154 | devtool: hiddenSourceMap ? "hidden-source-map" : (sourceMap ? "inline-source-map" : "none"),
155 | optimization: {
156 | runtimeChunk: "single",
157 | noEmitOnErrors: noEmitOnErrorFromTSConfig,
158 | splitChunks: {
159 | cacheGroups: {
160 | vendor: {
161 | name: "vendor",
162 | chunks: "all",
163 | test: (module, chunks) => {
164 | const moduleName = module.nameForCondition ? module.nameForCondition() : '';
165 | return /[\\/]node_modules[\\/]/.test(moduleName) ||
166 | appComponents.some(comp => comp === moduleName);
167 |
168 | },
169 | enforce: true,
170 | },
171 | }
172 | },
173 | minimize: !!uglify,
174 | minimizer: [
175 | new TerserPlugin({
176 | parallel: true,
177 | cache: true,
178 | sourceMap: isAnySourceMapEnabled,
179 | terserOptions: {
180 | output: {
181 | comments: false,
182 | semicolons: !isAnySourceMapEnabled
183 | },
184 | compress: {
185 | // The Android SBG has problems parsing the output
186 | // when these options are enabled
187 | 'collapse_vars': platform !== "android",
188 | sequences: platform !== "android",
189 | }
190 | }
191 | })
192 | ],
193 | },
194 | module: {
195 | rules: [
196 | {
197 | include: join(appFullPath, entryPath),
198 | use: [
199 | // Require all Android app components
200 | platform === "android" && {
201 | loader: "@nativescript/webpack/helpers/android-app-components-loader",
202 | options: { modules: appComponents }
203 | },
204 |
205 | {
206 | loader: "@nativescript/webpack/bundle-config-loader",
207 | options: {
208 | loadCss: !snapshot, // load the application css if in debug mode
209 | unitTesting,
210 | appFullPath,
211 | projectRoot,
212 | ignoredFiles: nsWebpack.getUserDefinedEntries(entries, platform)
213 | }
214 | },
215 | ].filter(loader => !!loader)
216 | },
217 |
218 | {
219 | test: /\.(ts|css|scss|html|xml)$/,
220 | use: "@nativescript/webpack/hmr/hot-loader"
221 | },
222 |
223 | { test: /\.(html|xml)$/, use: "@nativescript/webpack/helpers/xml-namespace-loader" },
224 |
225 | {
226 | test: /\.css$/,
227 | use: "@nativescript/webpack/helpers/css2json-loader"
228 | },
229 |
230 | {
231 | test: /\.scss$/,
232 | use: [
233 | "@nativescript/webpack/helpers/css2json-loader",
234 | "sass-loader"
235 | ]
236 | },
237 |
238 | {
239 | test: /\.ts$/,
240 | use: {
241 | loader: "ts-loader",
242 | options: {
243 | configFile: tsConfigPath,
244 | // https://github.com/TypeStrong/ts-loader/blob/ea2fcf925ec158d0a536d1e766adfec6567f5fb4/README.md#faster-builds
245 | // https://github.com/TypeStrong/ts-loader/blob/ea2fcf925ec158d0a536d1e766adfec6567f5fb4/README.md#hot-module-replacement
246 | transpileOnly: true,
247 | allowTsInNodeModules: true,
248 | compilerOptions: {
249 | sourceMap: isAnySourceMapEnabled,
250 | declaration: false
251 | },
252 | getCustomTransformers: (program) => ({
253 | before: [
254 | require("@nativescript/webpack/transformers/ns-transform-native-classes").default
255 | ]
256 | })
257 | },
258 | }
259 | },
260 | ]
261 | },
262 | plugins: [
263 | // Define useful constants like TNS_WEBPACK
264 | new webpack.DefinePlugin({
265 | "global.TNS_WEBPACK": "true",
266 | "global.isAndroid": platform === 'android',
267 | "global.isIOS": platform === 'ios',
268 | "process": "global.process",
269 | }),
270 | // Remove all files from the out dir.
271 | new CleanWebpackPlugin({
272 | cleanOnceBeforeBuildPatterns: itemsToClean,
273 | verbose: !!verbose
274 | }),
275 | // Copy assets
276 | new CopyWebpackPlugin({
277 | patterns: [
278 | { from: 'assets/**', noErrorOnMissing: true, globOptions: { dot: false, ...copyIgnore } },
279 | { from: 'fonts/**', noErrorOnMissing: true, globOptions: { dot: false, ...copyIgnore } },
280 | { from: '**/*.jpg', noErrorOnMissing: true, globOptions: { dot: false, ...copyIgnore } },
281 | { from: '**/*.png', noErrorOnMissing: true, globOptions: { dot: false, ...copyIgnore } },
282 | { from: '**/*.pdf', noErrorOnMissing: true, globOptions: { dot: false, ...copyIgnore } },
283 | ],
284 | }),
285 | new nsWebpack.GenerateNativeScriptEntryPointsPlugin("bundle"),
286 | // For instructions on how to set up workers with webpack
287 | // check out https://github.com/nativescript/worker-loader
288 | new NativeScriptWorkerPlugin(),
289 | new nsWebpack.PlatformFSPlugin({
290 | platform,
291 | platforms,
292 | }),
293 | // Does IPC communication with the {N} CLI to notify events when running in watch mode.
294 | new nsWebpack.WatchStateLoggerPlugin(),
295 | // https://github.com/TypeStrong/ts-loader/blob/ea2fcf925ec158d0a536d1e766adfec6567f5fb4/README.md#faster-builds
296 | // https://github.com/TypeStrong/ts-loader/blob/ea2fcf925ec158d0a536d1e766adfec6567f5fb4/README.md#hot-module-replacement
297 | new ForkTsCheckerWebpackPlugin({
298 | async: false,
299 | typescript: {
300 | configFile: tsConfigPath,
301 | memoryLimit: 4096,
302 | diagnosticOptions: {
303 | syntactic: true,
304 | semantic: true
305 | }
306 | }
307 | })
308 | ],
309 | };
310 |
311 | if (report) {
312 | // Generate report files for bundles content
313 | config.plugins.push(new BundleAnalyzerPlugin({
314 | analyzerMode: "static",
315 | openAnalyzer: false,
316 | generateStatsFile: true,
317 | reportFilename: resolve(projectRoot, "report", `report.html`),
318 | statsFilename: resolve(projectRoot, "report", `stats.json`),
319 | }));
320 | }
321 |
322 | if (snapshot) {
323 | config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({
324 | chunk: "vendor",
325 | requireModules: [
326 | "@nativescript/core/bundle-entry-points",
327 | ],
328 | projectRoot,
329 | webpackConfig: config,
330 | snapshotInDocker,
331 | skipSnapshotTools,
332 | useLibs
333 | }));
334 | }
335 |
336 | if (hmr) {
337 | config.plugins.push(new webpack.HotModuleReplacementPlugin());
338 | }
339 |
340 | return config;
341 | };
342 |
--------------------------------------------------------------------------------
/publish/pack.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | SOURCE_DIR=../src;
4 | TO_SOURCE_DIR=src;
5 | PACK_DIR=package;
6 | ROOT_DIR=..;
7 | PUBLISH=--publish
8 |
9 | install(){
10 | npm i
11 | }
12 |
13 | pack() {
14 |
15 | echo 'Clearing /src and /package...'
16 | node_modules/.bin/rimraf "$TO_SOURCE_DIR"
17 | node_modules/.bin/rimraf "$PACK_DIR"
18 |
19 | # copy src
20 | echo 'Copying src...'
21 | node_modules/.bin/ncp "$SOURCE_DIR" "$TO_SOURCE_DIR"
22 |
23 | # copy README & LICENSE to src
24 | echo 'Copying README and LICENSE to /src...'
25 | node_modules/.bin/ncp "$ROOT_DIR"/LICENSE "$TO_SOURCE_DIR"/LICENSE
26 | node_modules/.bin/ncp "$ROOT_DIR"/README.md "$TO_SOURCE_DIR"/README.md
27 |
28 | # compile package and copy files required by npm
29 | echo 'Building /src...'
30 | cd "$TO_SOURCE_DIR"
31 | node_modules/.bin/tsc
32 | cd ..
33 |
34 | echo 'Creating package...'
35 | # create package dir
36 | mkdir "$PACK_DIR"
37 |
38 | # create the package
39 | cd "$PACK_DIR"
40 | npm pack ../"$TO_SOURCE_DIR"
41 |
42 | # delete source directory used to create the package
43 | cd ..
44 | node_modules/.bin/rimraf "$TO_SOURCE_DIR"
45 | }
46 |
47 | install && pack
--------------------------------------------------------------------------------
/publish/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nativescript-publish",
3 | "version": "1.0.0",
4 | "description": "Publish helper",
5 | "devDependencies": {
6 | "ncp": "^2.0.0",
7 | "rimraf": "^2.5.0"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/publish/publish.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PACK_DIR=package;
4 |
5 | publish() {
6 | cd $PACK_DIR
7 | echo 'Publishing to npm...'
8 | npm publish *.tgz
9 | }
10 |
11 | ./pack.sh && publish
--------------------------------------------------------------------------------
/screenshots/android/android-printer-options.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EddyVerbruggen/nativescript-printer/87647438396d20ac02346ad810ee42a05f973f75/screenshots/android/android-printer-options.png
--------------------------------------------------------------------------------
/screenshots/android/android-select-printer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EddyVerbruggen/nativescript-printer/87647438396d20ac02346ad810ee42a05f973f75/screenshots/android/android-select-printer.png
--------------------------------------------------------------------------------
/screenshots/ios/ios-printing-in-progress.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EddyVerbruggen/nativescript-printer/87647438396d20ac02346ad810ee42a05f973f75/screenshots/ios/ios-printing-in-progress.png
--------------------------------------------------------------------------------
/screenshots/ios/ios-select-printer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EddyVerbruggen/nativescript-printer/87647438396d20ac02346ad810ee42a05f973f75/screenshots/ios/ios-select-printer.png
--------------------------------------------------------------------------------
/src/.npmignore:
--------------------------------------------------------------------------------
1 | tsconfig.json
2 | *.map
3 | *.ts
4 | !*.d.ts
5 |
--------------------------------------------------------------------------------
/src/index.d.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * iOS and Android apis should match.
3 | * It doesn't matter if you export `.ios` or `.android`, either one but only one.
4 | */
5 | export * from "./printer.ios";
6 |
7 | // Export any shared classes, constants, etc.
8 | export * from "./printer.common";
--------------------------------------------------------------------------------
/src/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nativescript-printer",
3 | "version": "3.0.0",
4 | "description": "Send an image or the screen contents to a physical printer",
5 | "main": "printer",
6 | "typings": "index.d.ts",
7 | "nativescript": {
8 | "platforms": {
9 | "android": "8.0.0",
10 | "ios": "8.0.0"
11 | }
12 | },
13 | "scripts": {
14 | "tsc": "tsc -skipLibCheck",
15 | "build": "npm i && npm run tsc",
16 | "demo.ios": "npm run build && cd ../demo && tns run ios --emulator",
17 | "demo.ios.device": "npm run build && cd ../demo && tns platform remove ios && tns run ios",
18 | "demo.android": "npm run build && cd ../demo && tns platform remove android && tns run android --justlaunch",
19 | "test": "npm run tslint && npm run tslint.demo && cd ../demo && tns build ios && tns build android",
20 | "test.ios": "cd ../demo && tns platform remove ios && tns test ios --emulator",
21 | "test.ios.device": "cd ../demo && tns platform remove ios && tns test ios",
22 | "test.android": "cd ../demo && tns platform remove android && tns test android --justlaunch",
23 | "preparedemo": "npm run build && cd ../demo && tns plugin remove nativescript-printer && tns plugin add ../src && tns install",
24 | "setup": "npm i && cd ../demo && npm i && cd ../src && npm run build",
25 | "setupandinstall": "npm i && cd ../demo && npm i && cd ../src && npm run build && cd ../demo && tns plugin add ../src && cd ../src",
26 | "tslint": "tslint *.ts",
27 | "tslint.demo": "tslint --config '../tslint.json' '../demo/app/*.ts' --exclude '**/node_modules/**'",
28 | "ci.tslint": "npm run tslint && npm run tslint.demo",
29 | "development.setup": "npm run setup && cd ../demo && npm link ../src && cd ../src"
30 | },
31 | "repository": {
32 | "type": "git",
33 | "url": "https://github.com/EddyVerbruggen/nativescript-printer.git"
34 | },
35 | "keywords": [
36 | "ecosystem:nativescript",
37 | "NativeScript",
38 | "JavaScript",
39 | "Android",
40 | "iOS",
41 | "Printer",
42 | "Print",
43 | "AirPrint",
44 | "Printscreen"
45 | ],
46 | "author": {
47 | "name": "Eddy Verbruggen",
48 | "email": "eddyverbruggen@gmail.com",
49 | "url": "https://github.com/EddyVerbruggen"
50 | },
51 | "contributors": [
52 | {
53 | "name": "Osei Fortune",
54 | "url": "https://github.com/triniwiz"
55 | }
56 | ],
57 | "bugs": {
58 | "url": "https://github.com/EddyVerbruggen/nativescript-printer/issues"
59 | },
60 | "license": "MIT",
61 | "homepage": "https://github.com/EddyVerbruggen/nativescript-printer",
62 | "readmeFilename": "README.md",
63 | "devDependencies": {
64 | "@nativescript/core": "~8.0.8",
65 | "@nativescript/types": "~8.0.1",
66 | "@nativescript/webpack": "~3.0.9",
67 | "typescript": "~4.0.8",
68 | "prompt": "^1.0.0",
69 | "rimraf": "^2.5.0",
70 | "tslint": "~6.1.3"
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/printer.android.ts:
--------------------------------------------------------------------------------
1 | import { Application, Frame, View } from "@nativescript/core";
2 | import * as utils from "@nativescript/core/utils/utils";
3 | import { PrinterApi, PrintImageOptions, PrintOptions, PrintPDFOptions, PrintScreenOptions } from "./printer.common";
4 |
5 | declare let android, global: any;
6 |
7 | const PrintPackageName = useAndroidX() ? global.androidx.print : android.support.v4.print;
8 |
9 | function useAndroidX() {
10 | return global.androidx && global.androidx.appcompat;
11 | }
12 |
13 | export class Printer implements PrinterApi {
14 |
15 | private printManager: any; // android.print.PrintManager;
16 |
17 | constructor() {
18 | this.printManager = utils.ad.getApplicationContext().getSystemService(android.content.Context.PRINT_SERVICE);
19 | }
20 |
21 | private static isPrintingSupported(): boolean {
22 | return PrintPackageName.PrintHelper.systemSupportsPrint();
23 | }
24 |
25 | public isSupported(): Promise {
26 | return new Promise((resolve, reject) => {
27 | try {
28 | resolve(Printer.isPrintingSupported());
29 | } catch (e) {
30 | reject(e);
31 | }
32 | });
33 | }
34 |
35 | private _printImage(image: any /* Image */, options?: PrintOptions): Promise {
36 | return new Promise((resolve, reject) => {
37 |
38 | if (!Printer.isPrintingSupported()) {
39 | reject("Printing is not supported on this device - better check isSupported() beforehand");
40 | return;
41 | }
42 |
43 | try {
44 | let callback = success => {
45 | resolve(success);
46 | };
47 |
48 | // see https://developer.android.com/training/printing/photos.html
49 | let printHelper = new PrintPackageName.PrintHelper(Application.android.foregroundActivity);
50 | printHelper.setScaleMode(PrintPackageName.PrintHelper.SCALE_MODE_FIT);
51 | let jobName = "MyPrintJob";
52 | printHelper.printBitmap(jobName, image);
53 |
54 | // there's no way to know whether the user printed or canceled, so returning true
55 | callback(true);
56 | } catch (e) {
57 | reject(e);
58 | }
59 | });
60 | }
61 |
62 | public printImage(arg: PrintImageOptions): Promise {
63 | return new Promise((resolve, reject) => {
64 | try {
65 | this._printImage(arg.imageSrc.android, arg).then(resolve, reject);
66 | } catch (e) {
67 | reject(e);
68 | }
69 | });
70 | }
71 |
72 | public printScreen(arg?: PrintScreenOptions): Promise {
73 | return new Promise((resolve, reject) => {
74 | try {
75 | let bmp: any;
76 |
77 | if (arg && arg.view) {
78 | let view: View = arg.view;
79 | bmp = android.graphics.Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), android.graphics.Bitmap.Config.ARGB_8888);
80 | view.android.draw(new android.graphics.Canvas(bmp));
81 | } else {
82 | let view: View = Frame.topmost().currentPage.content;
83 | view.android.setDrawingCacheEnabled(true);
84 | bmp = android.graphics.Bitmap.createBitmap(view.android.getDrawingCache());
85 | view.android.setDrawingCacheEnabled(false);
86 | }
87 |
88 | this._printImage(bmp, arg).then(resolve, reject);
89 | } catch (e) {
90 | reject(e);
91 | }
92 | });
93 | }
94 |
95 | public printPDF(arg: PrintPDFOptions): Promise {
96 | return new Promise((resolve, reject) => {
97 | try {
98 | let file = new java.io.File(arg.pdfPath);
99 |
100 | if (!file.exists()) {
101 | reject('File does not exist');
102 | return;
103 | }
104 |
105 | let fileDescriptor = android.os.ParcelFileDescriptor.open(file, android.os.ParcelFileDescriptor.MODE_READ_ONLY);
106 | let pdfRenderer = new android.graphics.pdf.PdfRenderer(fileDescriptor);
107 | let page = pdfRenderer.openPage(0);
108 |
109 | let bmp = android.graphics.Bitmap.createBitmap(page.getWidth(), page.getHeight(), android.graphics.Bitmap.Config.ARGB_8888);
110 | page.render(bmp, null, null, android.graphics.pdf.PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
111 |
112 | page.close();
113 | pdfRenderer.close();
114 |
115 | this._printImage(bmp, {}).then(resolve, reject);
116 | } catch (e) {
117 | reject(e);
118 | }
119 | });
120 | }
121 |
122 | }
123 |
--------------------------------------------------------------------------------
/src/printer.common.ts:
--------------------------------------------------------------------------------
1 | import { ImageSource, View } from "@nativescript/core";
2 |
3 | export interface PrintOptions {
4 | /**
5 | * Default false
6 | * iOS only
7 | */
8 | showsNumberOfCopies?: boolean;
9 |
10 | /**
11 | * Default false
12 | * iOS only
13 | */
14 | showsPageRange?: boolean;
15 | }
16 |
17 | export interface PrintScreenOptions extends PrintOptions {
18 | /**
19 | * By default the entire screen is printed, but may be limited to a specific view.
20 | */
21 | view?: View;
22 | }
23 |
24 | export interface PrintImageOptions extends PrintOptions {
25 | imageSrc: ImageSource;
26 | }
27 |
28 | export interface PrintPDFOptions extends PrintOptions {
29 | pdfPath: string;
30 | }
31 |
32 | export interface PrinterApi {
33 | isSupported(): Promise;
34 |
35 | printScreen(arg?: PrintScreenOptions): Promise;
36 |
37 | printImage(arg: PrintImageOptions): Promise;
38 |
39 | printPDF(arg: PrintPDFOptions): Promise;
40 | }
41 |
--------------------------------------------------------------------------------
/src/printer.ios.ts:
--------------------------------------------------------------------------------
1 | import { CoreTypes, Device, View, Frame } from "@nativescript/core";
2 | import { PrinterApi, PrintOptions, PrintImageOptions, PrintScreenOptions, PrintPDFOptions } from "./printer.common";
3 |
4 | export class Printer implements PrinterApi {
5 |
6 | private static isPrintingSupported(): boolean {
7 | let controller = NSClassFromString("UIPrintInteractionController");
8 | if (!controller) {
9 | return false;
10 | }
11 | return UIPrintInteractionController.sharedPrintController &&
12 | UIPrintInteractionController.printingAvailable;
13 | }
14 |
15 | public isSupported(): Promise {
16 | return new Promise((resolve, reject) => {
17 | try {
18 | resolve(Printer.isPrintingSupported());
19 | } catch (e) {
20 | reject(e);
21 | }
22 | });
23 | }
24 |
25 | private _printImage(image: any /* UIImage | NSData | NSURL */, options?: PrintOptions): Promise {
26 | return new Promise((resolve, reject) => {
27 |
28 | if (!Printer.isPrintingSupported()) {
29 | reject("Printing is not supported on this device - better check isSupported() beforehand");
30 | return;
31 | }
32 |
33 | try {
34 | const controller = UIPrintInteractionController.sharedPrintController;
35 | controller.showsNumberOfCopies = options && options.showsNumberOfCopies;
36 | controller.showsPageRange = options && options.showsPageRange;
37 |
38 | let printInfo = UIPrintInfo.printInfo();
39 | printInfo.outputType = UIPrintInfoOutputType.General;
40 | printInfo.jobName = "MyPrintJob";
41 | controller.printInfo = printInfo;
42 | controller.printingItem = image;
43 |
44 | let callback = (controller, success, error) => {
45 | resolve(success);
46 | };
47 |
48 | if (Device.deviceType === CoreTypes.DeviceType.Tablet) {
49 | let view = UIApplication.sharedApplication.keyWindow.rootViewController.view;
50 | let theFrame: any = Frame.topmost().currentPage.frame;
51 | controller.presentFromRectInViewAnimatedCompletionHandler(theFrame, view, true, callback);
52 | } else {
53 | controller.presentAnimatedCompletionHandler(true, callback);
54 | }
55 | } catch (e) {
56 | reject(e);
57 | }
58 | });
59 | }
60 |
61 | private _printView(nativeView: any /* UITextView | WKWebView | MKMapView */, options?: PrintOptions): Promise {
62 | return new Promise((resolve, reject) => {
63 |
64 | if (!Printer.isPrintingSupported()) {
65 | reject("Printing is not supported on this device - better check isSupported() beforehand");
66 | return;
67 | }
68 |
69 | try {
70 | const controller = UIPrintInteractionController.sharedPrintController;
71 | controller.showsNumberOfCopies = options && options.showsNumberOfCopies;
72 | controller.showsPageRange = options && options.showsPageRange;
73 |
74 | let printInfo = UIPrintInfo.printInfo();
75 | printInfo.outputType = UIPrintInfoOutputType.General;
76 | printInfo.jobName = "MyPrintJob";
77 | controller.printInfo = printInfo;
78 | controller.printFormatter = nativeView.viewPrintFormatter();
79 |
80 | let callback = (controller, success, error) => {
81 | resolve(success);
82 | };
83 |
84 | if (Device.deviceType === CoreTypes.DeviceType.Tablet) {
85 | let view = UIApplication.sharedApplication.keyWindow.rootViewController.view;
86 | let theFrame: any = Frame.topmost().currentPage.frame;
87 | controller.presentFromRectInViewAnimatedCompletionHandler(theFrame, view, true, callback);
88 | } else {
89 | controller.presentAnimatedCompletionHandler(true, callback);
90 | }
91 | } catch (e) {
92 | reject(e);
93 | }
94 | });
95 | }
96 |
97 | public printImage(arg: PrintImageOptions): Promise {
98 | return new Promise((resolve, reject) => {
99 | try {
100 | this._printImage(arg.imageSrc.ios, arg).then(resolve, reject);
101 | } catch (e) {
102 | reject(e);
103 | }
104 | });
105 | }
106 |
107 | public printScreen(arg?: PrintScreenOptions): Promise {
108 | return new Promise((resolve, reject) => {
109 | try {
110 | let view: View;
111 | let h: number;
112 | let w: number;
113 |
114 | if (arg && arg.view) {
115 | view = arg.view;
116 | h = view.getMeasuredHeight();
117 | w = view.getMeasuredWidth();
118 | } else {
119 | view = Frame.topmost().currentPage.content;
120 | h = view.ios.frame.size.height;
121 | w = view.ios.frame.size.width;
122 | }
123 |
124 |
125 | if (view.ios instanceof UITextView || view.ios instanceof WKWebView || view.ios instanceof MKMapView) {
126 | this._printView(view.ios, arg).then(resolve, reject);
127 | } else {
128 | UIGraphicsBeginImageContextWithOptions(view.ios.frame.size, false, 0);
129 | view.ios.drawViewHierarchyInRectAfterScreenUpdates(CGRectMake(0, 0, w, h), true);
130 | let imageFromCurrentImageContext = UIGraphicsGetImageFromCurrentImageContext();
131 | UIGraphicsEndImageContext();
132 | let img = UIImagePNGRepresentation(imageFromCurrentImageContext);
133 |
134 | this._printImage(img, arg).then(resolve, reject);
135 | }
136 | } catch (e) {
137 | reject(e);
138 | }
139 | });
140 | }
141 |
142 | public printPDF(arg: PrintPDFOptions): Promise {
143 | return new Promise((resolve, reject) => {
144 | try {
145 | // note that if we want to also support online files, we could use:
146 | // let url = NSURL.URLWithString(arg.pdfPath);
147 | let url = NSURL.fileURLWithPath(arg.pdfPath);
148 | this._printImage(url, arg).then(resolve, reject);
149 | } catch (e) {
150 | reject(e);
151 | }
152 | });
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/src/references.d.ts:
--------------------------------------------------------------------------------
1 | ///
--------------------------------------------------------------------------------
/src/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2017",
4 | "module": "esnext",
5 | "moduleResolution": "node",
6 | "declaration": true,
7 | "removeComments": true,
8 | "noLib": false,
9 | "emitDecoratorMetadata": true,
10 | "experimentalDecorators": true,
11 | "skipLibCheck": true,
12 | "lib": ["es2017", "dom"],
13 | "sourceMap": true,
14 | "pretty": true,
15 | "allowUnreachableCode": false,
16 | "allowUnusedLabels": false,
17 | "noEmitHelpers": true,
18 | "noEmitOnError": false,
19 | "noImplicitAny": false,
20 | "noImplicitReturns": true,
21 | "noImplicitUseStrict": false,
22 | "noFallthroughCasesInSwitch": true,
23 | "baseUrl": "."
24 | },
25 | "exclude": [
26 | "node_modules"
27 | ],
28 | "compileOnSave": false
29 | }
30 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "class-name": true,
4 | "comment-format": [
5 | true,
6 | "check-space"
7 | ],
8 | "indent": [
9 | true,
10 | "spaces"
11 | ],
12 | "no-duplicate-variable": true,
13 | "no-eval": true,
14 | "no-internal-module": true,
15 | "no-trailing-whitespace": true,
16 | "no-var-keyword": true,
17 | "one-line": [
18 | true,
19 | "check-open-brace",
20 | "check-whitespace"
21 | ],
22 | "quotemark": [
23 | false,
24 | "double"
25 | ],
26 | "semicolon": [
27 | true,
28 | "always"
29 | ],
30 | "triple-equals": [
31 | true,
32 | "allow-null-check"
33 | ],
34 | "typedef-whitespace": [
35 | true,
36 | {
37 | "call-signature": "nospace",
38 | "index-signature": "nospace",
39 | "parameter": "nospace",
40 | "property-declaration": "nospace",
41 | "variable-declaration": "nospace"
42 | }
43 | ],
44 | "variable-name": [
45 | true,
46 | "ban-keywords"
47 | ],
48 | "whitespace": [
49 | true,
50 | "check-branch",
51 | "check-decl",
52 | "check-operator",
53 | "check-separator",
54 | "check-type"
55 | ]
56 | }
57 | }
--------------------------------------------------------------------------------